Compare commits
6 Commits
4aa7ed1be8
...
english_ve
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c81315fd5 | ||
|
|
6e80a6cb70 | ||
|
|
0bf9501c3f | ||
|
|
97fca9c81a | ||
|
|
a5397a4495 | ||
|
|
f3fcd27387 |
178
.github/Intro.md
vendored
@@ -1,116 +1,116 @@
|
|||||||
# Предисловие
|
# Preface
|
||||||
|
|
||||||
Данная книга проведёт вас от азов разработки цифровых схем до проектирования однотактного микроконтроллера с архитектурой RISC-V, а также написания и компиляции программного обеспечения для него. Освоив материал, вы приобретёте практические навыки разработки на языке SystemVerilog, познакомитесь с основами работы с ПЛИС и инструментами проектирования, такими как Vivado, а также получите опыт программирования на языке ассемблера, что откроет для вас двери в мир низкоуровневого программирования.
|
This book will guide you from the fundamentals of digital circuit design all the way to designing a single-cycle RISC-V microcontroller and writing and compiling software for it. By working through the material, you will gain practical skills in SystemVerilog, learn the basics of working with FPGAs and design tools such as Vivado, and gain hands-on experience programming in assembly language — opening the door to the world of low-level programming.
|
||||||
|
|
||||||
Таким образом, книга предоставляет уникальную возможность начать с нуля и шаг за шагом освоить основы проектирования процессоров и работы с ПЛИС, что может стать первым шагом к вашей карьере в области цифровой электроники.
|
The book thus provides a unique opportunity to start from scratch and step by step master the fundamentals of processor design and FPGA development, which can serve as a first step toward a career in digital electronics.
|
||||||
|
|
||||||
Несмотря на то, что создаваемый процессор имеет чисто академическое назначение, на нём можно запускать простые игры, например "змейку". Представленный здесь материал является сборником лабораторных работ, выполняемых студентами в НИУ МИЭТ в рамках дисциплины "Архитектуры процессорных систем" (АПС) и, в первую очередь, рассчитан именно на них, поэтому в тексте будут встречаться фразы вроде: "Допуск к лабораторной работе", "Проконсультироваться с преподавателем", которые имеют смысл, только для обучающихся в ВУЗе. Если вы читаете эту книгу для самостоятельного обучения, большую часть подобных фраз можно игнорировать.
|
Although the processor being built is purely academic in nature, it is perfectly capable of running simple games such as Snake. The material presented here is a collection of lab assignments completed by students at MIET as part of the "Architectures of Processor Systems" (APS) course, and is primarily aimed at those students. As a result, the text occasionally contains phrases such as "Pre-lab admission" or "Consult your instructor," which are meaningful only in a university context. If you are reading this book for self-study, most such phrases can be safely ignored.
|
||||||
|
|
||||||
|
|
||||||
## Мотивация
|
## Motivation
|
||||||
|
|
||||||
Целью курса "Архитектуры процессорных систем" является изучение устройства и способов организации процессоров, а также систем под их управлением. Практическая часть курса ориентирована на разработку процессора с архитектурой RISC-V.
|
The goal of the "Architectures of Processor Systems" course is to study the design and organization of processors and the systems they control. The practical component of the course focuses on developing a processor with the RISC-V architecture.
|
||||||
|
|
||||||
Под словом Архитектура понимается некоторый способ организации. Процессор – это программно-управляемое устройство для обработки информации. Проще говоря, это устройство, управлять поведением которого можно с помощью программ (последовательности команд/действий). Система – это комбинация взаимодействующих элементов, организованных для достижения поставленных целей. Таким образом, дисциплина "Архитектуры процессорных систем" посвящена способам организации и построения систем под управлением устройств, управляемых программами.
|
The word *Architecture* refers to a particular way of organizing something. A *processor* is a programmable device for information processing — in other words, a device whose behavior can be controlled through programs (sequences of instructions/actions). A *system* is a combination of interacting elements organized to achieve defined goals. Thus, the "Architectures of Processor Systems" discipline is concerned with the ways of organizing and building systems controlled by programmable devices.
|
||||||
|
|
||||||
Дисциплина реализуется Институтом МПСУ на базе НИУ МИЭТ сразу для 7 различных направлений подготовки, которые имеют разные названия и количество теоретического и практического материалов. Несмотря на это масштаб покрытия у них одинаковый, а суть предмета изучения общая - организация компьютеров. Отличаются лишь глубина погружения и акценты.
|
The course is delivered by the MPSU Institute at MIET across 7 different degree programs, which vary in name and in the balance of theoretical and practical material. Despite these differences, the scope of coverage is the same across all programs, and the core subject is the same — computer organization. The programs differ only in depth and emphasis.
|
||||||
|
|
||||||
Для успешного погружения в дисциплину важно понимать зачем эта дисциплина нужна именно тебе, будучи студентом:
|
To engage successfully with this discipline, it is important to understand why it is relevant to you as a student in your particular field:
|
||||||
|
|
||||||
### Информационной безопасности
|
### Information Security
|
||||||
|
|
||||||
Нет никаких сомнений в том, что люди, разрабатывающие системы безопасностей для автомобилей, хорошо знают, как эти автомобили устроены и работают. Очевидно, что пожарную безопасность невозможно организовать не понимая, как горят материалы или, к примеру, в чем особенность помещений, которые будут защищаться. Также невозможно организовать стойкую информационную безопасность без понимания принципов работы устройств, которые эту информацию получают, обрабатывают и передают. Чтобы специалисту по информационной безопасности обеспечивать соблюдение правил обмена и обработки информации в информационных системах, очевидно, что нужно понимать как эти системы работают.
|
There is no doubt that people who design automotive safety systems have a thorough understanding of how those automobiles work. It is obvious that fire safety cannot be organized without understanding how materials burn or, for example, the specific characteristics of the spaces being protected. In the same way, robust information security cannot be achieved without understanding the principles of operation of the devices that receive, process, and transmit that information. For an information security specialist to enforce the rules governing the exchange and processing of information in information systems, it is clearly necessary to understand how those systems work.
|
||||||
|
|
||||||
Преступники в сфере информационных технологий знают как они устроены и работают, потому что в результате своих действий они их не "ломают" (как принято говорить), а заставляют работать так, как нужно им, а не владельцам этих систем. Ну, а если чтобы найти преступника нужно думать, как преступник, то хорошему безопаснику остается только одно – разобраться как компьютеры работают, изучив курс АПС.
|
Criminals in the field of information technology know how these systems are built and how they work — because the result of their actions is not "breaking" the systems (as is commonly said), but rather making them work the way the attacker wants, rather than the way the owner intends. And if catching a criminal requires thinking like a criminal, a good security professional has only one option: learn how computers work by studying the APS course.
|
||||||
|
|
||||||
### Информатики и вычислительной техники
|
### Computer Science and Engineering
|
||||||
|
|
||||||
30–40 лет назад, когда персональные компьютеры были ещё в новинку, а интернета как такового не было, пионеры вычислительной техники предсказывали, что в будущем электронные чипы станут настолько дешёвыми, что они будут повсюду — в домах, в транспорте, даже в человеческом теле. Для того времени эта идея казалась фантастической, даже абсурдной. Персональные компьютеры тогда были очень дороги и в большинстве своём даже не подключались к интернету. Мысль о том, что миллиарды крохотных чипов когда-нибудь будут во всем и станут дешевле семечек, казалась нелепой. Сегодня эти мысли уже не кажутся фантастическими. В последнее десятилетие почти всегда, какой-нибудь компьютер или компьютеры находятся на расстоянии вытянутой руки от человека. Билетик в метро – тоже компьютер, который спроектировал, возможно, выпускник ИВТ.
|
30–40 years ago, when personal computers were still a novelty and the internet as we know it did not yet exist, the pioneers of computing predicted that in the future, electronic chips would become so cheap that they would be everywhere — in our homes, in transportation, even in the human body. At the time, this idea seemed fantastical, even absurd. Personal computers were very expensive and mostly not connected to any network. The notion that billions of tiny chips would one day be embedded in everything and cost less than a handful of seeds seemed ridiculous. Today, these ideas no longer seem far-fetched. Over the past decade, some computer or another has almost always been within arm's reach of a person. Even a metro ticket is a computer — one that was perhaps designed by a graduate of a Computer Science and Engineering program.
|
||||||
|
|
||||||
Если ты выпускник направления Информатика и Вычислительная Техника, то скорее всего, в будущем, ты будешь разрабатывать электронику, компьютеры – цифровые автоматические устройства, которые, как правило, управляются процессорами и ПЛИС. Типичное современное электронное устройство – это набор датчиков физических величин, которые посылают свои измерения в процессор, который обрабатывает полученную информацию согласно заданной программе. Понимать, как это работает также разумно, как и терапевту знать из каких органов состоит человек, несмотря на то что он не хирург и внутрь не полезет. Выпускник ИВТ, понимающий устройство компьютера будет способен разрабатывать более эффективные решения: более быстрые, точные, энергоэффективные.
|
If you are a graduate of Computer Science and Engineering, you will most likely be developing electronics and computers in the future — digital automated devices that are typically controlled by processors and FPGAs. A typical modern electronic device consists of a set of physical sensors that send their measurements to a processor, which processes the received information according to a given program. Understanding how this works is just as reasonable as a physician knowing what organs the human body contains, even if they are not a surgeon and will not be operating. A Computer Science and Engineering graduate who understands how a computer is built will be able to develop more effective solutions: faster, more accurate, and more energy-efficient.
|
||||||
|
|
||||||
Логика такая: "Чтобы разрабатывать электронику, я должен понимать из чего она делается", "Современными электронными устройствами управляют процессоры" ⟹ "Чтобы разрабатывать электронику, я должен разбираться в процессорах".
|
The logic goes: "To develop electronics, I need to understand what it is made of," "Modern electronic devices are controlled by processors" ⟹ "To develop electronics, I need to understand processors."
|
||||||
|
|
||||||
### Инфокоммуникационных технологий и систем связи
|
### Infocommunication Technologies and Communication Systems
|
||||||
|
|
||||||
Помимо своей очевидности существует множество подтверждений того, что уровень развития цивилизации связан с развитием связи. Разработка новейших систем связи и их внедрение еще очень долго будет одной из самых актуальных задач развития человечества. Мы сталкиваемся с постоянной потребностью обеспечивать связь нужных адресатов и делать это быстро и безопасно. Достигается это благодаря современным программно-аппаратным решениям, которые постоянно развиваются и совершенствуются. По сути, сетевые инженеры разрабатывают специализированные компьютеры, задачей которых является обмен информацией между некоторыми входными и выходными узлами по заданным правилам. Все это требует понимания работы программируемых устройств, которые и лежат в основе сетевых узлов.
|
In addition to being self-evident, there is abundant evidence that the level of civilizational development is linked to the development of communications. The design of cutting-edge communication systems and their deployment will remain one of the most pressing challenges for humanity for a long time to come. We are constantly faced with the need to connect the right parties quickly and securely. This is achieved through modern hardware-software solutions that are continuously evolving and improving. In essence, network engineers design specialized computers whose purpose is to exchange information between certain input and output nodes according to defined rules. All of this requires an understanding of the operation of programmable devices, which form the foundation of network nodes.
|
||||||
|
|
||||||
Существует множество разнообразных сетевых процессоров и решений, реализуемых в программируемых логических интегральных схемах (ПЛИС). Для успешного участия в разработке современных сетевых решений необходимо не только знание методов передачи данных, алгоритмов кодирования и тому подобного, но и понимание принципов функционирования строительных блоков, из которых создаются сетевые системы. Глубина таких знаний позволяют увеличивать скорость передачи данных и улучшать безопасность.
|
There are numerous diverse network processors and solutions implemented in FPGAs. Successfully participating in the development of modern networking solutions requires not only knowledge of data transmission methods, coding algorithms, and the like, but also an understanding of the operating principles of the building blocks from which network systems are constructed. The depth of such knowledge makes it possible to increase data transfer speeds and improve security.
|
||||||
|
|
||||||
Знания в области разработки компьютеров являются важным инструментом в создании информационно-коммуникационных систем связи.
|
Knowledge in the area of computer design is an essential tool in the creation of information and communication systems.
|
||||||
|
|
||||||
### Конструирования и технологии электронных средств
|
### Electronic Device Design and Technology
|
||||||
|
|
||||||
Не так давно, когда персональные компьютеры только начали завоевывать мир, и интернет еще не был доступен для всех, многие представители конструкторской и технологической индустрии предсказывали будущее, в котором электроника будет всюду: в наших домах, транспорте и даже в наших собственных телах. Это казалось невероятным и даже фантастическим сценарием для тех времен, когда персональные компьютеры были дорогими и не имели доступа к сети Интернет.
|
Not so long ago, when personal computers were just beginning to conquer the world and the internet was not yet available to everyone, many in the design and technology industry predicted a future in which electronics would be everywhere: in our homes, our transportation, and even in our own bodies. This seemed incredible and even fantastical at a time when personal computers were expensive and had no internet access.
|
||||||
|
|
||||||
Сегодня эти идеи уже не кажутся фантастическими. В последние десятилетия мы постоянно окружены электроникой и множеством вычислительных систем, часть из которых появляется благодаря выпускникам Конструирования и технологии электронных средств. Возьмем, к примеру, роботов. Современные роботы – это высокотехнологичные электронные системы, спроектированные для выполнения различных задач. Они оснащены датчиками и процессорами, которые позволяют им воспринимать окружающую среду и принимать решения в реальном времени. Выпускник направления "Конструирование и Технология электронных средств" будет иметь уникальную возможность создавать и улучшать такие устройства, делая их более эффективными и функциональными.
|
Today, these ideas no longer seem far-fetched. In recent decades we have been constantly surrounded by electronics and numerous computing systems, some of which are brought into existence by graduates of Electronic Device Design and Technology programs. Take robots, for example. Modern robots are high-technology electronic systems designed to perform a wide range of tasks. They are equipped with sensors and processors that allow them to perceive their environment and make decisions in real time. A graduate of "Electronic Device Design and Technology" will have a unique opportunity to create and improve such devices, making them more efficient and functional.
|
||||||
|
|
||||||
Суть заключается в том, что для успешной карьеры в области конструирования и технологии электронных средств, необходимо обладать глубоким пониманием электронных систем. Это включает в себя знание принципов работы процессоров, сенсоров и других ключевых компонентов. Выпускники этой специальности будут способны создавать современные электронные устройства и внедрять их в самые разные области. Знание основ организации процессорных систем является мощным и необходимым инструментом в достижении цели создания передовых электронных систем.
|
The key point is that to succeed in a career in electronic device design and technology, one must have a deep understanding of electronic systems. This includes knowledge of how processors, sensors, and other key components work. Graduates of this program will be able to create modern electronic devices and deploy them across the most diverse application areas. Knowledge of the fundamentals of processor system organization is a powerful and essential tool in achieving the goal of creating advanced electronic systems.
|
||||||
|
|
||||||
### Программной инженерии
|
### Software Engineering
|
||||||
|
|
||||||
Не понимать как устроен и работает компьютер современному программисту, все равно что гонщику Формулы-1 не знать, как работает и устроена его машина. Это просто немыслимо! Такое возможно, но скорее исключение из правил. Конечно же кузнец знает, как устроен его инструмент, ведь тогда он может его более эффективно использовать. Понимает его слабые стороны и знает как хитро применить его на практике. Только в этом случае кузнец ценен.
|
For a modern software developer not to understand how a computer is structured and how it works is like a Formula 1 driver not knowing how his car works. It is simply unthinkable! It is possible, but very much the exception. Of course, a blacksmith knows how his tools work — because that knowledge allows him to use them more effectively. He understands their weaknesses and knows how to apply them cleverly in practice. Only then is the blacksmith truly valuable.
|
||||||
|
|
||||||
Современные языки программирования дают возможность значительно оторваться от реального железа. Не редко в этом есть практический смысл, но далеко не всегда. Большинство современных компьютеров автономны (на батарейном питании), а значит, что эффективность их работы есть продолжительность их работы. Понимание нюансов может значительно сэкономить энергию. А порой надо выбрать железо для сервера, а порой понять почему очевидно быстрый код работает медленно. Часто приходится разбираться в новых технологиях, фреймворках, языках, сервисах, библиотеках, но все это дается легко только в том случае, если есть устойчивая база, отвечающая на вопрос - "как это работает и почему именно так?". Во всем перечисленном поможет знание АПС.
|
Modern programming languages make it possible to operate at a great distance from the actual hardware. Often there is practical value in this abstraction, but not always. Most modern computers are autonomous (battery-powered), which means that efficiency directly translates to battery life. Understanding the nuances can lead to significant energy savings. Sometimes you need to choose hardware for a server, or figure out why obviously fast code is running slowly. You frequently have to get up to speed with new technologies, frameworks, languages, services, and libraries — but all of this comes easily only when there is a solid foundation that answers the question: "How does this work, and why does it work this way?" Knowledge of APS helps with all of the above.
|
||||||
|
|
||||||
"Разобраться в работе компьютера" не значит "делать(разрабатывать) компьютер". Врачи знают как устроен человек, чтобы лечить его, а не разрабатывать его. Гонщики знают свой автомобиль, чтобы совершенствовать его и использовать по-полной. Также и программисту необходимо понимание работы компьютера не для того, чтобы разрабатывать процессоры, а для более эффективного и разумного его использования.
|
"Understanding how a computer works" does not mean "building (designing) a computer." Doctors know how the human body is structured in order to treat it, not to design it. Racing drivers know their cars in order to optimize and fully exploit them. Likewise, a software developer needs to understand how a computer works not in order to design processors, but to use the computer more effectively and intelligently.
|
||||||
|
|
||||||
### Прикладной математики
|
### Applied Mathematics
|
||||||
|
|
||||||
Практически все современные приложения математики так или иначе связаны с компьютерами: большие данные, искусственный интеллект, робототехника, финансы и так далее. Математика давно вышла за рамки тетрадных листов, сегодня алгоритмы – это мысли процессоров.
|
Virtually all modern applications of mathematics are connected in one way or another with computers: big data, artificial intelligence, robotics, finance, and so on. Mathematics has long since outgrown the pages of a notebook — today, algorithms are the thoughts of processors.
|
||||||
|
|
||||||
Математические приложения, какими бы они ни были (моделирование, автоматизация, расчеты или что-то другое), требуют инструмента их решения – компьютера. Понимание устройства и работы основного инструмента дает явные преимущества перед тем, у кого этого понимания нет. Порой надо выбрать железо для системы, решающей некоторую задачу, порой – понять почему очевидно быстрый код работает медленно. Часто приходится разбираться в новых технологиях, фреймворках, языках, сервисах, библиотеках, но все это дается легко только в том случае, если есть устойчивая база, отвечающая на вопрос - "как это работает и почему именно так?". Во всем перечисленном поможет знание АПС.
|
Mathematical applications, whatever form they take — simulation, automation, computation, or something else — require an instrument to execute them: a computer. Understanding how your primary instrument is structured and how it works provides a clear advantage over those who lack that understanding. Sometimes you need to choose hardware for a system solving a particular problem; sometimes you need to figure out why obviously fast code is running slowly. You frequently have to get up to speed with new technologies, frameworks, languages, services, and libraries — but all of this comes easily only when there is a solid foundation that answers the question: "How does this work, and why does it work this way?" Knowledge of APS helps with all of the above.
|
||||||
|
|
||||||
"Разобраться в работе компьютера" не значит "делать(разрабатывать) компьютер". Врачи знают как устроен человек, чтобы лечить его, а не разрабатывать его. Гонщики знают свой автомобиль, чтобы совершенствовать его и использовать по-полной. Также и выпускнику прикладной математики необходимо понимание работы компьютера не для того, чтобы разрабатывать процессоры, а для более эффективного и разумного его использования в своих приложениях.
|
"Understanding how a computer works" does not mean "building (designing) a computer." Doctors know how the human body is structured in order to treat it, not to design it. Racing drivers know their cars in order to optimize and fully exploit them. Likewise, an applied mathematics graduate needs to understand how a computer works not in order to design processors, but to use the computer more effectively and intelligently in their own applications.
|
||||||
|
|
||||||
### Радиотехники
|
### Radio Engineering
|
||||||
|
|
||||||
Использование радиоволн сегодня помогает в решении огромного круга задач связанных с передачей информации/энергии на расстояние, локацией, позиционированием, изучением свойств объектов отражения и многим другим на что только фантазии хватит. На практике радиоволны оказываются удивительно полезными, и для того чтобы управлять ими и извлекать из них максимум, используются антенны. Эти устройства могут быть довольно сложными, и за ними должны стоять профессионалы, способные их создать. Управляют антеннами, контролируют их и получают с них информацию специальные устройства, которые, в конечном итоге, преобразуют радиосигналы в электрические цифровые, или наоборот.
|
The use of radio waves today helps solve an enormous range of problems related to transmitting information and energy over a distance, locating and positioning objects, studying the properties of reflecting objects, and much more — limited only by one's imagination. In practice, radio waves turn out to be remarkably useful, and antennas are the devices used to control them and extract maximum value from them. These devices can be quite complex, and professionals capable of designing them are needed behind them. The devices that control, monitor, and receive information from antennas are specialized systems that ultimately convert radio signals into electrical digital signals, or vice versa.
|
||||||
|
|
||||||
Современные микросхемы СВЧ (сверхвысоких частот), которые используются в антенных устройствах, часто являются программируемыми. Это означает, что они либо содержат в себе процессор, либо спроектированы для взаимодействия с процессорами. Чтобы раскрыть потенциал этих микросхем, вам нужно знать, как работают процессоры. Понимание их функций также пригодится в области радиотехники, особенно если вам нужно управлять сигналами в строгие временные рамки.
|
Modern microwave integrated circuits (operating at extremely high frequencies), used in antenna systems, are frequently programmable. This means they either contain a processor or are designed to interact with processors. To unlock the full potential of these chips, you need to know how processors work. Understanding their functions is also valuable in radio engineering, especially when you need to control signals within strict timing constraints.
|
||||||
|
|
||||||
Радиотехника — это не только работа с радиосигналами, но и их обработка. Иногда нужно обрабатывать сигналы очень быстро. В таких случаях важно знать, какой вычислитель выбрать, чтобы обеспечить точность обработки в установленные временные рамки и при этом не превысить требования по энергопотреблению. Без понимания АПС вы не сможете решать такие задачи. Ведь приходится выбирать из множества устройств, включая микроконтроллеры и процессоры цифровой обработки сигналов с различными характеристиками, ПЛИС. А как это сделать, если даже не понимаешь что это такое.
|
Radio engineering is not just about working with radio signals, but also about processing them. Sometimes signals must be processed very quickly. In such cases it is important to know which computing device to choose to ensure processing accuracy within the required time constraints while staying within power consumption requirements. Without an understanding of APS you cannot solve such problems — because you have to choose from a wide range of devices, including microcontrollers, digital signal processors with various characteristics, and FPGAs. But how can you make that choice if you do not even understand what these things are?
|
||||||
|
|
||||||
По сути, радиотехник – это специалист, который может не только посчитать антенну, но и создать ее, а также разработать систему управления, сбора и обработки данных с использованием знаний АПС.
|
In essence, a radio engineer is a specialist who can not only calculate an antenna design, but also build it and develop systems for control, data acquisition, and processing — using the knowledge gained from APS.
|
||||||
|
|
||||||
Радиотехника связана с радиосигналами, а радиосигналы всегда связаны с процессорами в современной аппаратуре. И если вы хотите быть в центре этой захватывающей области, изучение АПС — важный шаг на этом пути.
|
Radio engineering is tied to radio signals, and radio signals in modern equipment are always tied to processors. If you want to be at the forefront of this exciting field, studying APS is an important step on that path.
|
||||||
|
|
||||||
## Как читать эту книгу
|
## How to Read This Book
|
||||||
|
|
||||||
Книга рассчитана на широкий охват аудитории по уровню их подготовки на момент начала прослушивания дисциплины АПС, поэтому для кого-то некоторые материалы окажутся избыточными, а для кого-то — крайне необходимыми.
|
The book is designed for a wide range of readers with varying levels of preparation at the start of the APS course, so some material may be redundant for some readers while being essential for others.
|
||||||
|
|
||||||
Вне зависимости от вашего уровня подготовки, работу с этим курсом рекомендуется начать с прочтения документов из части: "Введение".
|
Regardless of your background, it is recommended to begin by reading the documents in the "Introduction" section.
|
||||||
|
|
||||||
Далее можно приступать к разделу "Лабораторные работы". Перед каждым лабораторным занятием вам **рекомендуется** ознакомиться с методичкой, т.к. они очень подробные и их чтение требует какого-то времени. Время, отведенное на лабораторное занятие, рекомендуется использовать по-максимуму: заниматься практической деятельностью, консультироваться с преподавателем, отлаживать разработанные блоки устройства и тому подобное, а для этого лучше прочитать методичку заранее.
|
You can then proceed to the "Lab Assignments" section. Before each lab session, you are **strongly encouraged** to read the corresponding lab guide in advance, as the guides are quite detailed and require some time to read. The time allocated for the lab session itself should be used to maximum effect: carrying out practical work, consulting with your instructor, debugging the device blocks you have designed, and so on — all of which requires having read the guide beforehand.
|
||||||
|
|
||||||
Кроме того, важно отметить, что в начале многих лабораторных работ указаны **дополнительные материалы для подготовки**, где перечислены все материалы со ссылками на главы раздела "Базовые конструкции SystemVerilog", которые студент **должен освоить** перед выполнением этой лабораторной работы. Данный раздел ориентирован в первую очередь на студентов, не работавших ранее с Verilog/SystemVerilog, однако, даже если вы работали с этими языками, рекомендуется пролистать данные главы и проверить свои знания в разделе "Проверь себя".
|
It is also important to note that at the beginning of many lab assignments, **additional preparation materials** are listed, with references to chapters in the "Basic SystemVerilog Constructs" section that the student **must study** before completing that lab. This section is primarily aimed at students who have not previously worked with Verilog/SystemVerilog; however, even if you have experience with these languages, it is recommended to skim through those chapters and test your knowledge in the "Check Yourself" section.
|
||||||
|
|
||||||
Лабораторные занятия будут проходить с использованием САПР `Vivado` (и отладочными стендами `Nexys A7`). Это очень сложный профессиональный инструмент, на полноценное изучение которого могут уйти годы. Во время данного курса лабораторных работ нет времени на годы изучения Vivado, поэтому для вас собрана основная информация по взаимодействию с САПР в разделе "Основы Vivado". Этой информации хватит, чтобы с помощью `Vivado` реализовать весь цикл лабораторных работ.
|
Lab sessions will use the `Vivado` EDA tool (along with `Nexys A7` development boards). This is a very complex professional tool that can take years to master fully. During this lab course there is no time for years of Vivado study, so the essential information for working with the tool has been compiled for you in the "Vivado Basics" section. This information is sufficient to complete the entire lab cycle using `Vivado`.
|
||||||
|
|
||||||
Традиционно, данные лабораторные считаются сложными. Однако за годы отработки методичек со студентами, было написано множество вспомогательных материалов, уточнений, а также акцентов на места, которые могут привести к ошибке. В данный момент, для успешного выполнения лабораторной работы от студента требуется только внимательно прочитать предоставленный ему материал и не бояться задать вопрос, если что-то непонятно.
|
Traditionally, these lab assignments are considered challenging. However, over the years of refining the guides with students, numerous supplementary materials, clarifications, and notes highlighting potential pitfalls have been added. At this point, successfully completing a lab assignment requires only that the student read the provided material carefully and not be afraid to ask a question if something is unclear.
|
||||||
|
|
||||||
Если вы читаете данную книгу не в рамках курса АПС, вы вольны в выборе как программных средств, так и способов отладки. [Репозиторий](https://github.com/MPSU/APS), сопровождающий эту книгу будет содержать некоторые файлы, специализированные для плат Nexys A7 (так называемые _ограничения_/_констрейны_), однако при должном уровне навыков вы с легкостью сможете портировать его под свою плату. В этому случае, авторы будут признательны, если вы предоставите получившиеся файлы и название платы, чтобы их можно было добавить в отдельную папку по другим платам для будущих читателей. По всем вопросам/замечаниям/предложениям вы можете связаться с авторами курса через разделы `Issues` и `Discussions` данного репозитория.
|
If you are reading this book outside the APS course, you are free to choose your own software tools and debugging approaches. The [repository](https://github.com/MPSU/APS) accompanying this book will contain some files specific to Nexys A7 boards (so-called _constraints_), but with the appropriate level of skill you will easily be able to port them to your own board. In that case, the authors would appreciate it if you could contribute the resulting files along with the board name, so they can be added to a separate folder for other boards for the benefit of future readers. For any questions, comments, or suggestions, you can contact the course authors through the `Issues` and `Discussions` sections of the repository.
|
||||||
|
|
||||||
Эта книга может быть интересна и полезна читателю, не имеющему никакой отладочной платы: проверка работоспособности осуществляется в первую очередь на моделировании, т.е. программно (на самом деле, 90% времени вы будете проверять все именно посредством моделирования).
|
This book can also be useful and interesting for readers who do not have any development board: functionality is verified primarily through simulation, i.e., in software (in fact, 90% of the time you will be testing everything through simulation).
|
||||||
|
|
||||||
В ходе выполнения лабораторных работ вы наверняка столкнетесь как с ошибками, связанными с работой Vivado, так и с ошибками описания на языке SystemVerilog. В первую очередь, рекомендуется ознакомиться с текстом ошибки. В случае ошибок, связанных с языком SystemVerilog, чаще всего там содержится вся необходимая информация по её устранению. В случае, если текст непонятен, рекомендуется ознакомиться со [списком типичных ошибок](Other/FAQ.md).
|
In the course of completing the lab assignments, you will inevitably encounter both errors related to Vivado's operation and errors in your SystemVerilog code. The first recommendation is always to read the error message carefully. For SystemVerilog-related errors, the message most often contains all the information needed to resolve the issue. If the message is unclear, consult the [list of common errors](Other/FAQ.md).
|
||||||
|
|
||||||
Материал этой книги будет пестрить множеством ссылок, которые в электронной версии этой книги, разумеется, будут кликабельными. Однако, если вы имеете удовольствие читать эту книгу в "аналоговом" формате, для вашего удобства все ссылки будут представлены в виде сносок под соответствующей страницей в текстовом формате. Текстовый формат вместо QR-кодов выбран чтобы иметь возможность ввести ссылку вручную (все ссылки будут представлены в формате Unicode, так что не беспокойтесь, что вам придется вводить что-то наподобие "https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B8%D0%B3%D0%B3%D0%B5%D1%80"). Кроме того, "умные" камеры современных смартфонов отлично справляются с распознаванием текстовых ссылок, поэтому авторы надеются, что и с этой стороны отсутствие QR-кодов не произведет неудобств.
|
The material in this book contains many links, which in the electronic version are of course clickable. However, if you have the pleasure of reading this book in "analog" format, all links are provided as footnotes on the corresponding page in plain text. Plain text was chosen over QR codes to allow links to be typed in manually (all links are in Unicode format, so do not worry about having to type something like "https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B8%D0%B3%D0%B3%D0%B5%D1%80"). Furthermore, the smart cameras on modern smartphones handle text link recognition very well, so the authors hope that the absence of QR codes will not cause inconvenience in that regard either.
|
||||||
|
|
||||||
Большая часть информации, касающаяся архитектуры RISC-V, взята напрямую из спецификации. Поскольку работа над спецификацией всё ещё идёт (хотя базовый набор инструкций rv32i уже заморожен и не изменится), чтобы ссылки на конкретные страницы спецификации имели смысл, они будут даваться на следующие версии двух документов:
|
The majority of the information concerning the RISC-V architecture is taken directly from the specification. Since work on the specification is still ongoing (although the base rv32i instruction set is now frozen and will not change), all references to specific pages of the specification will point to the following versions of two documents:
|
||||||
|
|
||||||
- "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA" — [версия документа `20240411`](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/unpriv-isa-asciidoc.pdf);
|
- "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA" — [document version `20240411`](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/unpriv-isa-asciidoc.pdf);
|
||||||
- "The RISC-V Instruction Set Manual Volume II: Privileged Architecture" — [версия документа `20240411`](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf).
|
- "The RISC-V Instruction Set Manual Volume II: Privileged Architecture" — [document version `20240411`](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf).
|
||||||
|
|
||||||
Курс лабораторных работ неразрывно связан с онлайн-репозиторием, расположенным по адресу: https://github.com/MPSU/APS. Этот репозиторий хранит методические материалы, верификационное окружение, готовые модули и файлы ограничений для отладочного стенда Nexys A7.
|
The lab course is inseparably linked to the online repository located at: https://github.com/MPSU/APS. This repository contains the course materials, verification environment, ready-made modules, and constraint files for the Nexys A7 development board.
|
||||||
|
|
||||||
По всем вопросам/замечаниям/предложениям вы можете связаться с авторами курса через разделы Issues и Discussions данного репозитория.
|
For any questions, comments, or suggestions, you can contact the course authors through the Issues and Discussions sections of this repository.
|
||||||
|
|
||||||
Данный курс непрерывно эволюционировал на протяжении нескольких лет до самого своего издания. Авторы допускают, что где-то в тексте могли остаться некоторые недочёты, которые после издания тиража уже "не вырубишь топором". Для того чтобы дать читателям возможность узнать об ошибках, найденных уже после издания, в корне репозитория находится специальный документ errata.
|
This course has evolved continuously over several years up until its publication. The authors acknowledge that some imperfections may remain in the text that can no longer be corrected after printing. To allow readers to learn about errors discovered after publication, a dedicated errata document is located at the root of the repository.
|
||||||
|
|
||||||
## Как пользоваться репозиторием
|
## How to Use the Repository
|
||||||
|
|
||||||
В корне репозитория находятся следующие элементы (символом ‘/’ на конце обозначены папки):
|
The root of the repository contains the following items (folders are marked with a trailing '/'):
|
||||||
|
|
||||||
- <p style="color:LightGray;">.github/</p>
|
- <p style="color:LightGray;">.github/</p>
|
||||||
- <p style="color:LightGray;">.pic/</p>
|
- <p style="color:LightGray;">.pic/</p>
|
||||||
@@ -124,11 +124,11 @@
|
|||||||
- <p style="color:LightGray;">LICENSE</p>
|
- <p style="color:LightGray;">LICENSE</p>
|
||||||
- <p style="color:LightGray;">README.md</p>
|
- <p style="color:LightGray;">README.md</p>
|
||||||
|
|
||||||
Серым цветом обозначены элементы, которые не потребуются в ходе выполнения лабораторных работ.
|
Items shown in gray are not needed when completing the lab assignments.
|
||||||
|
|
||||||
В папках Introduction, Basic Verilog structures и Vivado Basics описаны разделы 1, 3 и 4 данной книги. Папка Other, среди прочего, содержит информацию, формирующую раздел 5 данной книги.
|
The Introduction, Basic Verilog structures, and Vivado Basics folders contain the material corresponding to Parts 1, 3, and 4 of this book, respectively. The Other folder contains, among other things, the material that forms Part 5 of this book.
|
||||||
|
|
||||||
Рассмотрим структуру папки Labs:
|
The structure of the Labs folder is as follows:
|
||||||
|
|
||||||
01. Adder/
|
01. Adder/
|
||||||
02. Arithmetic-logic unit/
|
02. Arithmetic-logic unit/
|
||||||
@@ -149,46 +149,46 @@
|
|||||||
Made-up modules/
|
Made-up modules/
|
||||||
Readme.md
|
Readme.md
|
||||||
|
|
||||||
Здесь находятся методические материалы ко всем 16 лабораторным работам, разложенные по соответствующим им папкам.
|
Each of these folders contains the instructional materials for the corresponding lab assignment.
|
||||||
|
|
||||||
Практически в каждой такой папке находится файл формата _lab_xx.tb_xxx.sv_ — это файл с верификационным окружением для данной лабораторной работы. Такой файл необходимо добавлять в _Simulation Sources_ проекта (подробнее в разделе _Vivado Basics_).
|
In almost every such folder there is a file named _lab_xx.tb_xxx.sv_ — this is the verification environment (testbench) file for that lab assignment. This file must be added to the _Simulation Sources_ of the project (see the _Vivado Basics_ section for details).
|
||||||
|
|
||||||
Кроме того, в папке лабораторной работы могут находиться _xxx_pkg.sv_ и _xxx.mem_ файлы, содержащие соответственно параметры и данные, которыми необходимо проинициализировать память устройства. Такие файлы будет необходимо добавлять в _Design Sources_ проекта.
|
Additionally, a lab folder may contain _xxx_pkg.sv_ and _xxx.mem_ files, holding parameters and data, respectively, that are used to initialize the device memory. These files must be added to the _Design Sources_ of the project.
|
||||||
|
|
||||||
Ещё в большинстве папок будет находиться папка _board files_. Такая папка содержит модуль верхнего уровня (если требуется), описание способов взаимодействия с ним, а также файлы ограничений (_constraints_) под отладочную плату _Nexys A7_.
|
Most folders also contain a _board files_ subfolder. This subfolder contains the top-level module (if required), a description of how to interact with it, and constraint files for the _Nexys A7_ development board.
|
||||||
|
|
||||||
Помимо прочего, в папке `Made-up modules/` находятся готовые модули для некоторых лабораторных работ. В случае, если по какой-то причине вы не смогли выполнить лабораторную работу, вы можете продолжить работу над курсом, использовав готовый модуль из этой папки.
|
Furthermore, the `Made-up modules/` folder contains pre-built modules for certain lab assignments. If for any reason you were unable to complete a lab assignment, you can continue working through the course by using the corresponding ready-made module from this folder.
|
||||||
|
|
||||||
У репозитория есть зеркало (копия сайта), расположенное по адресу: https://gitlab.chips-miet.ru/MPSU/APS. Структура файлов в зеркале полностью совпадает с исходным репозиторием.
|
The repository has a mirror located at: https://gitlab.chips-miet.ru/MPSU/APS. The file structure of the mirror is identical to the original repository.
|
||||||
|
|
||||||
## История курса и разработчики
|
## Course History and Contributors
|
||||||
|
|
||||||
Дисциплины связанные с организацией вычислительной техники читаются в МИЭТ с самого его основания. Текущий курс эволюционировал из "Микропроцессорных средств и систем" (МПСиС), читаемый факультету МПиТК (Микроприборов и технической кибернетики) сначала [Савченко Юрием Васильевичем](https://miet.ru/person/10551), а после – [Переверзевым Алексеем Леонидовичем](https://miet.ru/person/49309). С 2014 по 2022 годы дисциплина проводилась и значительно модернизировалась [Поповым Михаилом Геннадиевичем](https://miet.ru/person/50480) совместно с коллективом сотрудников и студентов Института МПСУ. С 2022 года группам ИБ, ИКТ, КТ и РТ курс читает [Силантьев Александр Михайлович](https://miet.ru/person/64030), а группам ИВТ, ПИН, ПМ – [Орлов Александр Николаевич](https://miet.ru/person/53686), разработка методических материалов перешла в руки [Солодовникова Андрея Павловича](https://miet.ru/person/141139).
|
Disciplines related to computer organization have been taught at MIET since its founding. The current course evolved from "Microprocessor Means and Systems" (MMS), taught to the MPiTK (Microdevices and Technical Cybernetics) faculty — first by [Yuri Vasilyevich Savchenko](https://miet.ru/person/10551), and later by [Alexei Leonidovich Pereverzev](https://miet.ru/person/49309). From 2014 to 2022, the course was conducted and significantly modernized by [Mikhail Gennadyevich Popov](https://miet.ru/person/50480) together with a team of staff and students from the MPSU Institute. Since 2022, the course for the IB, IKT, KT, and RT student groups has been taught by [Alexander Mikhailovich Silantyev](https://miet.ru/person/64030), while the IVT, PIN, and PM groups are taught by [Alexander Nikolaevich Orlov](https://miet.ru/person/53686); the development of course materials has been taken over by [Andrei Pavlovich Solodovnikov](https://miet.ru/person/141139).
|
||||||
|
|
||||||
В 2019-2023 годах была значительно переработана, осовременена и дополнена теоретическая часть курса. Тогда же разработаны и полностью обновлены лабораторные работы с переходом на использование архитектуры RISC-V, введены новые способы оценки полученных знаний. Все материалы курса включая [видеозаписи лекций](https://www.youtube.com/c/АПСПопов), были выложены в свободный доступ.
|
Between 2019 and 2023 the theoretical part of the course was substantially revised, modernized, and expanded. During the same period, the lab assignments were redesigned and fully updated to use the RISC-V architecture, and new methods for assessing student knowledge were introduced. All course materials, including [lecture recordings](https://www.youtube.com/c/АПСПопов), were made publicly available.
|
||||||
|
|
||||||
Основное влияние на структуру и содержание курса в современном виде оказали: оригинальные лекции МПСиС для МПиТК, курс Вычислительных структур 6.004, читаемый в MIT, Харрис и Харрис "Цифровая схемотехника и архитектура компьютера", Орлов и Цилькер "Организация ЭВМ и систем".
|
The primary influences on the structure and content of the course in its current form are: the original MMS lectures for MPiTK, the 6.004 Computation Structures course taught at MIT, Harris & Harris "Digital Design and Computer Architecture," and Orlov & Tsil'ker "Computer Organization and Systems."
|
||||||
|
|
||||||
С подготовкой курса и репозитория помогали студенты и сотрудники института МПСУ (бывшие и нынешние): <!--- В алфавитном порядке -->
|
The following current and former students and staff of the MPSU Institute helped prepare the course and repository: <!--- In alphabetical order -->
|
||||||
|
|
||||||
| Фамилия, Имя, Отчество | Вклад в курс |
|
| Full Name | Contribution to the course |
|
||||||
|-------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Барков Евгений Сергеевич | Профессиональные консультации по деталям языка SystemVerilog, спецификации RISC-V и RTL-разработки, тематике синтеза и констрейнов. |
|
| Barkov Evgeny Sergeyevich | Professional consultations on SystemVerilog language details, the RISC-V specification, RTL development, synthesis, and constraints. |
|
||||||
| Булавин Никита Сергеевич | Отработка материалов, подготовка тестбенчей и модулей верхнего уровня для плат Nexys A7 для лабораторных работ. |
|
| Bulavin Nikita Sergeyevich | Refinement of materials, preparation of testbenches and top-level modules for Nexys A7 boards for the lab assignments. |
|
||||||
| Козин Алексей Александрович | Отработка материалов, подготовка обфусцированных модулей для лабораторных работ. |
|
| Kozin Alexei Alexandrovich | Refinement of materials, preparation of obfuscated modules for the lab assignments. |
|
||||||
| [Кулешов Владислав Константинович](https://t.me/SaintLiver) | Вычитка и исправление ошибок в методических материалах, сбор обратной связи от студентов. |
|
| [Kuleshov Vladislav Konstantinovich](https://t.me/SaintLiver) | Proofreading and correction of errors in the course materials, collection of student feedback. |
|
||||||
| Орлов Александр Николаевич | Профессиональные консультации по деталям языка SystemVerilog, спецификации RISC-V и RTL-разработки, примерам программ иллюстрирующим особенности архитектуры. |
|
| Orlov Alexander Nikolaevich | Professional consultations on SystemVerilog language details, the RISC-V specification, RTL development, and example programs illustrating architectural features. |
|
||||||
| Примаков Евгений Владимирович | Профессиональные консультации по деталям языка SystemVerilog, спецификации RISC-V и RTL-разработки и вопросам микроархитектуры. |
|
| Primakov Evgeny Vladimirovich | Professional consultations on SystemVerilog language details, the RISC-V specification, RTL development, and microarchitecture topics. |
|
||||||
| [Протасова Екатерина Андреевна](https://t.me/Katkus_s) | Подготовка индивидуальных заданий и допусков к лабораторным работам, вычитка и отработка материалов, а также сбор обратной связи от студентов. |
|
| [Protasova Ekaterina Andreyevna](https://t.me/Katkus_s) | Preparation of individual assignments and pre-lab admission tasks, proofreading and refinement of materials, collection of student feedback. |
|
||||||
| Русановский Богдан Витальевич | Перенос лабораторной работы по прерываниям из PDF в Markdown, подготовка иллюстраций. |
|
| Rusanovsky Bogdan Vitalyevich | Migration of the interrupt lab assignment from PDF to Markdown, preparation of illustrations. |
|
||||||
| Рыжкова Дарья Васильевна | Подготовка тестбенчей для лабораторных работ. |
|
| Ryzhkova Darya Vasilyevna | Preparation of testbenches for the lab assignments. |
|
||||||
| Силантьев Александр Михайлович | Профессиональные консультации по деталям языка SystemVerilog, спецификации RISC-V и RTL-разработки, вопросам микроархитектуры, тематике синтеза и констрейнов, особенностям компиляции и профилирования. |
|
| Silantyev Alexander Mikhailovich | Professional consultations on SystemVerilog language details, the RISC-V specification, RTL development, microarchitecture topics, synthesis and constraints, and compilation and profiling specifics. |
|
||||||
| Стрелков Даниил Владимирович | Отработка материалов, подготовка тестбенчей для лабораторных работ и иллюстраций структуры курса. |
|
| Strelkov Daniil Vladimirovich | Refinement of materials, preparation of testbenches for the lab assignments, and preparation of course structure illustrations. |
|
||||||
| [Терновой Николай Эдуардович](https://t.me/cpu_design) | Профессиональные консультации по деталям языка SystemVerilog, спецификации RISC-V и RTL-разработки, вычитка материалов, сбор обратной связи от студентов. |
|
| [Ternovoy Nikolai Eduardovich](https://t.me/cpu_design) | Professional consultations on SystemVerilog language details, the RISC-V specification, RTL development, proofreading of materials, collection of student feedback. |
|
||||||
| Харламов Александр Александрович | Отработка материалов, проектирование вспомогательных модулей для лабораторных работ. |
|
| Kharlamov Alexander Alexandrovich | Refinement of materials, design of auxiliary modules for the lab assignments. |
|
||||||
| [Хисамов Василь Тагирович](https://t.me/PascalVT) | Вычитка материалов, сбор обратной связи от студентов. |
|
| [Khisamov Vasil Tagirovich](https://t.me/PascalVT) | Proofreading of materials, collection of student feedback. |
|
||||||
| Чусов Сергей Андреевич | Вычитка материалов, сбор обратной связи от студентов. |
|
| Chusov Sergei Andreyevich | Proofreading of materials, collection of student feedback. |
|
||||||
|
|
||||||
Кроме того, часть иллюстраций была нарисована Краснюк Екатериной Александровной.
|
In addition, some of the illustrations were drawn by Ekaterina Alexandrovna Krasnyuk.
|
||||||
|
|
||||||
На этом вводное слово окончено, желаю вам успехов в этом увлекательнейшем путешествии!
|
With that, the introductory remarks are complete — I wish you success on this most fascinating journey!
|
||||||
|
|||||||
96
.github/SUMMARY.md
vendored
@@ -1,68 +1,68 @@
|
|||||||
# Summary
|
# Summary
|
||||||
|
|
||||||
[Порядок выполнения лабораторных работ для групп](index.md)
|
[Lab schedule by group](index.md)
|
||||||
[Предисловие](Intro.md)
|
[Preface](Intro.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Введение
|
# Introduction
|
||||||
|
|
||||||
- [О данном разделе](Introduction/README.md)
|
- [About this section](Introduction/README.md)
|
||||||
- [Что такое Язык Описания Аппаратуры](Introduction/What%20is%20HDL.md)
|
- [What is a Hardware Description Language](Introduction/What%20is%20HDL.md)
|
||||||
- [Как работает ПЛИС](Introduction/How%20FPGA%20works.md)
|
- [How FPGAs work](Introduction/How%20FPGA%20works.md)
|
||||||
- [Последовательностная логика](Introduction/Sequential%20logic.md)
|
- [Sequential logic](Introduction/Sequential%20logic.md)
|
||||||
- [Этапы реализации проекта в ПЛИС](Introduction/Implementation%20steps.md)
|
- [FPGA implementation steps](Introduction/Implementation%20steps.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Лабораторные работы
|
# Laboratory works
|
||||||
|
|
||||||
- [Лабораторная №1. Сумматор](Labs/01.%20Adder/README.md)
|
- [Lab 1. Adder](Labs/01.%20Adder/README.md)
|
||||||
- [Лабораторная №2. АЛУ](Labs/02.%20Arithmetic-logic%20unit/README.md)
|
- [Lab 2. ALU](Labs/02.%20Arithmetic-logic%20unit/README.md)
|
||||||
- [Лабораторная №3. Регистровый файл и внешняя память](Labs/03.%20Register%20file%20and%20memory/README.md)
|
- [Lab 3. Register file and external memory](Labs/03.%20Regiter%20file%20and%20memory/README.md)
|
||||||
- [Лабораторная №4. Простейшее программируемое устройство](Labs/04.%20Primitive%20programmable%20device/README.md)
|
- [Lab 4. Primitive programmable device](Labs/04.%20Primtive%20programmable%20device/README.md)
|
||||||
- [Написание программы под процессор CYBERcobra](Labs/04.%20Primitive%20programmable%20device/Индивидуальное%20задание/README.md)
|
- [Writng a program for the CYBERcobra processor](Labs/04.%20Primtive%20programmable%20device/Индивидуальное%20задание/README.md)
|
||||||
- [Лабораторная №5. Декодер инструкций](Labs/05.%20Main%20decoder/README.md)
|
- [Lab 5. Instruction decoder](Labs/05.%20Main%20decoder/README.md)
|
||||||
- [Лабораторная №6. Основная память](Labs/06.%20Main%20memory/README.md)
|
- [Lab 6. Main memory](Labs/06.%20Main%20memory/README.md)
|
||||||
- [Лабораторная №7. Тракт данных](Labs/07.%20Datapath/README.md)
|
- [Lab 7. Datapath](Labs/07.%20Datapath/README.md)
|
||||||
- [Лабораторная №8. Блок загрузки и сохранения](Labs/08.%20Load-store%20unit/README.md)
|
- [Lab 8. Load-store unit](Labs/08.%20Load-store%20unit/README.md)
|
||||||
- [Лабораторная №9. Интеграция LSU](Labs/09.%20LSU%20Integration/README.md)
|
- [Lab 9. LSU integration](Labs/09.%20LSU%20Integration/README.md)
|
||||||
- [Лабораторная №10. Подсистема прерывания](Labs/10.%20Interrupt%20subsystem/README.md)
|
- [Lab 10. Interrupt subsystem](Labs/10.%20Interrupt%20subsystem/README.md)
|
||||||
- [Лабораторная №11. Интеграция подсистемы прерывания](Labs/11.%20Interrupt%20integration/README.md)
|
- [Lab 11. Interrupt subsystem integration](Labs/11.%20Interrupt%20integration/README.md)
|
||||||
- [Лабораторная №12. Блок приоритетных прерываний](Labs/12.%20Daisy%20chain/README.md)
|
- [Lab 12. Priority interrupt unit (Daisy chain)](Labs/12.%20Daisy%20chain/README.md)
|
||||||
- [Лабораторная №13. Периферийные устройства](Labs/13.%20Peripheral%20units/README.md)
|
- [Lab 13. Peripheral devices](Labs/13.%20Peripheral%20units/README.md)
|
||||||
- [Лабораторная №14. Программирование](Labs/14.%20Programming/README.md)
|
- [Lab 14. Programming](Labs/14.%20Programming/README.md)
|
||||||
- [Лабораторная №15. Программатор](Labs/15.%20Programming%20device/README.md)
|
- [Lab 15. Programmer device](Labs/15.%20Programming%20device/README.md)
|
||||||
- [Лабораторная №16. Оценка производительности](Labs/16.%20Coremark/README.md)
|
- [Lab 16. Performance evaluation](Labs/16.%20Coremark/README.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Базовые конструкции SystemVerilog
|
# Basic SystemVerilog constructs
|
||||||
|
|
||||||
- [Описание раздела](Basic%20Verilog%20structures/README.md)
|
- [Section overview](Basic%20Verilog%20structures/README.md)
|
||||||
- [Модули](Basic%20Verilog%20structures/Modules.md)
|
- [Modules](Basic%20Verilog%20structures/Modules.md)
|
||||||
- [Мультиплексоры](Basic%20Verilog%20structures/Multiplexors.md)
|
- [Multiplexers](Basic%20Verilog%20structures/Multiplexors.md)
|
||||||
- [Регистры](Basic%20Verilog%20structures/Registers.md)
|
- [Registers](Basic%20Verilog%20structures/Registers.md)
|
||||||
- [Конкатенация](Basic%20Verilog%20structures/Concatenation.md)
|
- [Concatenation](Basic%20Verilog%20structures/Concatenation.md)
|
||||||
- [Защелки](Basic%20Verilog%20structures/Latches.md)
|
- [Latches](Basic%20Verilog%20structures/Latches.md)
|
||||||
- [О различиях между блокирующими и неблокирующими присваиваниями](Basic%20Verilog%20structures/Assignments.md)
|
- [Blocking vs non-blocking assignments](Basic%20Verilog%20structures/Assignments.md)
|
||||||
- [Контроллеры](Basic%20Verilog%20structures/Controllers.md)
|
- [Controllers](Basic%20Verilog%20structures/Controllers.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Основы Vivado
|
# Vivado Basics
|
||||||
|
|
||||||
1. [Создание проекта в Vivado](Vivado%20Basics/01.%20New%20project.md)
|
1. [Creating a project in Vivado](Vivado%20Basics/01.%20New%20project.md)
|
||||||
2. [Навигатор по маршруту проектирования](Vivado%20Basics/02.%20Flow%20Navigator.md)
|
2. [Flow Navigator](Vivado%20Basics/02.%20Flow%20Navigator.md)
|
||||||
3. [Менеджер проекта](Vivado%20Basics/03.%20Project%20manager.md)
|
3. [Project Manager](Vivado%20Basics/03.%20Project%20manager.md)
|
||||||
4. [Симуляция](Vivado%20Basics/04.%20Simulation.md)
|
4. [Simulation](Vivado%20Basics/04.%20Simulation.md)
|
||||||
5. [Руководство по поиску функциональных ошибок](Vivado%20Basics/05.%20Bug%20hunting.md)
|
5. [Functional bug hunting guide](Vivado%20Basics/05.%20Bug%20hunting.md)
|
||||||
6. [Анализ RTL](Vivado%20Basics/06.%20RTL%20Analysis.md)
|
6. [RTL Analysis](Vivado%20Basics/06.%20RTL%20Analysis.md)
|
||||||
7. [Руководство по прошивке ПЛИС](Vivado%20Basics/07.%20Program%20and%20debug.md)
|
7. [FPGA programming guide](Vivado%20Basics/07.%20Program%20and%20debug.md)
|
||||||
8. [Руководство по работе с ошибками обработки кода](Vivado%20Basics/08.%20Code%20processing%20errors.md)
|
8. [Code processing errors guide](Vivado%20Basics/08.%20Code%20processing%20errors.md)
|
||||||
|
|
||||||
# Дополнительные материалы
|
# Additional materials
|
||||||
|
|
||||||
- [RV32I - Стандартный набор целочисленных инструкций RISC-V](Other/rv32i.md)
|
- [RV32I — RISC-V Base Integer Instruction Set](Other/rv32i.md)
|
||||||
- [О регистрах контроля и статуса](Other/CSR.md)
|
- [Control and Status Registers (CSR)](Other/CSR.md)
|
||||||
- [Список типичных ошибок при работе с Vivado и SystemVerilog](Other/FAQ.md)
|
- [Common Vivado & SystemVerilog pitfalls](Other/FAQ.md)
|
||||||
|
|||||||
2
.github/book_en.toml
vendored
@@ -2,7 +2,7 @@
|
|||||||
authors = ["Andrei Solodovnikov, Mikhail Popov"]
|
authors = ["Andrei Solodovnikov, Mikhail Popov"]
|
||||||
language = "en"
|
language = "en"
|
||||||
src = "./"
|
src = "./"
|
||||||
title = "Processor System Architectures"
|
title = "Architectures of Processor Systems"
|
||||||
|
|
||||||
[output.html]
|
[output.html]
|
||||||
git-repository-url = "https://github.com/MPSU/APS"
|
git-repository-url = "https://github.com/MPSU/APS"
|
||||||
|
|||||||
70
.github/index.md
vendored
@@ -1,48 +1,48 @@
|
|||||||
# Курс лабораторных работ
|
# Lab Course
|
||||||
|
|
||||||
## Полезное
|
## Useful Resources
|
||||||
|
|
||||||
- [Создание базового проекта с прошивкой ПЛИС в Vivado](Vivado%20Basics/01.%20New%20project.md)
|
- [Creating a basic project with FPGA programming in Vivado](Vivado%20Basics/01.%20New%20project.md)
|
||||||
- [Базовые конструкции Verilog](Basic%20Verilog%20structures/)
|
- [Basic Verilog Constructs](Basic%20Verilog%20structures/)
|
||||||
- [Список типичных ошибок в Vivado и SystemVerilog](Other/FAQ.md)
|
- [List of common errors in Vivado and SystemVerilog](Other/FAQ.md)
|
||||||
- [Тестовое окружение](Basic%20Verilog%20structures/Testbench.md)
|
- [Testbench](Basic%20Verilog%20structures/Testbench.md)
|
||||||
|
|
||||||
## Порядок выполнения лабораторных работ для групп
|
## Lab Sequence by Group
|
||||||
|
|
||||||
### ИБ, ИКТ, КТ, РТ
|
### IB, ICT, CT, RT
|
||||||
|
|
||||||
1. Сумматор ([01. Adder](Labs/01.%20Adder))
|
1. Adder ([01. Adder](Labs/01.%20Adder))
|
||||||
2. АЛУ ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
|
2. ALU ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
|
||||||
3. Регистровый файл и внешняя память ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
|
3. Register file and external memory ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
|
||||||
4. Простейшее программируемое устройство ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
|
4. Primitive programmable device ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
|
||||||
|
|
||||||
### ПИН, ПМ
|
### PIN, PM
|
||||||
|
|
||||||
1. Сумматор ([01. Adder](Labs/01.%20Adder))
|
1. Adder ([01. Adder](Labs/01.%20Adder))
|
||||||
2. АЛУ ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
|
2. ALU ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
|
||||||
3. Регистровый файл и внешняя память ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
|
3. Register file and external memory ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
|
||||||
4. Простейшее программируемое устройство ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
|
4. Primitive programmable device ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
|
||||||
5. Основной дешифратор ([05. Main decoder](Labs/05.%20Main%20decoder))
|
5. Main decoder ([05. Main decoder](Labs/05.%20Main%20decoder))
|
||||||
6.
|
6.
|
||||||
1. Тракт данных ([07. Datapath](Labs/07.%20Datapath))
|
1. Datapath ([07. Datapath](Labs/07.%20Datapath))
|
||||||
2. Интеграция блока загрузки и сохранения ([09. LSU Integration](Labs/09.%20LSU%20Integration))
|
2. Load-store unit integration ([09. LSU Integration](Labs/09.%20LSU%20Integration))
|
||||||
3. Интеграция подсистемы прерываний ([11. Interrupt Integration](Labs/11.%20Interrupt%20integration))
|
3. Interrupt subsystem integration ([11. Interrupt Integration](Labs/11.%20Interrupt%20integration))
|
||||||
7. Периферийные устройства ([13. Peripheral units](Labs/13.%20Peripheral%20units))
|
7. Peripheral units ([13. Peripheral units](Labs/13.%20Peripheral%20units))
|
||||||
8. Программирование ([14. Programming](Labs/14.%20Programming))
|
8. Programming ([14. Programming](Labs/14.%20Programming))
|
||||||
|
|
||||||
### ИВТ
|
### ICS
|
||||||
|
|
||||||
1. АЛУ ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
|
1. ALU ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
|
||||||
2.
|
2.
|
||||||
1. Память ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory)),
|
1. Memory ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
|
||||||
2. Простейшее программируемое устройство ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
|
2. Primitive programmable device ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
|
||||||
3. Основной дешифратор ([05. Main decoder](Labs/05.%20Main%20decoder))
|
3. Main decoder ([05. Main decoder](Labs/05.%20Main%20decoder))
|
||||||
4. Тракт данных ([07. Datapath](Labs/07.%20Datapath))
|
4. Datapath ([07. Datapath](Labs/07.%20Datapath))
|
||||||
5.
|
5.
|
||||||
1. Модуль загрузки и сохранения ([08. Load-store unit](Labs/08.%20Load-store%20unit))
|
1. Load-store unit ([08. Load-store unit](Labs/08.%20Load-store%20unit))
|
||||||
2. Интеграция блока загрузки и сохранения ([09. LSU Integration](Labs/09.%20LSU%20Integration))
|
2. Load-store unit integration ([09. LSU Integration](Labs/09.%20LSU%20Integration))
|
||||||
6.
|
6.
|
||||||
1. Контроллер прерываний ([10. Interrupt subsystem](Labs/10.%20Interrupt%20subsystem))
|
1. Interrupt controller ([10. Interrupt subsystem](Labs/10.%20Interrupt%20subsystem))
|
||||||
2. Интеграция подсистемы прерываний ([11. Interrupt Integration](Labs/11.%20Interrupt%20integration))
|
2. Interrupt subsystem integration ([11. Interrupt Integration](Labs/11.%20Interrupt%20integration))
|
||||||
7. Периферийные устройства ([13. Peripheral units](Labs/13.%20Peripheral%20units))
|
7. Peripheral units ([13. Peripheral units](Labs/13.%20Peripheral%20units))
|
||||||
8. Программирование ([14. Programming](Labs/14.%20Programming))
|
8. Programming ([14. Programming](Labs/14.%20Programming))
|
||||||
|
|||||||
2
.github/workflows/mdbook.yml
vendored
@@ -30,6 +30,8 @@ jobs:
|
|||||||
# ── 1. Checkout master (Russian) ──────────────────────────────────────
|
# ── 1. Checkout master (Russian) ──────────────────────────────────────
|
||||||
- name: Checkout master (Russian)
|
- name: Checkout master (Russian)
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: master
|
||||||
# checks out into $GITHUB_WORKSPACE (i.e. the working directory)
|
# checks out into $GITHUB_WORKSPACE (i.e. the working directory)
|
||||||
|
|
||||||
# ── 2. Install mdBook ─────────────────────────────────────────────────
|
# ── 2. Install mdBook ─────────────────────────────────────────────────
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 52 KiB |
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 241.04 133.06" style="background-color: rgb(255, 255, 255);">
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" viewBox="0 0 241.04 133.06" style="background-color: rgb(255, 255, 255);">
|
||||||
<defs>
|
<defs>
|
||||||
<style>
|
<style>
|
||||||
.cls-1 {
|
.cls-1 {
|
||||||
@@ -266,45 +266,11 @@
|
|||||||
<path class="cls-20" d="M183.28,105.24c-3.51,0-6.37-2.88-6.37-6.42s2.86-6.41,6.37-6.41,6.37,2.88,6.37,6.41-2.86,6.42-6.37,6.42ZM183.28,93.08c-3.14,0-5.69,2.58-5.69,5.74s2.55,5.74,5.69,5.74,5.69-2.58,5.69-5.74-2.55-5.74-5.69-5.74Z"/>
|
<path class="cls-20" d="M183.28,105.24c-3.51,0-6.37-2.88-6.37-6.42s2.86-6.41,6.37-6.41,6.37,2.88,6.37,6.41-2.86,6.42-6.37,6.42ZM183.28,93.08c-3.14,0-5.69,2.58-5.69,5.74s2.55,5.74,5.69,5.74,5.69-2.58,5.69-5.74-2.55-5.74-5.69-5.74Z"/>
|
||||||
<g>
|
<g>
|
||||||
<g>
|
<g>
|
||||||
<path class="cls-9" d="M168.34,113.64c-.01.1-.03.22-.06.34-.03.12-.07.24-.13.36s-.13.24-.22.35c-.09.11-.2.21-.33.29s-.28.15-.46.21c-.18.05-.38.08-.6.08-.12,0-.25-.02-.39-.05-.14-.03-.27-.08-.4-.15-.13-.07-.25-.16-.37-.28-.12-.11-.22-.25-.31-.42s-.16-.36-.21-.58c-.05-.22-.08-.47-.08-.76,0-.35.05-.67.15-.95s.23-.52.4-.71c.17-.2.36-.35.58-.45.22-.11.45-.16.7-.16.22,0,.41.02.58.07.17.05.32.11.44.19s.23.17.32.28c.09.1.16.21.21.33.05.11.09.23.12.35.03.12.05.23.05.34h-.68c-.04-.29-.13-.51-.3-.68-.16-.16-.39-.25-.68-.25-.2,0-.37.04-.52.12-.15.08-.27.2-.37.34-.1.15-.17.32-.22.53-.05.21-.07.43-.07.68,0,.28.03.52.08.72.05.2.13.37.22.5s.21.23.36.29c.14.06.3.09.48.09.13,0,.25-.02.36-.07s.21-.11.3-.2c.09-.09.17-.2.23-.33.06-.13.11-.28.13-.44h.68Z"/>
|
|
||||||
<path class="cls-9" d="M170.17,111.52h-1.45v-.63h3.62v.63h-1.45v3.6h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M173.07,112.16c0-.26.06-.48.14-.66.09-.18.21-.32.36-.43.15-.11.33-.19.54-.24.21-.05.44-.07.68-.07.2,0,.4.02.59.06.19.04.36.11.51.2s.27.21.36.36c.09.15.14.33.14.54v2.46c0,.07.02.13.05.18s.1.07.18.07c.04,0,.07,0,.11,0,.04,0,.08-.01.12-.02v.5c-.06.02-.12.03-.18.04-.06.01-.13.02-.21.02-.12,0-.23-.01-.32-.03-.09-.02-.17-.06-.23-.1s-.11-.11-.14-.19c-.03-.08-.06-.17-.07-.29-.09.1-.18.19-.28.27s-.21.16-.33.22c-.12.06-.26.11-.41.15s-.32.05-.51.05c-.16,0-.32-.03-.47-.08s-.29-.13-.41-.23c-.12-.1-.22-.23-.29-.38-.07-.15-.11-.33-.11-.53,0-.22.04-.41.11-.57.07-.16.17-.29.29-.4.12-.11.25-.19.4-.25.15-.06.31-.1.46-.12l1.18-.15c.11-.01.2-.06.27-.13.06-.08.1-.2.1-.36,0-.26-.08-.44-.25-.55-.17-.11-.41-.17-.72-.17s-.56.07-.71.2c-.16.14-.25.34-.27.61h-.67ZM175.67,112.97c-.06.04-.13.08-.21.1s-.18.05-.28.07c-.1.02-.21.04-.33.05-.12.01-.23.03-.35.04-.13.02-.25.04-.36.08-.11.03-.21.08-.29.13s-.14.12-.19.2c-.04.08-.07.17-.07.27,0,.12.02.23.06.32.04.09.09.17.16.23.07.06.15.11.24.14.09.03.2.05.31.05.07,0,.15,0,.24-.03.09-.02.19-.04.28-.08s.19-.08.29-.13c.09-.05.18-.12.25-.2.07-.08.13-.16.18-.26.04-.1.07-.21.07-.33v-.68Z"/>
|
|
||||||
<path class="cls-9" d="M180.81,109.26s-.01.09-.02.14c0,.06-.03.12-.05.18s-.06.13-.11.19c-.05.06-.11.12-.18.18-.04.03-.08.05-.11.08s-.08.04-.13.06c-.05.02-.12.03-.2.04s-.19.02-.33.02h-.3c-.2.01-.39.06-.55.13-.16.08-.31.19-.43.32-.12.14-.23.31-.31.5-.08.2-.14.41-.18.65.05-.11.12-.21.2-.31s.18-.19.3-.27.26-.15.42-.19.35-.07.57-.07c.24,0,.47.04.69.13s.41.22.57.39c.16.17.29.39.39.65s.15.56.15.9c0,.11,0,.24-.02.39s-.05.32-.09.48-.11.34-.2.5-.2.32-.35.45-.32.24-.53.32-.46.12-.75.12c-.12,0-.25,0-.38-.03-.14-.02-.27-.06-.41-.11s-.27-.13-.39-.22-.24-.22-.35-.36c-.05-.07-.1-.16-.16-.25-.05-.1-.1-.21-.14-.35-.04-.14-.08-.3-.1-.49-.03-.19-.04-.41-.04-.67,0-.17,0-.36.02-.57.02-.21.04-.43.08-.65s.09-.44.16-.64c.07-.21.15-.39.25-.54.11-.17.23-.31.35-.41s.25-.19.38-.25c.14-.06.28-.1.44-.13s.33-.04.51-.05h.25c.08-.01.16-.01.21-.02s.11-.02.15-.03c.04-.02.07-.04.09-.07.02-.03.04-.08.06-.13h.55ZM178.02,113.09c0,.08,0,.17.01.28,0,.11.03.22.06.34.03.12.07.23.12.35s.13.22.22.31c.09.09.2.17.34.22s.29.08.48.08c.21,0,.38-.03.52-.1s.26-.15.35-.26c.09-.11.16-.22.21-.35.05-.13.08-.26.11-.38.02-.12.04-.24.04-.34s0-.18,0-.23c0-.19-.02-.38-.07-.57-.04-.18-.11-.35-.21-.49-.09-.14-.22-.26-.37-.34-.15-.09-.34-.13-.56-.13s-.4.04-.56.13-.29.2-.39.35c-.1.15-.18.32-.23.51-.05.19-.08.4-.08.62Z"/>
|
|
||||||
<path class="cls-9" d="M182.02,110.89h.72v3.25h.02l2.06-3.25h.83v4.24h-.73v-3.25h-.02l-2.06,3.25h-.83v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M189.54,111.52h-1.61l-.03,1.02c-.02.51-.05.94-.12,1.29-.06.34-.15.62-.26.83-.11.21-.24.36-.39.44-.15.09-.33.13-.53.13-.07,0-.14-.01-.19-.03s-.09-.05-.12-.07v-.64c.1.04.19.06.27.06.05,0,.11,0,.16-.03.05-.02.1-.05.14-.11.05-.05.09-.13.13-.22.04-.1.07-.22.1-.38.03-.16.05-.34.07-.57s.03-.49.04-.79l.04-1.56h3.02v4.24h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M191.33,110.89h.72v1.59h1.17c.23,0,.44.03.62.09.18.06.33.15.46.27.13.11.22.25.29.42.07.16.1.35.1.55s-.03.39-.1.55c-.07.16-.16.3-.29.42-.13.12-.28.2-.46.26s-.39.09-.62.09h-1.89v-4.24ZM192.05,114.55h1.03c.12,0,.24-.01.35-.04.11-.03.2-.07.28-.13s.14-.14.18-.23c.04-.09.07-.21.07-.34s-.02-.24-.07-.34c-.05-.09-.11-.17-.19-.23-.08-.06-.18-.1-.3-.13-.12-.03-.25-.04-.39-.04h-.96v1.48Z"/>
|
|
||||||
<path class="cls-9" d="M195.34,110.89h.72v1.71h1.96v-1.71h.73v4.24h-.73v-1.9h-1.96v1.9h-.72v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M203.47,113c0,.35-.04.66-.13.94s-.22.52-.38.71c-.17.2-.37.34-.61.45-.24.1-.52.16-.82.16s-.58-.05-.82-.16c-.24-.1-.44-.25-.61-.45-.17-.2-.3-.43-.38-.71s-.13-.59-.13-.94.04-.65.13-.93c.09-.28.22-.51.38-.71.17-.2.37-.35.61-.45.24-.1.51-.16.82-.16s.58.05.82.16c.24.1.45.25.61.45.17.19.3.43.38.71.09.28.13.59.13.93ZM202.75,113c0-.23-.03-.45-.08-.65-.05-.2-.13-.37-.24-.51s-.23-.25-.39-.33c-.15-.08-.33-.12-.53-.12s-.38.04-.53.12c-.15.08-.28.19-.38.33s-.18.31-.24.51c-.05.2-.08.41-.08.65s.03.46.08.66c.05.2.13.37.24.51.1.14.23.25.38.33.15.08.33.12.53.12s.38-.04.53-.12c.15-.08.28-.19.39-.33.1-.14.18-.31.24-.51.05-.2.08-.42.08-.66Z"/>
|
|
||||||
<path class="cls-9" d="M207.86,113.78c-.03.18-.09.37-.19.54s-.22.33-.38.48c-.16.14-.34.25-.56.34-.21.09-.45.13-.71.13-.28,0-.54-.05-.78-.14-.24-.09-.45-.24-.62-.42-.17-.19-.31-.42-.41-.71s-.15-.62-.15-1c0-.26.03-.49.08-.7.06-.21.13-.4.23-.56s.21-.31.33-.43c.13-.12.26-.22.4-.3.14-.08.28-.14.43-.17s.29-.06.42-.06c.29,0,.55.04.79.13s.44.22.62.4c.17.18.3.4.4.67.09.27.14.58.14.94v.36h-3.07c0,.21.03.39.09.56.05.17.13.31.24.43.1.12.23.21.37.28s.31.1.49.1.34-.03.47-.08.24-.12.32-.2c.09-.08.16-.17.21-.27s.1-.2.13-.3h.7ZM207.19,112.68c0-.21-.04-.39-.09-.55-.06-.16-.13-.3-.24-.41s-.22-.19-.36-.25-.3-.08-.47-.08-.32.03-.46.1-.26.15-.37.27c-.1.11-.19.25-.25.41s-.1.33-.11.52h2.35Z"/>
|
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<path class="cls-9" d="M41.87,113.64c-.01.1-.03.22-.06.34-.03.12-.07.24-.13.36s-.13.24-.22.35c-.09.11-.2.21-.33.29s-.28.15-.46.21c-.18.05-.38.08-.6.08-.12,0-.25-.02-.39-.05-.14-.03-.27-.08-.4-.15-.13-.07-.25-.16-.37-.28-.12-.11-.22-.25-.31-.42s-.16-.36-.21-.58c-.05-.22-.08-.47-.08-.76,0-.35.05-.67.15-.95s.23-.52.4-.71c.17-.2.36-.35.58-.45.22-.11.45-.16.7-.16.22,0,.41.02.58.07.17.05.32.11.44.19s.23.17.32.28c.09.1.16.21.21.33.05.11.09.23.12.35.03.12.05.23.05.34h-.68c-.04-.29-.13-.51-.3-.68-.16-.16-.39-.25-.68-.25-.2,0-.37.04-.52.12-.15.08-.27.2-.37.34-.1.15-.17.32-.22.53-.05.21-.07.43-.07.68,0,.28.03.52.08.72.05.2.13.37.22.5s.21.23.36.29c.14.06.3.09.48.09.13,0,.25-.02.36-.07s.21-.11.3-.2c.09-.09.17-.2.23-.33.06-.13.11-.28.13-.44h.68Z"/>
|
|
||||||
<path class="cls-9" d="M43.71,111.52h-1.45v-.63h3.62v.63h-1.45v3.6h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M46.6,112.16c0-.26.06-.48.14-.66.09-.18.21-.32.36-.43.15-.11.33-.19.54-.24.21-.05.44-.07.68-.07.2,0,.4.02.59.06.19.04.36.11.51.2s.27.21.36.36c.09.15.14.33.14.54v2.46c0,.07.02.13.05.18s.1.07.18.07c.04,0,.07,0,.11,0,.04,0,.08-.01.12-.02v.5c-.06.02-.12.03-.18.04-.06.01-.13.02-.21.02-.12,0-.23-.01-.32-.03-.09-.02-.17-.06-.23-.1s-.11-.11-.14-.19c-.03-.08-.06-.17-.07-.29-.09.1-.18.19-.28.27s-.21.16-.33.22c-.12.06-.26.11-.41.15s-.32.05-.51.05c-.16,0-.32-.03-.47-.08s-.29-.13-.41-.23c-.12-.1-.22-.23-.29-.38-.07-.15-.11-.33-.11-.53,0-.22.04-.41.11-.57.07-.16.17-.29.29-.4.12-.11.25-.19.4-.25.15-.06.31-.1.46-.12l1.18-.15c.11-.01.2-.06.27-.13.06-.08.1-.2.1-.36,0-.26-.08-.44-.25-.55-.17-.11-.41-.17-.72-.17s-.56.07-.71.2c-.16.14-.25.34-.27.61h-.67ZM49.21,112.97c-.06.04-.13.08-.21.1s-.18.05-.28.07c-.1.02-.21.04-.33.05-.12.01-.23.03-.35.04-.13.02-.25.04-.36.08-.11.03-.21.08-.29.13s-.14.12-.19.2c-.04.08-.07.17-.07.27,0,.12.02.23.06.32.04.09.09.17.16.23.07.06.15.11.24.14.09.03.2.05.31.05.07,0,.15,0,.24-.03.09-.02.19-.04.28-.08s.19-.08.29-.13c.09-.05.18-.12.25-.2.07-.08.13-.16.18-.26.04-.1.07-.21.07-.33v-.68Z"/>
|
|
||||||
<path class="cls-9" d="M54.34,109.26s-.01.09-.02.14c0,.06-.03.12-.05.18s-.06.13-.11.19c-.05.06-.11.12-.18.18-.04.03-.08.05-.11.08s-.08.04-.13.06c-.05.02-.12.03-.2.04s-.19.02-.33.02h-.3c-.2.01-.39.06-.55.13-.16.08-.31.19-.43.32-.12.14-.23.31-.31.5-.08.2-.14.41-.18.65.05-.11.12-.21.2-.31s.18-.19.3-.27.26-.15.42-.19.35-.07.57-.07c.24,0,.47.04.69.13s.41.22.57.39c.16.17.29.39.39.65s.15.56.15.9c0,.11,0,.24-.02.39s-.05.32-.09.48-.11.34-.2.5-.2.32-.35.45-.32.24-.53.32-.46.12-.75.12c-.12,0-.25,0-.38-.03-.14-.02-.27-.06-.41-.11s-.27-.13-.39-.22-.24-.22-.35-.36c-.05-.07-.1-.16-.16-.25-.05-.1-.1-.21-.14-.35-.04-.14-.08-.3-.1-.49-.03-.19-.04-.41-.04-.67,0-.17,0-.36.02-.57.02-.21.04-.43.08-.65s.09-.44.16-.64c.07-.21.15-.39.25-.54.11-.17.23-.31.35-.41s.25-.19.38-.25c.14-.06.28-.1.44-.13s.33-.04.51-.05h.25c.08-.01.16-.01.21-.02s.11-.02.15-.03c.04-.02.07-.04.09-.07.02-.03.04-.08.06-.13h.55ZM51.55,113.09c0,.08,0,.17.01.28,0,.11.03.22.06.34.03.12.07.23.12.35s.13.22.22.31c.09.09.2.17.34.22s.29.08.48.08c.21,0,.38-.03.52-.1s.26-.15.35-.26c.09-.11.16-.22.21-.35.05-.13.08-.26.11-.38.02-.12.04-.24.04-.34s0-.18,0-.23c0-.19-.02-.38-.07-.57-.04-.18-.11-.35-.21-.49-.09-.14-.22-.26-.37-.34-.15-.09-.34-.13-.56-.13s-.4.04-.56.13-.29.2-.39.35c-.1.15-.18.32-.23.51-.05.19-.08.4-.08.62Z"/>
|
|
||||||
<path class="cls-9" d="M55.55,110.89h.72v3.25h.02l2.06-3.25h.83v4.24h-.73v-3.25h-.02l-2.06,3.25h-.83v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M63.07,111.52h-1.61l-.03,1.02c-.02.51-.05.94-.12,1.29-.06.34-.15.62-.26.83-.11.21-.24.36-.39.44-.15.09-.33.13-.53.13-.07,0-.14-.01-.19-.03s-.09-.05-.12-.07v-.64c.1.04.19.06.27.06.05,0,.11,0,.16-.03.05-.02.1-.05.14-.11.05-.05.09-.13.13-.22.04-.1.07-.22.1-.38.03-.16.05-.34.07-.57s.03-.49.04-.79l.04-1.56h3.02v4.24h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M64.86,110.89h.72v1.59h1.17c.23,0,.44.03.62.09.18.06.33.15.46.27.13.11.22.25.29.42.07.16.1.35.1.55s-.03.39-.1.55c-.07.16-.16.3-.29.42-.13.12-.28.2-.46.26s-.39.09-.62.09h-1.89v-4.24ZM65.58,114.55h1.03c.12,0,.24-.01.35-.04.11-.03.2-.07.28-.13s.14-.14.18-.23c.04-.09.07-.21.07-.34s-.02-.24-.07-.34c-.05-.09-.11-.17-.19-.23-.08-.06-.18-.1-.3-.13-.12-.03-.25-.04-.39-.04h-.96v1.48Z"/>
|
|
||||||
<path class="cls-9" d="M68.88,110.89h.72v1.71h1.96v-1.71h.73v4.24h-.73v-1.9h-1.96v1.9h-.72v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M77.01,113c0,.35-.04.66-.13.94s-.22.52-.38.71c-.17.2-.37.34-.61.45-.24.1-.52.16-.82.16s-.58-.05-.82-.16c-.24-.1-.44-.25-.61-.45-.17-.2-.3-.43-.38-.71s-.13-.59-.13-.94.04-.65.13-.93c.09-.28.22-.51.38-.71.17-.2.37-.35.61-.45.24-.1.51-.16.82-.16s.58.05.82.16c.24.1.45.25.61.45.17.19.3.43.38.71.09.28.13.59.13.93ZM76.28,113c0-.23-.03-.45-.08-.65-.05-.2-.13-.37-.24-.51s-.23-.25-.39-.33c-.15-.08-.33-.12-.53-.12s-.38.04-.53.12c-.15.08-.28.19-.38.33s-.18.31-.24.51c-.05.2-.08.41-.08.65s.03.46.08.66c.05.2.13.37.24.51.1.14.23.25.38.33.15.08.33.12.53.12s.38-.04.53-.12c.15-.08.28-.19.39-.33.1-.14.18-.31.24-.51.05-.2.08-.42.08-.66Z"/>
|
|
||||||
<path class="cls-9" d="M81.4,113.78c-.03.18-.09.37-.19.54s-.22.33-.38.48c-.16.14-.34.25-.56.34-.21.09-.45.13-.71.13-.28,0-.54-.05-.78-.14-.24-.09-.45-.24-.62-.42-.17-.19-.31-.42-.41-.71s-.15-.62-.15-1c0-.26.03-.49.08-.7.06-.21.13-.4.23-.56s.21-.31.33-.43c.13-.12.26-.22.4-.3.14-.08.28-.14.43-.17s.29-.06.42-.06c.29,0,.55.04.79.13s.44.22.62.4c.17.18.3.4.4.67.09.27.14.58.14.94v.36h-3.07c0,.21.03.39.09.56.05.17.13.31.24.43.1.12.23.21.37.28s.31.1.49.1.34-.03.47-.08.24-.12.32-.2c.09-.08.16-.17.21-.27s.1-.2.13-.3h.7ZM80.72,112.68c0-.21-.04-.39-.09-.55-.06-.16-.13-.3-.24-.41s-.22-.19-.36-.25-.3-.08-.47-.08-.32.03-.46.1-.26.15-.37.27c-.1.11-.19.25-.25.41s-.1.33-.11.52h2.35Z"/>
|
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<path class="cls-9" d="M92.48,35.25h1.05l1.11,3.47h.02l1.13-3.47h.99v4.24h-.68v-3.41h-.02l-1.11,3.41h-.69l-1.11-3.41h-.02v3.41h-.67v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M101.42,38.14c-.03.18-.09.37-.19.54s-.22.33-.38.48c-.16.14-.34.25-.56.34-.21.09-.45.13-.71.13-.28,0-.54-.05-.78-.14-.24-.09-.45-.24-.62-.42-.17-.19-.31-.42-.41-.71s-.15-.62-.15-1c0-.26.03-.49.08-.7.06-.21.13-.4.23-.56s.21-.31.33-.43c.13-.12.26-.22.4-.3.14-.08.28-.14.43-.17s.29-.06.42-.06c.29,0,.55.04.79.13s.44.22.62.4c.17.18.3.4.4.67.09.27.14.58.14.94v.36h-3.07c0,.21.03.39.09.56.05.17.13.31.24.43.1.12.23.21.37.28s.31.1.49.1.34-.03.47-.08.24-.12.32-.2c.09-.08.16-.17.21-.27s.1-.2.13-.3h.7ZM100.74,37.05c0-.21-.04-.39-.09-.55-.06-.16-.13-.3-.24-.41s-.22-.19-.36-.25-.3-.08-.47-.08-.32.03-.46.1-.26.15-.37.27c-.1.11-.19.25-.25.41s-.1.33-.11.52h2.35Z"/>
|
|
||||||
<path class="cls-9" d="M103.43,35.89h-1.45v-.63h3.62v.63h-1.45v3.6h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M106.32,36.52c0-.26.06-.48.14-.66.09-.18.21-.32.36-.43.15-.11.33-.19.54-.24.21-.05.44-.07.68-.07.2,0,.4.02.59.06.19.04.36.11.51.2s.27.21.36.36c.09.15.14.33.14.54v2.46c0,.07.02.13.05.18s.1.07.18.07c.04,0,.07,0,.11,0,.04,0,.08-.01.12-.02v.5c-.06.02-.12.03-.18.04-.06.01-.13.02-.21.02-.12,0-.23-.01-.32-.03-.09-.02-.17-.06-.23-.1s-.11-.11-.14-.19c-.03-.08-.06-.17-.07-.29-.09.1-.18.19-.28.27s-.21.16-.33.22c-.12.06-.26.11-.41.15s-.32.05-.51.05c-.16,0-.32-.03-.47-.08s-.29-.13-.41-.23c-.12-.1-.22-.23-.29-.38-.07-.15-.11-.33-.11-.53,0-.22.04-.41.11-.57.07-.16.17-.29.29-.4.12-.11.25-.19.4-.25.15-.06.31-.1.46-.12l1.18-.15c.11-.01.2-.06.27-.13.06-.08.1-.2.1-.36,0-.26-.08-.44-.25-.55-.17-.11-.41-.17-.72-.17s-.56.07-.71.2c-.16.14-.25.34-.27.61h-.67ZM108.93,37.34c-.06.04-.13.08-.21.1s-.18.05-.28.07c-.1.02-.21.04-.33.05-.12.01-.23.03-.35.04-.13.02-.25.04-.36.08-.11.03-.21.08-.29.13s-.14.12-.19.2c-.04.08-.07.17-.07.27,0,.12.02.23.06.32.04.09.09.17.16.23.07.06.15.11.24.14.09.03.2.05.31.05.07,0,.15,0,.24-.03.09-.02.19-.04.28-.08s.19-.08.29-.13c.09-.05.18-.12.25-.2.07-.08.13-.16.18-.26.04-.1.07-.21.07-.33v-.68Z"/>
|
|
||||||
<path class="cls-9" d="M114.11,38c-.01.1-.03.22-.06.34-.03.12-.07.24-.13.36s-.13.24-.22.35c-.09.11-.2.21-.33.29s-.28.15-.46.21c-.18.05-.38.08-.6.08-.12,0-.25-.02-.39-.05-.14-.03-.27-.08-.4-.15-.13-.07-.25-.16-.37-.28-.12-.11-.22-.25-.31-.42s-.16-.36-.21-.58c-.05-.22-.08-.47-.08-.76,0-.35.05-.67.15-.95s.23-.52.4-.71c.17-.2.36-.35.58-.45.22-.11.45-.16.7-.16.22,0,.41.02.58.07.17.05.32.11.44.19s.23.17.32.28c.09.1.16.21.21.33.05.11.09.23.12.35.03.12.05.23.05.34h-.68c-.04-.29-.13-.51-.3-.68-.16-.16-.39-.25-.68-.25-.2,0-.37.04-.52.12-.15.08-.27.2-.37.34-.1.15-.17.32-.22.53-.05.21-.07.43-.07.68,0,.28.03.52.08.72.05.2.13.37.22.5s.21.23.36.29c.14.06.3.09.48.09.13,0,.25-.02.36-.07s.21-.11.3-.2c.09-.09.17-.2.23-.33.06-.13.11-.28.13-.44h.68Z"/>
|
|
||||||
<path class="cls-9" d="M115.94,35.89h-1.45v-.63h3.62v.63h-1.45v3.6h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M118.84,36.52c0-.26.06-.48.14-.66.09-.18.21-.32.36-.43.15-.11.33-.19.54-.24.21-.05.44-.07.68-.07.2,0,.4.02.59.06.19.04.36.11.51.2s.27.21.36.36c.09.15.14.33.14.54v2.46c0,.07.02.13.05.18s.1.07.18.07c.04,0,.07,0,.11,0,.04,0,.08-.01.12-.02v.5c-.06.02-.12.03-.18.04-.06.01-.13.02-.21.02-.12,0-.23-.01-.32-.03-.09-.02-.17-.06-.23-.1s-.11-.11-.14-.19c-.03-.08-.06-.17-.07-.29-.09.1-.18.19-.28.27s-.21.16-.33.22c-.12.06-.26.11-.41.15s-.32.05-.51.05c-.16,0-.32-.03-.47-.08s-.29-.13-.41-.23c-.12-.1-.22-.23-.29-.38-.07-.15-.11-.33-.11-.53,0-.22.04-.41.11-.57.07-.16.17-.29.29-.4.12-.11.25-.19.4-.25.15-.06.31-.1.46-.12l1.18-.15c.11-.01.2-.06.27-.13.06-.08.1-.2.1-.36,0-.26-.08-.44-.25-.55-.17-.11-.41-.17-.72-.17s-.56.07-.71.2c-.16.14-.25.34-.27.61h-.67ZM121.44,37.34c-.06.04-.13.08-.21.1s-.18.05-.28.07c-.1.02-.21.04-.33.05-.12.01-.23.03-.35.04-.13.02-.25.04-.36.08-.11.03-.21.08-.29.13s-.14.12-.19.2c-.04.08-.07.17-.07.27,0,.12.02.23.06.32.04.09.09.17.16.23.07.06.15.11.24.14.09.03.2.05.31.05.07,0,.15,0,.24-.03.09-.02.19-.04.28-.08s.19-.08.29-.13c.09-.05.18-.12.25-.2.07-.08.13-.16.18-.26.04-.1.07-.21.07-.33v-.68Z"/>
|
|
||||||
<path class="cls-9" d="M126.58,33.62s-.01.09-.02.14c0,.06-.03.12-.05.18s-.06.13-.11.19c-.05.06-.11.12-.18.18-.04.03-.08.05-.11.08s-.08.04-.13.06c-.05.02-.12.03-.2.04s-.19.02-.33.02h-.3c-.2.01-.39.06-.55.13-.16.08-.31.19-.43.32-.12.14-.23.31-.31.5-.08.2-.14.41-.18.65.05-.11.12-.21.2-.31s.18-.19.3-.27.26-.15.42-.19.35-.07.57-.07c.24,0,.47.04.69.13s.41.22.57.39c.16.17.29.39.39.65s.15.56.15.9c0,.11,0,.24-.02.39s-.05.32-.09.48-.11.34-.2.5-.2.32-.35.45-.32.24-.53.32-.46.12-.75.12c-.12,0-.25,0-.38-.03-.14-.02-.27-.06-.41-.11s-.27-.13-.39-.22-.24-.22-.35-.36c-.05-.07-.1-.16-.16-.25-.05-.1-.1-.21-.14-.35-.04-.14-.08-.3-.1-.49-.03-.19-.04-.41-.04-.67,0-.17,0-.36.02-.57.02-.21.04-.43.08-.65s.09-.44.16-.64c.07-.21.15-.39.25-.54.11-.17.23-.31.35-.41s.25-.19.38-.25c.14-.06.28-.1.44-.13s.33-.04.51-.05h.25c.08-.01.16-.01.21-.02s.11-.02.15-.03c.04-.02.07-.04.09-.07.02-.03.04-.08.06-.13h.55ZM123.79,37.45c0,.08,0,.17.01.28,0,.11.03.22.06.34.03.12.07.23.12.35s.13.22.22.31c.09.09.2.17.34.22s.29.08.48.08c.21,0,.38-.03.52-.1s.26-.15.35-.26c.09-.11.16-.22.21-.35.05-.13.08-.26.11-.38.02-.12.04-.24.04-.34s0-.18,0-.23c0-.19-.02-.38-.07-.57-.04-.18-.11-.35-.21-.49-.09-.14-.22-.26-.37-.34-.15-.09-.34-.13-.56-.13s-.4.04-.56.13-.29.2-.39.35c-.1.15-.18.32-.23.51-.05.19-.08.4-.08.62Z"/>
|
|
||||||
<path class="cls-9" d="M127.79,35.25h.72v3.25h.02l2.06-3.25h.83v4.24h-.73v-3.25h-.02l-2.06,3.25h-.83v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M135.31,35.89h-1.61l-.03,1.02c-.02.51-.05.94-.12,1.29-.06.34-.15.62-.26.83-.11.21-.24.36-.39.44-.15.09-.33.13-.53.13-.07,0-.14-.01-.19-.03s-.09-.05-.12-.07v-.64c.1.04.19.06.27.06.05,0,.11,0,.16-.03.05-.02.1-.05.14-.11.05-.05.09-.13.13-.22.04-.1.07-.22.1-.38.03-.16.05-.34.07-.57s.03-.49.04-.79l.04-1.56h3.02v4.24h-.72v-3.6Z"/>
|
|
||||||
<path class="cls-9" d="M137.1,35.25h.72v1.59h1.17c.23,0,.44.03.62.09.18.06.33.15.46.27.13.11.22.25.29.42.07.16.1.35.1.55s-.03.39-.1.55c-.07.16-.16.3-.29.42-.13.12-.28.2-.46.26s-.39.09-.62.09h-1.89v-4.24ZM137.82,38.91h1.03c.12,0,.24-.01.35-.04.11-.03.2-.07.28-.13s.14-.14.18-.23c.04-.09.07-.21.07-.34s-.02-.24-.07-.34c-.05-.09-.11-.17-.19-.23-.08-.06-.18-.1-.3-.13-.12-.03-.25-.04-.39-.04h-.96v1.48Z"/>
|
|
||||||
<path class="cls-9" d="M141.11,35.25h.72v1.71h1.96v-1.71h.73v4.24h-.73v-1.9h-1.96v1.9h-.72v-4.24Z"/>
|
|
||||||
<path class="cls-9" d="M149.24,37.37c0,.35-.04.66-.13.94s-.22.52-.38.71c-.17.2-.37.34-.61.45-.24.1-.52.16-.82.16s-.58-.05-.82-.16c-.24-.1-.44-.25-.61-.45-.17-.2-.3-.43-.38-.71s-.13-.59-.13-.94.04-.65.13-.93c.09-.28.22-.51.38-.71.17-.2.37-.35.61-.45.24-.1.51-.16.82-.16s.58.05.82.16c.24.1.45.25.61.45.17.19.3.43.38.71.09.28.13.59.13.93ZM148.52,37.37c0-.23-.03-.45-.08-.65-.05-.2-.13-.37-.24-.51s-.23-.25-.39-.33c-.15-.08-.33-.12-.53-.12s-.38.04-.53.12c-.15.08-.28.19-.38.33s-.18.31-.24.51c-.05.2-.08.41-.08.65s.03.46.08.66c.05.2.13.37.24.51.1.14.23.25.38.33.15.08.33.12.53.12s.38-.04.53-.12c.15-.08.28-.19.39-.33.1-.14.18-.31.24-.51.05-.2.08-.42.08-.66Z"/>
|
|
||||||
<path class="cls-9" d="M153.63,38.14c-.03.18-.09.37-.19.54s-.22.33-.38.48c-.16.14-.34.25-.56.34-.21.09-.45.13-.71.13-.28,0-.54-.05-.78-.14-.24-.09-.45-.24-.62-.42-.17-.19-.31-.42-.41-.71s-.15-.62-.15-1c0-.26.03-.49.08-.7.06-.21.13-.4.23-.56s.21-.31.33-.43c.13-.12.26-.22.4-.3.14-.08.28-.14.43-.17s.29-.06.42-.06c.29,0,.55.04.79.13s.44.22.62.4c.17.18.3.4.4.67.09.27.14.58.14.94v.36h-3.07c0,.21.03.39.09.56.05.17.13.31.24.43.1.12.23.21.37.28s.31.1.49.1.34-.03.47-.08.24-.12.32-.2c.09-.08.16-.17.21-.27s.1-.2.13-.3h.7ZM152.96,37.05c0-.21-.04-.39-.09-.55-.06-.16-.13-.3-.24-.41s-.22-.19-.36-.25-.3-.08-.47-.08-.32.03-.46.1-.26.15-.37.27c-.1.11-.19.25-.25.41s-.1.33-.11.52h2.35Z"/>
|
|
||||||
</g>
|
</g>
|
||||||
<path class="cls-9" d="M207.89,106.17h-24.62c-16.21,0-28.54-8.27-36.63-24.59-7.91-15.95-15.88-24.03-23.67-24.03s-15.76,8.09-23.67,24.03c-8.09,16.32-20.42,24.59-36.63,24.59h-24.63v-13.17h1.01v12.16h23.62c15.8,0,27.82-8.09,35.73-24.03,8.09-16.32,16.36-24.59,24.57-24.59s16.48,8.27,24.57,24.59c7.91,15.95,19.93,24.03,35.73,24.03h23.61v-12.16h1.01v13.17Z"/>
|
<path class="cls-9" d="M207.89,106.17h-24.62c-16.21,0-28.54-8.27-36.63-24.59-7.91-15.95-15.88-24.03-23.67-24.03s-15.76,8.09-23.67,24.03c-8.09,16.32-20.42,24.59-36.63,24.59h-24.63v-13.17h1.01v12.16h23.62c15.8,0,27.82-8.09,35.73-24.03,8.09-16.32,16.36-24.59,24.57-24.59s16.48,8.27,24.57,24.59c7.91,15.95,19.93,24.03,35.73,24.03h23.61v-12.16h1.01v13.17Z"/>
|
||||||
</svg>
|
<text x="123.1" y="39.5" font-family="Arial, Helvetica, sans-serif" font-size="8" fill="#231f20" text-anchor="middle">metastable</text><text x="59.9" y="115.2" font-family="Arial, Helvetica, sans-serif" font-size="8" fill="#231f20" text-anchor="middle">stable</text><text x="186.4" y="115.2" font-family="Arial, Helvetica, sans-serif" font-size="8" fill="#231f20" text-anchor="middle">stable</text></svg>
|
||||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 394 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 325 KiB After Width: | Height: | Size: 322 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 240 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 299 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 215 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 246 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 250 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 9.9 KiB |
@@ -1,24 +1,24 @@
|
|||||||
# О различиях между блокирующими и неблокирующими присваиваниями
|
# Blocking vs. Non-Blocking Assignments
|
||||||
|
|
||||||
Вскоре после начала курса студенты сталкиваются с понятиями "блокирующего" и "неблокирующего" присваивания. Часто объяснения преподавателей по этой теме сопровождаются словами "последовательный" и "параллельный", а также предлагается _просто запомнить_ [[1, стр. 2]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf):
|
Early in the course, students encounter the concepts of "blocking" and "non-blocking" assignments. Explanations from instructors on this topic are often accompanied by the words "sequential" and "parallel", and students are told to _simply remember_ [[1, p. 2]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf):
|
||||||
|
|
||||||
- при описании последовательностной логики (регистров) используйте **неблокирующее** присваивание;
|
- when describing sequential logic (registers), use the **non-blocking** assignment;
|
||||||
- при описании комбинационной логики используйте **блокирующее** присваивание.
|
- when describing combinational logic, use the **blocking** assignment.
|
||||||
|
|
||||||
Давайте разберемся что это за присваивания и почему необходимо руководствоваться этими правилами.
|
Let us understand what these assignments are and why these rules must be followed.
|
||||||
|
|
||||||
Начать придется издалека. Несмотря на то, что SystemVerilog является **языком описания аппаратуры**, он так же является и языком для верификации описанной аппаратуры (слово `Verilog` является объединением двух слов: `verification` и `logic` [[2](http://archive.computerhistory.org/resources/access/text/2013/11/102746653-05-01-acc.pdf), стр. 24]). Для целей верификации в языке выделено целое подмножество конструкций, которые не могут быть использованы для описания аппаратуры — так называемое "_несинтезируемое подмножество языка SystemVerilog_". Разумеется, часть языка, которая может быть использована для описания аппаратуры ("_синтезируемое подмножество языка SystemVerilog_") тоже может использоваться в верификации.
|
We need to start from the basics. Although SystemVerilog is a **hardware description language**, it is also a language for verifying described hardware (the word `Verilog` is a combination of two words: `verification` and `logic` [[2](http://archive.computerhistory.org/resources/access/text/2013/11/102746653-05-01-acc.pdf), p. 24]). For verification purposes, the language defines an entire subset of constructs that cannot be used for hardware description — the so-called "_non-synthesizable subset of SystemVerilog_". Naturally, the part of the language that can be used for hardware description (the "_synthesizable subset of SystemVerilog_") can also be used in verification.
|
||||||
|
|
||||||
Давайте для начала разберемся в том, как будут использоваться операторы присваивания при программном моделировании (так называемой симуляции) — одном из инструментов верификации. Разобравшись в поведении операторов во время симуляции, будет куда проще объяснить результат использования операторов при синтезе цифровой схемы.
|
Let us first understand how assignment operators behave during software simulation — one of the verification tools. Once we understand operator behavior during simulation, it will be much easier to explain the result of using these operators during synthesis of a digital circuit.
|
||||||
|
|
||||||
Введем пару сокращений для удобства дальнейшего повествования:
|
We will introduce a couple of abbreviations for convenience:
|
||||||
|
|
||||||
- под `LHS` (left hand side) мы будем подразумевать "выражение, **которому** присваивают";
|
- `LHS` (left-hand side) refers to the "expression **to which** a value is assigned";
|
||||||
- под `RHS` (right hand side) мы будем подразумевать "выражение, **которое** присваивают".
|
- `RHS` (right-hand side) refers to the "expression **that** is assigned".
|
||||||
|
|
||||||
В выражении `a = b+c`, `a` является `LHS`, `b+c` является `RHS`.
|
In the expression `a = b+c`, `a` is the `LHS` and `b+c` is the `RHS`.
|
||||||
|
|
||||||
Существует два вида присваиваний: **непрерывное** и **процедурное**.
|
There are two types of assignments: **continuous** and **procedural**.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_1(
|
module example_1(
|
||||||
@@ -26,10 +26,10 @@ module example_1(
|
|||||||
output logic c, d
|
output logic c, d
|
||||||
);
|
);
|
||||||
|
|
||||||
// непрерывное присваивание
|
// continuous assignment
|
||||||
assign c = a + b;
|
assign c = a + b;
|
||||||
|
|
||||||
// процедурное присваивание
|
// procedural assignment
|
||||||
always_comb begin
|
always_comb begin
|
||||||
d = a + b;
|
d = a + b;
|
||||||
end
|
end
|
||||||
@@ -37,75 +37,75 @@ end
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 1. Пример непрерывного и процедурного присваивания._
|
_Listing 1. Example of a continuous and a procedural assignment._
|
||||||
|
|
||||||
С непрерывным присваиванием вы знакомитесь в самом начале — это оператор `assign`. Непрерывное присваивание постоянно следит за `RHS` этого оператора, и каждый раз, когда любая часть этого выражения меняет своё значение, производит пересчёт значения `RHS`, а затем сразу же передает это значение `LHS`. Если мы произведем `assign a = b+c`, то каждый раз, когда будет меняться значение `b` или `c`, будет пересчитываться результат их суммы, который сразу же будет присвоен выражению `a`.
|
You encounter the continuous assignment at the very beginning — it is the `assign` operator. A continuous assignment constantly monitors the `RHS` of the operator, and every time any part of that expression changes its value, it recomputes the `RHS` value and immediately transfers it to the `LHS`. If we write `assign a = b+c`, then every time `b` or `c` changes, the sum is recomputed and immediately assigned to `a`.
|
||||||
|
|
||||||
**Непрерывное присваивание может быть использовано только вне программных блоков.**
|
**A continuous assignment can only be used outside of procedural blocks.**
|
||||||
|
|
||||||
Под "программными блоками" подразумеваются блоки `always` (всех типов) и `initial`. Есть и другие программные блоки, но в рамках данного курса лабораторных работ вы с ними не столкнетесь. Вообще говоря, синтаксис языка SystemVerilog допускает использование оператора `assign` внутри программного блока (так называемое "**процедурное непрерывное присваивание**") [[2, стр. 256]](https://ieeexplore.ieee.org/document/10458102), однако в рамках данного курса не существует ни одной ситуации, когда это может потребоваться и со 100% вероятностью будет ошибочно.
|
"Procedural blocks" refer to `always` blocks (of all types) and `initial` blocks. There are other procedural blocks, but you will not encounter them in this lab course. Strictly speaking, SystemVerilog syntax allows the use of the `assign` operator inside a procedural block (the so-called "**procedural continuous assignment**") [[2, p. 256]](https://ieeexplore.ieee.org/document/10458102), but within this course there is no situation where this would be needed, and it would be an error with 100% certainty.
|
||||||
|
|
||||||
В отличие от непрерывного присваивания, **процедурное присваивание может быть использовано только в программных блоках** (процедурное присваивание в общем-то и является присваиванием, произошедшим в программном блоке).
|
Unlike the continuous assignment, **a procedural assignment can only be used inside procedural blocks** (a procedural assignment is, in essence, any assignment that occurs inside a procedural block).
|
||||||
|
|
||||||
С точки зрения моделирования (не описания аппаратуры), программный блок — это программа (в привычном вам понимании парадигмы программирования), исполняющаяся в отдельном процессе. Программные блоки исполняются независимо друг от друга по определенным событиям.
|
From a simulation perspective (not hardware description), a procedural block is a program (in the familiar programming paradigm sense) that executes in a separate process. Procedural blocks execute independently of one another in response to specific events.
|
||||||
|
|
||||||
Блоки `initial` (их может быть много) исполняются в момент начала моделирования. Блоки `always` исполняются по событиям, указанным в **списке чувствительности**:
|
`initial` blocks (there can be many) execute at the start of simulation. `always` blocks execute in response to events specified in the **sensitivity list**:
|
||||||
|
|
||||||
- `always @(posedge clk)` будет исполняться каждый раз когда произойдет положительный фронт `clk`;
|
- `always @(posedge clk)` executes every time a positive edge of `clk` occurs;
|
||||||
- `always @(a,b,c)` будет исполняться каждый раз, когда изменится значение любого из сигналов `a`,`b`,`c`;
|
- `always @(a,b,c)` executes every time the value of any of the signals `a`, `b`, `c` changes;
|
||||||
- `always @(*)` будет исполняться каждый раз, когда изменится состояние любой составляющей любого `RHS` в этом блоке (когда изменится хоть что-то, от чего зависит любое выражение слева от оператора присваивания в этом блоке).
|
- `always @(*)` executes every time any operand of any `RHS` in the block changes (whenever anything that any left-hand-side expression depends on changes).
|
||||||
|
|
||||||
Похожие правила применимы и к остальным блокам `always`: `always_comb`, `always_ff`, `always_latch` (с некоторыми оговорками, не имеющими значения в рамках данного повествования).
|
Similar rules apply to other `always` blocks: `always_comb`, `always_ff`, `always_latch` (with some caveats irrelevant to this discussion).
|
||||||
|
|
||||||
Под независимостью исполнения подразумевается то, что порядок исполнения блоков не зависит от очередности, в которой они были описаны. Более того, исполнение одного блока может быть приостановлено, чтобы исполнить другой блок.
|
Independence of execution means that the execution order of blocks does not depend on the order in which they were described. Moreover, execution of one block can be suspended to allow another block to execute.
|
||||||
|
|
||||||
А вот выражения внутри отдельного программного блока (с точки зрения моделирования) исполняются последовательно. И вот тут на сцену выходят два типа процедурного присваивания: блокирующее и неблокирующее.
|
However, expressions inside an individual procedural block are executed sequentially (from the simulation perspective). This is where the two types of procedural assignment come into play: blocking and non-blocking.
|
||||||
|
|
||||||
Блокирующее присваивание (оператор `=`) **блокирует** исполнение дальнейших выражений до завершения вычисления `RHS` и присвоения вычисленного результата `LHS` (иными словами, это привычное вам присваивание из мира программирования, там все работает точно так же).
|
A blocking assignment (operator `=`) **blocks** execution of subsequent expressions until the `RHS` has been evaluated and the result has been assigned to the `LHS` (in other words, this is the familiar assignment from programming — it works exactly the same way).
|
||||||
|
|
||||||
Неблокирующее присваивание (оператор `<=`) производит вычисление `RHS`, запоминает его, и **откладывает** присваивание вычисленного значения, позволяя выполняться остальным выражениям до завершения присваивания `LHS`.
|
A non-blocking assignment (operator `<=`) evaluates the `RHS`, saves the result, and **defers** the assignment to the `LHS`, allowing other expressions to execute before the assignment completes.
|
||||||
|
|
||||||
Рассмотрим пример, представленный на _рис. 1_.
|
Consider the example shown in _Fig. 1_.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 1. Пример цепочки блокирующих присваиваний._
|
_Figure 1. Example of a chain of blocking assignments._
|
||||||
|
|
||||||
1. Сперва вычисляется `RHS` первого присваивания программного блока — константа `5`.
|
1. First, the `RHS` of the first assignment in the procedural block is evaluated — the constant `5`.
|
||||||
2. Затем, вычисленное значение записывается в LHS первого присваивания — сигнал `a` становится равным `5`.
|
2. Then the evaluated value is written to the `LHS` of the first assignment — signal `a` becomes `5`.
|
||||||
3. Далее вычисляется `RHS` следующего присваивания — `a`, которое к этому моменту уже равно `5`.
|
3. Next, the `RHS` of the second assignment is evaluated — `a`, which is already equal to `5` at this point.
|
||||||
4. Поскольку вычисленное `RHS` равняется `5`, `LHS` второго присваивания (`b`) тоже становится равным `5`.
|
4. Since the evaluated `RHS` equals `5`, the `LHS` of the second assignment (`b`) also becomes `5`.
|
||||||
5. Аналогичным образом `c` тоже становится равным `5`.
|
5. Similarly, `c` also becomes `5`.
|
||||||
|
|
||||||
Обратите внимание, что все это произошло в нулевой момент времени. На временной диаграмме Vivado просто отобразится, что все сигналы одновременно стали равны `5`, однако с точки зрения симулятора это было не так. Другие симуляторы (например `QuestaSim`) позволяют настроить временную диаграмму таким образом, чтобы отображались все переходы между присваиваниями.
|
Note that all of this happened at time zero. Vivado's waveform will simply show that all signals became `5` simultaneously, but from the simulator's perspective that was not the case. Other simulators (e.g., `QuestaSim`) allow the waveform to be configured to display all intermediate transitions between assignments.
|
||||||
|
|
||||||
Посмотрим, как работает аналогичная цепочка неблокирующих присваиваний. Чтобы иллюстрация была более наглядной, предположим, что перед присваиваниями был исполнен какой-то код, который привел `a` в состояние `3`, `b` в `2`, `c` в `7`.
|
Now let us look at how an equivalent chain of non-blocking assignments works. To make the illustration clearer, assume that some code executed before the assignments, setting `a` to `3`, `b` to `2`, and `c` to `7`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 2. Пример цепочки неблокирующих присваиваний._
|
_Figure 2. Example of a chain of non-blocking assignments._
|
||||||
|
|
||||||
1. Сперва вычисляется значение `RHS` первого присваивания (`5`). Присваивание этого значения **откладывается** на потом.
|
1. First, the `RHS` of the first assignment (`5`) is evaluated. The assignment of this value is **deferred**.
|
||||||
2. Затем вычисляется значение `RHS` второго присваивания. Поскольку `a` еще не присвоили значение `5`, результатом `RHS` становится текущее значение `a` — 3. Присваивание этого значения сигналу `b` **откладывается** на потом.
|
2. Then the `RHS` of the second assignment is evaluated. Since `a` has not yet been assigned the value `5`, the result of the `RHS` is the current value of `a` — 3. The assignment of this value to `b` is **deferred**.
|
||||||
3. Аналогичным образом вычисляется `RHS` третьего присваивания (`2`). Присваивание этого значения также **откладывается** на потом.
|
3. Similarly, the `RHS` of the third assignment (`2`) is evaluated. Its assignment is also **deferred**.
|
||||||
|
|
||||||
Так называемое "**потом**" наступает, когда завершается вычисление `RHS` всех неблокирующих присваиваний и завершение присвоений всех блокирующих присваиваний (однако "потом" все равно происходит в тот же момент времени, обратите внимание на значение времени на _рис. 2_). В стандарте SystemVerilog этот момент называется `NBA-region` (сокр. от "Non-Blocking Assignment region") [[2, стр. 64]](https://ieeexplore.ieee.org/document/10458102). Выполнение отложенных присваиваний происходит в том же порядке, в котором они шли в программном блоке. Подробнее о том как, работает событийная симуляция (event based simulation) в SystemVerilog, вы можете прочесть в стандарте [IEEE 1800-2023](https://ieeexplore.ieee.org/document/10458102) (раздел 4). Стандарт доступен бесплатно всем желающим по программе "IEEE GET Program".
|
The so-called "**later**" arrives when all `RHS` evaluations of non-blocking assignments and all `LHS` assignments of blocking assignments have completed (however, "later" still occurs at the same simulation timestamp — note the time value in _Fig. 2_). In the SystemVerilog standard, this moment is called the `NBA-region` (short for "Non-Blocking Assignment region") [[2, p. 64]](https://ieeexplore.ieee.org/document/10458102). Deferred assignments are executed in the same order they appeared in the procedural block. For more information on how event-based simulation works in SystemVerilog, refer to the [IEEE 1800-2023](https://ieeexplore.ieee.org/document/10458102) standard (Section 4). The standard is freely available to everyone through the "IEEE GET Program".
|
||||||
|
|
||||||
Таким образом, если `LHS` **блокирующего** присваивания используется в качестве операнда `RHS` любого другого последующего присваивания, это выражение будет иметь уже обновленное значение, что очень похоже на "_последовательное вычисление_".
|
Thus, if the `LHS` of a **blocking** assignment is used as an operand of the `RHS` of any subsequent assignment, that expression will already have the updated value — much like "_sequential computation_".
|
||||||
|
|
||||||
С другой стороны значение, присвоенное `LHS` значение с помощью **неблокирующего** присваивания, не может использоваться в качестве операнда `RHS` последующих присваиваний, что создает иллюзию "_параллельного вычисления_" (см. _рис. 3_).
|
On the other hand, a value assigned to an `LHS` via a **non-blocking** assignment cannot be used as an operand of the `RHS` of subsequent assignments, creating the illusion of "_parallel computation_" (see _Fig. 3_).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 3. Иллюстрация блокирующих и неблокирующих присваиваний._
|
_Figure 3. Illustration of blocking and non-blocking assignments._
|
||||||
|
|
||||||
Теперь, понимая как работают присваивания с точки зрения моделирования, посмотрим на то, во что могут синтезироваться подобные операторы.
|
Now that we understand how assignments work from a simulation perspective, let us look at what these operators synthesize into.
|
||||||
|
|
||||||
Начнем с непрерывного присваивания. Оно превращается в провод, передающий данные от `RHS` к `LHS`. При этом вы должны следить за тем, **что** и **чему** вы присваиваете (не путайте местами `RHS` и `LHS`).
|
Starting with the continuous assignment: it becomes a wire that carries data from `RHS` to `LHS`. You must pay attention to **what** you are assigning and **to what** (do not swap `RHS` and `LHS`).
|
||||||
|
|
||||||
То, во что синтезируются блокирующие и неблокирующие присваивания зависит от описываемой логики, поэтому давайте разберём несколько примеров.
|
What blocking and non-blocking assignments synthesize into depends on the logic being described, so let us work through several examples.
|
||||||
|
|
||||||
Начнем с исходного примера c цепочкой блокирующих присваиваний, только теперь перепишем его в синтезируемом виде, сохранив изначальную идею.
|
We start with the original example using a chain of blocking assignments, but this time rewritten in a synthesizable form while preserving the original intent.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_2(
|
module example_2(
|
||||||
@@ -127,56 +127,56 @@ assign out = c;
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 2. Пример описания модуля, использующего цепочку блокирующих присваиваний._
|
_Listing 2. Example of a module description using a chain of blocking assignments._
|
||||||
|
|
||||||
Если вы уже знакомы с содержимым документа о том, [как описывать регистры](Registers.md), подумайте: какой будет результат синтеза у этой схемы?
|
If you are already familiar with the content of the document on [how to describe registers](Registers.md), think about what the synthesis result of this circuit will be.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Давайте "прочитаем" эту схему. Мы видим модуль, с входом `in`, выходом `out` и тактирующим синхроимпульсом `clk`. Также мы видим три сигнала `a`, `b`, `c`, которые описываются в блоке `always_ff`, предназначенном для описания регистров. Значение `in` по цепочке этих регистров передается до регистра `c`, выход которого подключен к выходу `out`.
|
Let us "read" this circuit. We see a module with input `in`, output `out`, and a clock signal `clk`. We also see three signals `a`, `b`, `c`, described inside an `always_ff` block intended for register description. The value of `in` is propagated through a chain of these registers up to register `c`, whose output is connected to `out`.
|
||||||
|
|
||||||
Похоже, что здесь был описан [**сдвиговый регистр**](https://ru.wikipedia.org/wiki/Регистр_(цифровая_техника)#Сдвигающие_(последовательные)_регистры), представленный на _рис. 4_.
|
It appears that a [**shift register**](https://ru.wikipedia.org/wiki/Регистр_(цифровая_техника)#Сдвигающие_(последовательные)_регистры) was described, as shown in _Fig. 4_.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 4. Трехразрядный сдвиговый регистр._
|
_Figure 4. Three-stage shift register._
|
||||||
|
|
||||||
Давайте откроем цифровую схему, сгенерированную Vivado и убедимся в наших выводах.
|
Let us open the digital schematic generated by Vivado and verify our conclusion.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 5. Схема, сгенерированная Vivado по описанию из Листинга 2._
|
_Figure 5. Schematic generated by Vivado from Listing 2._
|
||||||
|
|
||||||
Произошло что-то странное. Вместо трех регистров Vivado создал только один и судя по названию — это последний регистр `c`. Почему это произошло?
|
Something unexpected happened. Instead of three registers, Vivado created only one — and judging by the name, it is the last register `c`. Why?
|
||||||
|
|
||||||
Изучим внимательней поведение цепочки блокирующих присваиваний, представленное на _рис. 1_.
|
Let us closely examine the behavior of the blocking assignment chain shown in _Fig. 1_.
|
||||||
|
|
||||||
Каждое последующее присваивание ожидало, пока не выполнится предыдущее, таким образом, `RHS` первого присваивания (`5`) сразу же распространился по всем регистрам. Моделируя _Листинг 2_, мы получим **поведение**, когда на вход каждого регистра будет подаваться сигнал `in`.
|
Each subsequent assignment waited for the previous one to complete, so the `RHS` of the first assignment (`5`) immediately propagated through all registers. Simulating _Listing 2_, we get a **behavior** where each register receives the signal `in` directly.
|
||||||
|
|
||||||
Таким образом на самом деле, мы должны были изобразить нашу схему как на _рис. 6_.
|
Therefore, the circuit we should have drawn is the one in _Fig. 6_.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 6. Схема, описанная Листингом 2._
|
_Figure 6. Schematic described by Listing 2._
|
||||||
|
|
||||||
Но почему тогда на схеме Vivado не осталось регистров `a` и `b`? Посмотрим на них внимательней. Их выходы ни на что не влияют, они ни к чему не подключены. А значит эти регистры не имеют никакого смысла и, если их убрать, ничего не изменится.
|
But why did Vivado remove registers `a` and `b`? Looking at them more closely: their outputs have no effect — they are not connected to anything. Therefore these registers serve no purpose, and removing them changes nothing.
|
||||||
|
|
||||||
При генерации схемы, Vivado вывел в `Tcl Console` следующие предупреждения:
|
When generating the schematic, Vivado printed the following warnings to the `Tcl Console`:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
WARNING: [Synth 8-6014] Unused sequential element a_reg was removed. [example_1.sv:10]
|
WARNING: [Synth 8-6014] Unused sequential element a_reg was removed. [example_1.sv:10]
|
||||||
WARNING: [Synth 8-6014] Unused sequential element b_reg was removed. [example_1.sv:11]
|
WARNING: [Synth 8-6014] Unused sequential element b_reg was removed. [example_1.sv:11]
|
||||||
```
|
```
|
||||||
|
|
||||||
Vivado обнаружил, что регистры `a` и `b` ни на что не влияют и удалил их со схемы.
|
Vivado detected that registers `a` and `b` have no effect and removed them from the schematic.
|
||||||
|
|
||||||
Если вы используете Vivado 2023.1 и новее, вы можете обнаруживать подобные предупреждения более удобным способом — посредством линтера, который можно вызвать из вкладки `RTL ANALYSIS` окна `Flow Navigator`.
|
If you are using Vivado 2023.1 or newer, you can detect such warnings more conveniently using the linter, which can be launched from the `RTL ANALYSIS` tab in the `Flow Navigator`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 7. Пример вызова линтера._
|
_Figure 7. Example of invoking the linter._
|
||||||
|
|
||||||
Давайте заменим в _Листинге 2_ блокирующие присваивания на неблокирующие. Напоминаем, что оператор неблокирующего присваивания записывается как `<=`.
|
Now let us replace the blocking assignments in _Listing 2_ with non-blocking ones. Recall that the non-blocking assignment operator is written as `<=`.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_3(
|
module example_3(
|
||||||
@@ -198,21 +198,21 @@ assign out = c;
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 3. Пример описания модуля, использующего цепочку неблокирующих присваиваний._
|
_Listing 3. Example of a module description using a chain of non-blocking assignments._
|
||||||
|
|
||||||
Посмотрим, какую схему сгенерирует Vivado в этот раз.
|
Let us see what schematic Vivado generates this time.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 8. Схема, сгенерированная Vivado по описанию из Листинга 3._
|
_Figure 8. Schematic generated by Vivado from Listing 3._
|
||||||
|
|
||||||
Вряд ли полученный результат стал для вас неожиданным сюжетным поворотом, но давайте разберемся, почему в этот раз сгенерировалась схема, аналогичная представленной на _рис. 4_.
|
This result is probably not a surprise, but let us understand why the schematic generated this time is equivalent to the one in _Fig. 4_.
|
||||||
|
|
||||||
Для этого обратимся к примеру, представленному на _рис. 2_. В данном примере **неблокирующего присваивания** сперва вычислялись значения всех `RHS` (запоминались значения выходов всех регистров) и только потом происходило присваивание новых значений. Подобное **поведение** аналогично поведению сдвиговых регистров.
|
Referring to the example in _Fig. 2_: in the **non-blocking assignment** case, all `RHS` values were evaluated first (capturing the current output values of all registers), and only then were new values assigned. This **behavior** is analogous to that of a shift register.
|
||||||
|
|
||||||
Слово "_поведение_" было выделено дважды неспроста. Описание схем, которое мы сделали называется "**поведенческим описанием схемы**".
|
The word "_behavior_" was highlighted twice for a reason. The style of description we have been using is called "**behavioral description of a circuit**".
|
||||||
|
|
||||||
Можно ли реализовать сдвиговый регистр, используя блокирующие присваивания? Конечно. Например, можно поменять порядок присваиваний как в _Листинге 4_.
|
Can a shift register be implemented using blocking assignments? Of course. For example, we can reverse the order of assignments as in _Listing 4_.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_4(
|
module example_4(
|
||||||
@@ -234,15 +234,15 @@ assign out = c;
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 4. Цепочка блокирующих присваиваний в порядке, обратном приведенному в Листинге 2._
|
_Listing 4. Chain of blocking assignments in reverse order compared to Listing 2._
|
||||||
|
|
||||||
В этом случае, линтер не сообщит ни о каких ошибках, а Vivado сгенерирует схему, аналогичную _рис. 8_
|
In this case, the linter will report no errors, and Vivado will generate a schematic equivalent to _Fig. 8_.
|
||||||
|
|
||||||
Так произошло, поскольку мы разорвали зависимость значений `RHS` последующих присваиваний от значений `LHS` предыдущих (поведение, которое демонстрировала цепочка неблокирующих присваиваний с самого начала). Однако данное решение является скорее хаком, чем примером хорошего проектирования. По сути, мы просто подстроили код, описанный с помощью блокирующих присваиваний таким образом, чтоб он вел себя как код, использующий неблокирующие присваивания.
|
This works because we broke the dependency of subsequent `RHS` values on previous `LHS` values — the behavior that the chain of non-blocking assignments demonstrated from the start. However, this solution is more of a hack than an example of good design practice. Essentially, we manually rearranged blocking-assignment code to behave like non-blocking-assignment code.
|
||||||
|
|
||||||
Важно отметить, что при использовании неблокирующих присваиваний, их порядок вообще не имеет значения с точки зрения синтеза.
|
It is important to note that when using non-blocking assignments, their order has no effect on synthesis at all.
|
||||||
|
|
||||||
Давайте разнесем логику работы каждого регистра по отдельным блокам `always`.
|
Now let us distribute the logic for each register across separate `always` blocks.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_5(
|
module example_5(
|
||||||
@@ -270,33 +270,33 @@ assign out = c;
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 5. Сдвиговый регистр, описанный через блокирующие присваивания в отдельных блоках always._
|
_Listing 5. Shift register described using blocking assignments in separate always blocks._
|
||||||
|
|
||||||
Сгенерированная в Vivado схема будет аналогична _рис. 8_. Но давайте попробуем промоделировать работу этой схемы, подавая случайные воздействия на вход `in`.
|
The schematic generated by Vivado will be equivalent to _Fig. 8_. But let us try simulating this module with random inputs on `in`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 9. Симуляция модуля, описанного Листингом 5._
|
_Figure 9. Simulation of the module described in Listing 5._
|
||||||
|
|
||||||
Выглядит как-то не по "сдвигово-регистерски". В чем же дело?
|
This does not look like a shift register. What is happening?
|
||||||
|
|
||||||
Как уже упоминалось ранее, программные блоки (коими являются блоки `always`) исполняются во время моделирования независимо друг от друга в недетерминированном стандартом порядке. На практике это означает, что сперва может исполниться второй блок, потом третий, а потом первый — либо в любом другом порядке. Разработчик не может (и не должен) рассчитывать на порядок блоков `always` при описании схемы.
|
As mentioned earlier, procedural blocks (`always` blocks) execute independently of each other during simulation in an order that is non-deterministic per the standard. In practice, this means the second block might execute first, then the third, then the first — or in any other order. A designer cannot (and should not) rely on the execution order of `always` blocks when describing a circuit.
|
||||||
|
|
||||||
Конкретно в данной ситуации, симулятор воспроизвел блоки ровно в том порядке, в котором они были описаны. Сперва `a` получил значение `in`, потом `b` получил обновленное значение `a`, затем `c` получил обновленное значение `b`.
|
In this particular case, the simulator executed the blocks in the exact order they were described. First `a` received the value of `in`, then `b` received the updated value of `a`, then `c` received the updated value of `b`.
|
||||||
|
|
||||||
Поскольку поведение недетерминировано, нельзя однозначно сказать, какую схему должен был воспроизвести синтезатор. В данной ситуации, он воспроизвел схему которую мы хотели получить, но моделирование того же самого модуля демонстрирует поведение вовсе не этой схемы.
|
Since the behavior is non-deterministic, it is impossible to say unambiguously which circuit the synthesizer should produce. In this situation it produced the circuit we wanted, but the simulation of that same module demonstrates behavior that does not match that circuit.
|
||||||
|
|
||||||
Если заменить порядок `always` подобно тому, как мы изменили порядок в _Листинге 4_, результат на временной диаграмме совпадет с поведением сдвигового регистра.
|
If we rearrange the `always` blocks as we rearranged the assignments in _Listing 4_, the waveform result will match the behavior of a shift register.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 10. Моделирование поведения сдвигового регистра._
|
_Figure 10. Simulation of the shift register behavior._
|
||||||
|
|
||||||
Однако, как уже объяснялось ранее, вы не можете рассчитывать на такой результат. Сегодня симулятор смоделировал поведение одним образом — завтра он смоделирует этот же код (в котором не изменилась ни одна строка) по-другому, и будет по-прежнему работать в соответствии со стандартом.
|
However, as explained earlier, you cannot rely on that result. Today the simulator modeled the behavior one way — tomorrow it may model the exact same code (with not a single line changed) differently, and both runs would be fully compliant with the standard.
|
||||||
|
|
||||||
Для того, чтобы получить детерминированный результат, вам необходимо снова воспользоваться неблокирующим присваиванием, поскольку и в этом случае порядок исполнения блоков `always` не влияет на результат присваиваний — сначала вычисляются значения `RHS` всех неблокирующих присваиваний всех программных блоков, и только потом происходит присваивание этих значений `LHS`.
|
To obtain a deterministic result, you must use the non-blocking assignment, because in that case the execution order of `always` blocks does not affect the assignment results — all `RHS` values of all non-blocking assignments across all procedural blocks are evaluated first, and only then are those values assigned to their respective `LHS` targets.
|
||||||
|
|
||||||
Рассмотрим еще один пример того, как различие в присваиваниях приведет к описанию двух различных схем:
|
Let us consider one more example of how different assignment types lead to two different circuits:
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_6(
|
module example_6(
|
||||||
@@ -315,39 +315,39 @@ end
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 6. Пример цепочки блокирующих присваиваний с комбинационной логикой._
|
_Listing 6. Example of a chain of blocking assignments with combinational logic._
|
||||||
|
|
||||||
Остановитесь на минуту и подумайте, схему с каким поведением описывает _Листинг 6_?
|
Stop for a moment and think: what behavior does _Listing 6_ describe?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Как вы могли догадаться, данный листинг описывает схему с одним регистром `d`, на вход которого подается результат комбинационной логики `c & (a | b)`, поскольку сперва в `temp` попадает результат `a | b` и только после этого вычисляется значение `c & temp`.
|
As you may have guessed, this listing describes a circuit with a single register `d`, whose input receives the result of combinational logic `c & (a | b)`, because `temp` first receives the result of `a | b`, and only then is `c & temp` evaluated.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 11. Схема, сгенерированная Vivado по описанию из Листинга 6._
|
_Figure 11. Schematic generated by Vivado from Listing 6._
|
||||||
|
|
||||||
Попробуйте догадаться о том, что произойдет, если снова заменить блокирующие присваивания на неблокирующие?
|
Now try to predict what happens if we replace the blocking assignments with non-blocking ones.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Результат изменится следующим образом.
|
The result changes as follows.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 12. Схема, сгенерированная Vivado по описанию из Листинга 6 после замены блокирующих присваиваний на неблокирующие._
|
_Figure 12. Schematic generated by Vivado from Listing 6 after replacing blocking assignments with non-blocking ones._
|
||||||
|
|
||||||
Из прочтённого может сложиться впечатление, будто бы авторы хотят показать, что блокирующее присваивание — это плохо, а неблокирующее — хорошо, однако это не так. Это просто два похожих инструмента, работающих разными способами, о которых должен знать профессионал, использующий эти инструменты.
|
One might get the impression from what has been presented that the authors are trying to show that blocking assignments are bad and non-blocking are good — but that is not the case. These are simply two similar tools that work in different ways, and a professional using these tools must understand both.
|
||||||
|
|
||||||
Одно и тоже описание, использующее разные типы присваиваний может привести к синтезу разных схем.
|
The same description using different assignment types can lead to the synthesis of different circuits.
|
||||||
|
|
||||||
Рассмотрим предыдущий пример еще раз. Нельзя сказать, что одна схема лучше другой — это просто две разные схемы и то, какая из них вам нужна зависит только от вашей задачи.
|
Let us revisit the previous example. It cannot be said that one circuit is better than the other — they are simply two different circuits, and which one you need depends entirely on your task.
|
||||||
|
|
||||||
Однако нельзя не заметить, что при использовании блокирующего присваивания, мы "теряли" регистры. Более того, моделирование **неблокирующих** присваиваний ближе всего по поведению приближено к моделированию регистровой логики [[1, стр. 14]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf).
|
However, one cannot ignore the fact that with blocking assignments, we were "losing" registers. Furthermore, simulation of **non-blocking** assignments most closely approximates the behavior of register logic [[1, p. 14]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf).
|
||||||
|
|
||||||
Пока что мы рассматривали только синхронные схемы (схемы, работающие по тактовому синхроимпульсу).
|
We have only been looking at synchronous circuits (circuits driven by a clock signal) so far.
|
||||||
|
|
||||||
Рассмотрим зависимость от типа присваивания в комбинационных схемах. Для этого возьмем предыдущий пример, и уберем тактирующий синхроимпульс.
|
Now let us examine the dependency on assignment type in combinational circuits. We take the previous example and remove the clock signal.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example_7(
|
module example_7(
|
||||||
@@ -365,79 +365,79 @@ end
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 7. Пример цепочки блокирующих присваиваний в комбинационной схеме._
|
_Listing 7. Example of a chain of blocking assignments in a combinational circuit._
|
||||||
|
|
||||||
> Обратите внимание на то, что `always_ff` поменялся на `always_comb`.
|
> Note that `always_ff` has been changed to `always_comb`.
|
||||||
|
|
||||||
Как вы думаете, какая схема будет сгенерирована по описанию, представленному в _листинге 7_, и что произойдет с этой схемой, если заменить в нем все блокирующие присваивания на неблокирующие?
|
What circuit do you think will be generated from _Listing 7_, and what will happen if we replace all blocking assignments with non-blocking ones?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Вас может это удивить, но в обоих случаях будет сгенерирована схема, представленная на _рис. 13_.
|
You may be surprised, but in both cases the circuit shown in _Fig. 13_ is generated.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 13. Схема, сгенерированная Vivado по описанию из Листинга 7._
|
_Figure 13. Schematic generated by Vivado from Listing 7._
|
||||||
|
|
||||||
> Девочка остолбенела. У неё возникло отчётливое чувство какой-то ужасной несправедливости по отношению к ней. Гарри Поттер был грязным, отвратительным обманщиком и лжецом. Но во время игры все его ответы были верными. [Элиезер Юдковский / Гарри Поттер и методы рационального мышления]
|
> The girl was dumbstruck. She had a vivid sense of some terrible injustice being done to her. Harry Potter was a dirty, loathsome cheat and liar. But all his answers during the game had been correct. [Eliezer Yudkowsky / Harry Potter and the Methods of Rationality]
|
||||||
|
|
||||||
На протяжении всего документа вам рассказывали, что использование блокирующих присваиваний приведет к изменению поведения и синтезу другой схемы, а теперь сами же приводят пример, где схема остается точно такой же!
|
Throughout this document you were told that using blocking assignments would change the behavior and synthesize a different circuit — and now we present an example where the circuit remains exactly the same!
|
||||||
|
|
||||||
Давайте разберемся по порядку, что же произошло.
|
Let us work through what happened step by step.
|
||||||
|
|
||||||
Все дело в изменении блока `always`. Когда мы использовали `always_ff @(posedge clk)`, этот программный блок исполнялся только один раз за такт.
|
The key is the change in the `always` block type. When we used `always_ff @(posedge clk)`, that procedural block executed only once per clock cycle.
|
||||||
|
|
||||||
Теперь, когда мы стали использовать блок `always_comb`, правила игры изменились. Нет, принцип работы блокирующих и неблокирующих присваиваний остался тем же самым. Изменилось только то, сколько раз будет вызван данный блок.
|
Now that we are using `always_comb`, the rules have changed. The principle of how blocking and non-blocking assignments work remains the same. What changed is how many times the block is invoked.
|
||||||
|
|
||||||
Начнем со схемы, построенной по описанию, использующему блокирующее присваивание. В общем-то, тут у вас не должно было возникнуть вопросов, логика ровно та же, что была и при построении схемы по _Листингу 6_ (_рис. 11)_, только без выходного регистра. Что логично, ведь мы убрали из описания тактирующий сигнал.
|
Let us start with the circuit built from the blocking-assignment description. There should be no surprise here — the logic is exactly the same as for the circuit from _Listing 6_ (_Fig. 11_), just without the output register. Which makes sense, since we removed the clock signal from the description.
|
||||||
|
|
||||||
Вопрос в том, почему это вдруг схема, построенная после замены блокирующих присваиваний на неблокирующие ведет себя точно так же?
|
The question is why the circuit built after replacing blocking assignments with non-blocking ones behaves the same way.
|
||||||
|
|
||||||
Рассмотрим _рис. 14_.
|
Consider _Fig. 14_.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_Рисунок 14. Моделирование цепочки присваиваний в комбинационном блоке `always`._
|
_Figure 14. Simulation of an assignment chain in a combinational `always` block._
|
||||||
|
|
||||||
Комбинационный блок `always` начинает исполняться **каждый раз**, когда операнд любого `RHS` этого блока меняет своё значение.
|
A combinational `always` block starts executing **every time** any operand of any `RHS` in that block changes its value.
|
||||||
|
|
||||||
Изначально, блок `always` начал исполняться, когда операнды `a`, `b` и `c` приняли значение `1`, `0` и `1` соответственно. В этот момент (поскольку присваивание неблокирующее), вычисляются значения `RHS` для присваивания сигналам `temp` и `d`. Новое значение `temp` будет `1`, но пока что этого не произошло, и `temp` все ещё в состоянии `x`, поэтому новым значением `d` все ещё будет `x`.
|
Initially, the `always` block started executing when operands `a`, `b`, and `c` took the values `1`, `0`, and `1` respectively. At that moment (since the assignment is non-blocking), the `RHS` values for signals `temp` and `d` are evaluated. The new value of `temp` will be `1`, but that has not happened yet, and `temp` is still in the `x` state, so the new value of `d` will also still be `x`.
|
||||||
|
|
||||||
После происходит присваивание вычисленных значений сигналам `temp` и `d`.
|
Then the evaluated values are assigned to `temp` and `d`.
|
||||||
|
|
||||||
Однако `temp` является операндом `RHS` в выражении `d = c & temp`, поэтому блок `always` запускается еще один раз в этот же момент времени (в примере это `5ns`). Поскольку значения `a` и `b` не менялись, значение `RHS` первого выражения останется прежним. А вот значение `temp` уже иное, поэтому `RHS` второго выражения станет `1`.
|
However, `temp` is an operand of the `RHS` in the expression `d = c & temp`, so the `always` block is triggered again at the same simulation timestamp (in the example, this is `5ns`). Since `a` and `b` have not changed, the `RHS` of the first expression remains the same. But the value of `temp` has changed, so the `RHS` of the second expression now becomes `1`.
|
||||||
|
|
||||||
После повторного присваивания сигналы `temp` и `d` примут установившееся значение. Поскольку ни один из операндов `RHS`—выражений больше не изменил своего значения, блок `always` больше не вызывается.
|
After the second round of assignments, signals `temp` and `d` reach their steady-state values. Since no operand of any `RHS` expression has changed again, the `always` block is not triggered again.
|
||||||
|
|
||||||
Подобное поведение можно сравнить с переходным процессом в комбинационной схеме.
|
This behavior is analogous to transient settling in a combinational circuit.
|
||||||
|
|
||||||
Обратите внимание, поведение схем описанных при разных типах присваивания слегка различаются. При блокирующем присваивании все сигналы приняли установившиеся значения за один проход блока `always`, при неблокирующем потребовалось несколько проходов. Однако с точки зрения пользователя, читающего временную диаграмму, в обоих ситуациях сигналы изменили свое значение мгновенно.
|
Note that the behavior of circuits described with different assignment types differs slightly. With blocking assignments, all signals reached their steady-state values in a single pass through the `always` block; with non-blocking assignments, multiple passes were required. However, from the perspective of a user reading the waveform, the signals changed instantaneously in both cases.
|
||||||
|
|
||||||
Поэтому несмотря на различия в типах присваиваний схемы получились одинаковыми.
|
Therefore, despite the difference in assignment types, the resulting circuits are identical.
|
||||||
|
|
||||||
> Получается что для комбинационной логики нет разницы между блокирующим и неблокирующим присваиванием, после переходных процессов результат будет одинаковым?
|
> So for combinational logic there is no difference between blocking and non-blocking assignments — after transients settle the result is the same?
|
||||||
|
|
||||||
И да, и нет. С точки зрения синтеза схемы так и есть. Однако есть нюанс в случае моделирования схемы. Поведение комбинационной логики лучше моделирует блокирующее присваивание[[1, стр. 14]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf).
|
Yes and no. From a synthesis perspective, that is correct. However, there is a nuance when it comes to simulation. Blocking assignments more accurately model the behavior of combinational logic [[1, p. 14]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf).
|
||||||
|
|
||||||
## Итоги главы
|
## Chapter Summary
|
||||||
|
|
||||||
Подведем итоги прочитанному:
|
Key takeaways:
|
||||||
|
|
||||||
- Блокирующее присваивание блокирует выполнение остальных операций до завершения текущего присваивания. Оно подобно обычному присваиванию в парадигме программирования.
|
- A blocking assignment blocks execution of subsequent operations until the current assignment completes. It behaves like a regular assignment in the programming paradigm.
|
||||||
- Неблокирующее присваивание сперва вычисляет `RHS`, давая исполниться остальным операциям до самого присваивания.
|
- A non-blocking assignment first evaluates the `RHS`, allowing other operations to execute before the actual assignment takes place.
|
||||||
|
|
||||||
В связи с особенностями поведения блокирующего и неблокирующего присваивания, выведены следующие две максимы:
|
Due to the behavioral characteristics of blocking and non-blocking assignments, the following two rules apply:
|
||||||
|
|
||||||
- при описании последовательностной логики (регистров) используйте **неблокирующее** присваивание;
|
- when describing sequential logic (registers), use the **non-blocking** assignment;
|
||||||
- при описании комбинационной логики используйте **блокирующее** присваивание.
|
- when describing combinational logic, use the **blocking** assignment.
|
||||||
|
|
||||||
Кроме того, существуют следующие рекомендации и требования[[1, стр. 5]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf):
|
Additionally, the following recommendations and requirements apply [[1, p. 5]](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf):
|
||||||
|
|
||||||
- _При описании как последовательностной логики, так и комбинационной в одном блоке `always` используйте неблокирующее присваивание._
|
- _When describing both sequential and combinational logic within a single `always` block, use the non-blocking assignment._
|
||||||
- _Не смешивайте в одном блоке блокирующие и неблокирующие присваивания_ — стандарт допускает подобное описание, но оно затрудняет его чтение. Представьте, что, читая описание схемы, вам бы постоянно приходилось держать в голове, какие присваивания уже произошли, а какие только произойдут, чтобы понять как эта схема работает.
|
- _Do not mix blocking and non-blocking assignments within the same block_ — the standard allows it, but it makes the description much harder to read. Imagine having to constantly track which assignments have already occurred and which are still pending just to understand how the circuit works.
|
||||||
- _Не смешивайте блокирующие и неблокирующие присваивания для одного и того же сигнала_ — стандарт это запрещает (для блоков `always_ff`, `always_comb`, `always_latch`).
|
- _Do not mix blocking and non-blocking assignments for the same signal_ — the standard prohibits this (for `always_ff`, `always_comb`, and `always_latch` blocks).
|
||||||
|
|
||||||
## Список источников
|
## References
|
||||||
|
|
||||||
1. [Clifford E. Cummings / Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf)
|
1. [Clifford E. Cummings / Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf)
|
||||||
2. [1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language](https://ieeexplore.ieee.org/document/10458102)
|
2. [1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language](https://ieeexplore.ieee.org/document/10458102)
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
# Список типичных ошибок в SystemVerilog
|
# Common Mistakes in SystemVerilog
|
||||||
|
|
||||||
- [Список типичных ошибок в SystemVerilog](#Список-типичных-ошибок-в-systemverilog)
|
- [Common Mistakes in SystemVerilog](#common-mistakes-in-systemverilog)
|
||||||
- [имя сигнала is not a type](#имя-сигнала-is-not-a-type)
|
- [signal name is not a type](#signal-name-is-not-a-type)
|
||||||
- [cannot find port on this module](#cannot-find-port-on-this-module)
|
- [cannot find port on this module](#cannot-find-port-on-this-module)
|
||||||
- [Использование сигнала без его объявления (или до его объявления)](#Использование-сигнала-без-его-объявления-или-до-его-объявления)
|
- [Using a signal without declaring it (or before its declaration)](#using-a-signal-without-declaring-it-or-before-its-declaration)
|
||||||
- [Объявление выхода модуля его входом](#Объявление-выхода-модуля-его-входом)
|
- [Declaring a module output as an input](#declaring-a-module-output-as-an-input)
|
||||||
- [](#)
|
- [](#)
|
||||||
|
|
||||||
## имя сигнала is not a type
|
## signal name is not a type
|
||||||
|
|
||||||
Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков `always` и `initial` можно выполнять только непрерывное присваивание (через `assign`).
|
Most likely, the compiler did not recognize the assignment because it was written incorrectly. Outside of `always` and `initial` blocks, only continuous assignments (via `assign`) are allowed.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module half_adder(input logic a, input logic b, output logic c);
|
module half_adder(input logic a, input logic b, output logic c);
|
||||||
c = a ^ b; // ошибка, для непрерывного присваивания
|
c = a ^ b; // error: for a continuous assignment,
|
||||||
// необходимо ключевое слово assign
|
// the keyword assign is required
|
||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 1. Пример ошибочного присваивания._
|
_Listing 1. Example of an incorrect assignment._
|
||||||
|
|
||||||
## cannot find port on this module
|
## cannot find port on this module
|
||||||
|
|
||||||
Имя порта, указанного при подключении модуля (после точки) не соответствует ни одному имени сигналов подключаемого модуля
|
The port name specified when instantiating the module (after the dot) does not match any signal name in the instantiated module.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module half_adder(input logic a, input logic b, output logic c);
|
module half_adder(input logic a, input logic b, output logic c);
|
||||||
@@ -32,20 +32,20 @@ endmodule
|
|||||||
module testbench();
|
module testbench();
|
||||||
logic A, B, C;
|
logic A, B, C;
|
||||||
|
|
||||||
half_adder DUT(
|
adder DUT(
|
||||||
.A(A), // <- здесь будет ошибка,
|
.A(A), // <- error here,
|
||||||
// т.к. в модуле half_adder нет порта 'A'
|
// because module half_adder has no port 'A'
|
||||||
.b(B),
|
.b(B),
|
||||||
.c(C)
|
.c(C)
|
||||||
);
|
);
|
||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Листинг 2. Пример создание экземпляра модуля с ошибкой в описании его входных портов._
|
_Listing 2. Example of a module instantiation with an error in the input port description._
|
||||||
|
|
||||||
## Использование сигнала без его объявления (или до его объявления)
|
## Using a signal without declaring it (or before its declaration)
|
||||||
|
|
||||||
Достаточно частая ошибка, когда сигнал забывают объявить, либо объявляют, но потом добавляют код с использованием этого сигнала выше его объявления. Не смотря на то, что в SystemVerilog не важно, в каком порядке были описаны блоки кода, это не касается объявления сигналов — они должны выполняться до их использования. Рассмотрим следующий пример, приведенный в _листинге 3_.
|
A fairly common mistake where a signal is forgotten to be declared, or is declared but then code using that signal is added above its declaration. Although in SystemVerilog the order in which code blocks are described does not matter, this does not apply to signal declarations — they must appear before the signal is used. Consider the following example in _Listing 3_.
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module example(
|
module example(
|
||||||
@@ -72,33 +72,33 @@ module tb_example();
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
_Литсинг 3. Пример присваивания значения сигналу без его объявления._
|
_Listing 3. Example of assigning a value to a signal without declaring it._
|
||||||
|
|
||||||
Результат моделирования _листинга 3_ приведён на _рисунке 1_.
|
The simulation result of _Listing 3_ is shown in _Figure 1_.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Как вы можете увидеть, код был успешно собрался и был промоделирован, но значения в выделенных синим прямоугольниках не те, что должны были быть. Можно заметить также и то, что значение выхода `c` никогда не превышает единицу.
|
As you can see, the code compiled and was simulated successfully, but the values in the areas highlighted with blue rectangles are not what they should be. Note also that the value of output `c` never exceeds one.
|
||||||
|
|
||||||
Если мы начнем разбираться, и решим вытащить на временную диаграмму внутренний сигнал модуля `ab`, мы увидим, что он почему-то 1-битный. Более того, если раскомментировать строчку с объявлением сигнала `ab`, результат никак не изменится.
|
If we start investigating and decide to add the internal signal `ab` of the module to the waveform, we will see that it is, for some reason, 1-bit wide. Moreover, uncommenting the line with the declaration of signal `ab` will not change the result in any way.
|
||||||
|
|
||||||
Подобное поведение в точности воспроизводит требование стандарта SystemVerilog [1, стр. 108]:
|
This behavior precisely follows the requirement of the SystemVerilog standard [1, p. 108]:
|
||||||
|
|
||||||
> - Если идентификатор использовался списке сигналов, подключаемых к модулю, и этот идентификатор не был объявлен в области видимости, которая доступна при этом подключении, то неявно подразумевается 1-битный провод.
|
> - If an identifier is used in a port connection list and that identifier has not been declared in the scope accessible at the point of connection, a 1-bit net is implicitly assumed.
|
||||||
> - Если идентификатор встречается по левую сторону от оператора непрерывного присваивания, и этот идентификатор не был объявлен в той области видимости, которая доступна оператору, то неявно подразумевается 1-битный провод.
|
> - If an identifier appears on the left-hand side of a continuous assignment and that identifier has not been declared in the scope accessible to the assignment, a 1-bit net is implicitly assumed.
|
||||||
|
|
||||||
Иными словами, если вы присваиваете значение необъявленному сигналу, или пытаетесь подключить необъявленный сигнал к модулю, неявно создается 1-битный сигнал с тем же именем (попробуйте удалить объявление сигналов `a`, `b`, `c` в тестбенче _листинга 3_ и посмотрите, как изменится разрядность сигналов тестбенча на временной диаграмме).
|
In other words, if you assign a value to an undeclared signal or try to connect an undeclared signal to a module, a 1-bit signal with the same name is implicitly created (try removing the declarations of signals `a`, `b`, `c` in the testbench of _Listing 3_ and observe how the bit width of the testbench signals changes in the waveform).
|
||||||
|
|
||||||
Даже если объявите сигнал с правильной разрядностью после его использования — это уже ничему не поможет, поскольку повторные объявления уже объявленных проводов и регистров стандартом запрещены [1, стр. 91] и в зависимости от САПР будут либо проигнорированы, либо вызовут ошибку.
|
Even if you later declare the signal with the correct bit width after it has already been used — this will not help, because re-declaring already declared nets and registers is prohibited by the standard [1, p. 91] and, depending on the EDA tool, will either be ignored or cause an error.
|
||||||
|
|
||||||
Подобная ошибка легко обнаруживается линтером (появился в Vivado начиная с версии 2023.1). Кроме того, при попытке открыть схематик описанной схемы, в TCL-консоли появится сообщение об использовании необъявленного идентификатора:
|
This type of mistake is easily detected by the linter (available in Vivado starting from version 2023.1). Additionally, when attempting to open the schematic of the described design, the TCL console will display a message about the use of an undeclared identifier:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
INFO: [Synth 8-11241] undeclared symbol 'ab', assumed default net type 'wire'
|
INFO: [Synth 8-11241] undeclared symbol 'ab', assumed default net type 'wire'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Объявление выхода модуля его входом
|
## Declaring a module output as an input
|
||||||
|
|
||||||
Очень часто в попытке сэкономить себе немного времени студенты выполняют операцию копирования. В частности, копирования строк вида `input logic [7:0]` в процессе описания портов модуля. В случае, если по итогу подобного копирования, выход модуля будет объявлен как его вход (т.е. с помощью ключевого слова `input` вместо `output`).
|
Very often, in an attempt to save a little time, students use copy-paste. In particular, they copy lines like `input logic [7:0]` when describing module ports. If, as a result of such copying, a module output ends up declared as an input (i.e., using the keyword `input` instead of `output`).
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Конкатенация (объединение сигналов)
|
# Concatenation (Signal Merging)
|
||||||
|
|
||||||
Конкатенация позволяет присвоить какому-то многоразрядному сигналу "склейку" из нескольких сигналов меньшей разрядности, либо наоборот: присвоить сигнал большей разрядности группе сигналов меньшей разрядности.
|
Concatenation allows assigning a multi-bit signal the "join" of several lower-width signals, or conversely, assigning a higher-width signal to a group of lower-width signals.
|
||||||
|
|
||||||
Оператор конкатенации выглядит следующим образом: `{sig1, sig2, ..., sign}`.
|
The concatenation operator has the following form: `{sig1, sig2, ..., sign}`.
|
||||||
|
|
||||||
Предположим, у нас есть следующий набор сигналов:
|
Suppose we have the following set of signals:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -18,16 +18,16 @@ logic [1:0] d;
|
|||||||
logic [5:0] e;
|
logic [5:0] e;
|
||||||
```
|
```
|
||||||
|
|
||||||
И мы хотим, чтобы на провод `e` подавались следующие сигналы:
|
And we want the wire `e` to receive the following signals:
|
||||||
|
|
||||||
- на старший бит сигнала `e` подавался сигнал `a`
|
- the MSB of signal `e` receives signal `a`
|
||||||
- на его следующий бит подавался сигнал `b`
|
- the next bit receives signal `b`
|
||||||
- на его следующие 2 бита подавались биты `[4:3]` сигнала `c`
|
- the next 2 bits receive bits `[4:3]` of signal `c`
|
||||||
- на младшие 2 бита подавался сигнал `d`
|
- the 2 LSBs receive signal `d`
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Это можно сделать путем 4 непрерывных присваиваний:
|
This can be done using 4 continuous assignments:
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
logic a;
|
logic a;
|
||||||
@@ -43,7 +43,7 @@ assign e[3:2] = c[4:3];
|
|||||||
assign e[1:0] = d;
|
assign e[1:0] = d;
|
||||||
```
|
```
|
||||||
|
|
||||||
либо через одно присваивание, использующее конкатенацию:
|
or with a single assignment using concatenation:
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
logic a;
|
logic a;
|
||||||
@@ -56,7 +56,7 @@ logic [5:0] e;
|
|||||||
assign e = {a, b, c[4:3], d};
|
assign e = {a, b, c[4:3], d};
|
||||||
```
|
```
|
||||||
|
|
||||||
Кроме того, возможна и обратная ситуация. Предположим, мы хотим подать отдельные биты сигнала `e` на различные провода:
|
The reverse is also possible. Suppose we want to drive individual wires from separate bits of signal `e`:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ assign c[4:3] = e[3:2];
|
|||||||
assign d = e[1:0];
|
assign d = e[1:0];
|
||||||
```
|
```
|
||||||
|
|
||||||
Подобную операцию можно так же выполнить в одно выражение через конкатенацию:
|
This operation can also be expressed as a single concatenation:
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
logic a;
|
logic a;
|
||||||
@@ -87,14 +87,13 @@ logic [5:0] e;
|
|||||||
assign {a, b, c[4:3], d} = e;
|
assign {a, b, c[4:3], d} = e;
|
||||||
```
|
```
|
||||||
|
|
||||||
Кроме того, конкатенация может использоваться при **множественном дублировании** сигналов. Дублирование выполняется выражением:
|
Additionally, concatenation can be used for **signal replication**. Replication is expressed as:
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
{a, {число_повторений{повторяемый_сигнал}} ,b}
|
{a, {replication_count{signal_to_replicate}} ,b}
|
||||||
```
|
```
|
||||||
|
|
||||||
Допустим, мы хотим присвоить какому-то сигналу три копии `[4:3]` битов сигнала `c`, после которых идут сигналы `a` и `b`.
|
For example, to assign three copies of bits `[4:3]` of signal `c`, followed by signals `a` and `b`:
|
||||||
Это можно сделать выражением:
|
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
logic a;
|
logic a;
|
||||||
@@ -106,9 +105,9 @@ logic [7:0] e;
|
|||||||
assign e = { {3{c[4:3]}}, a, b};
|
assign e = { {3{c[4:3]}}, a, b};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Итоги главы
|
## Chapter Summary
|
||||||
|
|
||||||
Оператор конкатенации может быть использован для группировки и репликации сигналов по обе стороны присваивания, а именно:
|
The concatenation operator can be used to group and replicate signals on either side of an assignment:
|
||||||
|
|
||||||
- он может быть использован для присваивания сигналу большей разрядности группы сигналов меньшей разрядности
|
- it can be used to assign a group of lower-width signals to a higher-width signal
|
||||||
- он может быть использован для присваивания группе сигналов меньшей разрядности соответствующих бит сигнала большей разрядности.
|
- it can be used to assign the corresponding bits of a higher-width signal to a group of lower-width signals.
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
# Пример разработки модуля-контроллера периферийного устройства
|
# Example of Developing a Peripheral Device Controller Module
|
||||||
|
|
||||||
Для того, чтобы лучше понять, что от вас требуется в рамках лабораторной работы по периферийным устройствам, рассмотрим процесс разработки структурной схемы (не SystemVerilog-описания) для контроллера светодиодов.
|
To better understand what is required in the peripheral devices lab, let us walk through the process of developing a block diagram (not a SystemVerilog description) for an LED controller.
|
||||||
|
|
||||||
В первую очередь, здесь будет продублирована выдержка из спецификации на этот контроллер (общая часть раздела "[Описание контроллеров периферийных устройств](../Labs/13.%20Peripheral%20units/README.md#описание-контроллеров-периферийных-устройств)", а также подраздел "[Светодиоды](../Labs/13.%20Peripheral%20units/#Светодиоды)"):
|
First, we reproduce the relevant excerpt from the controller specification (the general section "[Peripheral Device Controller Descriptions](../Labs/13.%20Peripheral%20units/README.md#описание-контроллеров-периферийных-устройств)" and the subsection "[LEDs](../Labs/13.%20Peripheral%20units/#Светодиоды)"):
|
||||||
|
|
||||||
## Спецификация контроллера
|
## Controller Specification
|
||||||
|
|
||||||
### Общие термины
|
### General Terms
|
||||||
|
|
||||||
1. Под "**запросом на запись** по адресу `0xАДРЕС`" будет пониматься совокупность следующих условий:
|
1. A "**write request** to address `0xADDRESS`" refers to the combination of the following conditions:
|
||||||
1. Происходит восходящий фронт `clk_i`.
|
1. A rising edge of `clk_i` occurs.
|
||||||
2. На входе `req_i` выставлено значение `1`.
|
2. The input `req_i` is asserted to `1`.
|
||||||
3. На входе `write_enable_i` выставлено значение `1`.
|
3. The input `write_enable_i` is asserted to `1`.
|
||||||
4. На входе `addr_i` выставлено значение `0xАДРЕС`
|
4. The input `addr_i` holds the value `0xADDRESS`
|
||||||
2. Под "**запросом на чтение** по адресу `0xАДРЕС`" будет пониматься совокупность следующих условий:
|
2. A "**read request** to address `0xADDRESS`" refers to the combination of the following conditions:
|
||||||
1. Происходит восходящий фронт `clk_i`.
|
1. A rising edge of `clk_i` occurs.
|
||||||
2. На входе `req_i` выставлено значение `1`.
|
2. The input `req_i` is asserted to `1`.
|
||||||
3. На входе `write_enable_i` выставлено значение `0`.
|
3. The input `write_enable_i` is asserted to `0`.
|
||||||
4. На входе `addr_i` выставлено значение `0xАДРЕС`
|
4. The input `addr_i` holds the value `0xADDRESS`
|
||||||
|
|
||||||
Обратите внимание на то, что **запрос на чтение** должен обрабатываться **синхронно** (выходные данные должны выдаваться по положительному фронту `clk_i`) так же как был реализован порт на чтение памяти данных в [ЛР№6](../Labs/06.%20Main%20memory/).
|
Note that a **read request** must be handled **synchronously** (output data must be produced on the rising edge of `clk_i`), in the same way as the read port of the data memory was implemented in [Lab 6](../Labs/06.%20Main%20memory/).
|
||||||
|
|
||||||
При описании поддерживаемых режимов доступа по данному адресу используются следующее обозначения:
|
The following notation is used to describe the supported access modes for each address:
|
||||||
|
|
||||||
- R — доступ **только на чтение**;
|
- R — **read-only** access;
|
||||||
- W — доступ **только на запись**;
|
- W — **write-only** access;
|
||||||
- RW — доступ на **чтение и запись**.
|
- RW — **read and write** access.
|
||||||
|
|
||||||
В случае отсутствия **запроса на чтение**, на выходе `read_data_o` не должно меняться значение (тоже самое было сделано в процессе разработки памяти данных).
|
When there is no **read request**, the value on `read_data_o` must not change (the same behavior was implemented during data memory development).
|
||||||
|
|
||||||
Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу, поддерживающему только чтение), данный запрос должен игнорироваться. В случае **запроса на чтение** по недоступному адресу, на выходе `read_data_o` должно остаться прежнее значение.
|
Receiving a **write** or **read request** does not necessarily mean the controller must execute it. If a request is made to an address that does not support the requested operation (e.g., a **write request** to a read-only address), the request must be ignored. For a **read request** to an unsupported address, the value on `read_data_o` must remain unchanged.
|
||||||
|
|
||||||
В случае осуществления записи по принятому запросу, необходимо записать данные с сигнала `write_data_i` в регистр, ассоциированный с адресом `addr_i` (если разрядность регистра меньше разрядности сигнала `write_data_i`, старшие биты записываемых данных отбрасываются).
|
When a write is performed in response to a valid request, the data from `write_data_i` must be written into the register associated with `addr_i` (if the register width is less than the width of `write_data_i`, the upper bits of the written data are discarded).
|
||||||
|
|
||||||
В случае осуществления чтения по принятому запросу, необходимо по положительному фронту `clk_i` выставить данные с сигнала, ассоциированного с адресом `addr_i` на выходной сигнал `read_data_o` (если разрядность сигнала меньше разрядности выходного сигнала `read_data_o`, возвращаемые данные должны дополниться нулями в старших битах).
|
When a read is performed in response to a valid request, on the rising edge of `clk_i` the data associated with `addr_i` must be placed on the output `read_data_o` (if the signal width is less than the width of `read_data_o`, the returned data must be zero-extended in the upper bits).
|
||||||
|
|
||||||
### Светодиоды
|
### LEDs
|
||||||
|
|
||||||
Светодиоды являются простейшим устройством вывода. Поэтому, чтобы задание было интересней, для их управления был добавлен регистр, управляющий режимом вывода данных на светодиоды.
|
LEDs are the simplest output device. To make the assignment more interesting, a register controlling the LED output mode has been added.
|
||||||
Рассмотрим прототип модуля, который вам необходимо реализовать:
|
Here is the module prototype you need to implement:
|
||||||
|
|
||||||
```Verilog
|
```Verilog
|
||||||
module led_sb_ctrl(
|
module led_sb_ctrl(
|
||||||
/*
|
/*
|
||||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
Part of the module interface responsible for connection to the system bus
|
||||||
*/
|
*/
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_i,
|
input logic rst_i,
|
||||||
@@ -54,7 +54,7 @@ module led_sb_ctrl(
|
|||||||
output logic [31:0] read_data_o,
|
output logic [31:0] read_data_o,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Часть интерфейса модуля, отвечающая за подключение к периферии
|
Part of the module interface responsible for connection to the peripheral
|
||||||
*/
|
*/
|
||||||
output logic [15:0] led_o
|
output logic [15:0] led_o
|
||||||
);
|
);
|
||||||
@@ -65,88 +65,88 @@ logic led_mode;
|
|||||||
endmodule
|
endmodule
|
||||||
```
|
```
|
||||||
|
|
||||||
Данный модуль должен подавать на выходной сигнал `led_o` данные с регистра `led_val`. Запись и чтение регистра `led_val` осуществляется по адресу `0x00`.
|
This module must drive the output signal `led_o` with the value from register `led_val`. Reading and writing register `led_val` is performed at address `0x00`.
|
||||||
|
|
||||||
Регистр `led_mode` отвечает за режим вывода данных на светодиоды. Когда этот регистр равен единице, светодиоды должны "моргать" выводимым значением. Под морганием подразумевается вывод значения из регистра `led_val` на выход `led_o` на одну секунду (загорится часть светодиодов, соответствующие которым биты шины `led_o` равны единице), после чего на одну секунду выход `led_o` необходимо подать нули. Запись и чтение регистра `led_mode` осуществляется по адресу `0x04`.
|
Register `led_mode` controls the LED output mode. When this register equals one, the LEDs must "blink" with the output value. Blinking means: drive the value from `led_val` onto `led_o` for one second (the LEDs whose corresponding bits in `led_o` are one will light up), then drive `led_o` to zero for one second. Reading and writing register `led_mode` is performed at address `0x04`.
|
||||||
|
|
||||||
Отсчет времени можно реализовать простейшим счетчиком, каждый такт увеличивающимся на 1 и сбрасывающимся по достижении определенного значения, чтобы продолжить считать с нуля. Зная тактовую частоту, нетрудно определить до скольки должен считать счетчик. При тактовой частоте в 10 МГц происходит 10 миллионов тактов в секунду. Это означает, что при такой тактовой частоте через секунду счетчик будет равен `10⁷-1` (счет идет с нуля). Тем не менее удобней будет считать не до `10⁷-1` (что было бы достаточно очевидным и тоже правильным решением), а до `2*10⁷-1`. В этом случае старший бит счетчика каждую секунду будет инвертировать свое значение, что может быть использовано при реализации логики "моргания".
|
Timekeeping can be implemented with a simple counter that increments by 1 each clock cycle and resets when it reaches a certain value to start counting again. Knowing the clock frequency, it is straightforward to determine the counter limit. At a clock frequency of 10 MHz, there are 10 million cycles per second. This means that at this frequency, after one second the counter will equal `10⁷-1` (counting from zero). However, it is more convenient to count not to `10⁷-1` (which would be an obvious and correct solution), but to `2*10⁷-1`. In this case, the MSB of the counter inverts its value every second, which can be used directly to implement the blinking logic.
|
||||||
|
|
||||||
Важно отметить, что счетчик должен работать только при `led_mode == 1`, в противном случае счетчик должен быть равен нулю.
|
It is important to note that the counter must operate only when `led_mode == 1`; otherwise, the counter must be held at zero.
|
||||||
|
|
||||||
Обратите внимание на то, что адрес `0x24` является адресом сброса. В случае **запроса на запись** по этому адресу значения `1`, вы должны сбросить регистры `led_val`, `led_mode` и все вспомогательные регистры, которые вы создали. Для реализации сброса вы можете как создать отдельный регистр `led_rst`, в который будет происходить запись, а сам сброс будет происходить по появлению единицы в этом регистре (в этом случае необходимо не забыть сбрасывать и этот регистр тоже), так и создать обычный провод, формирующий единицу в случае выполнения всех указанных условий (условий **запроса на запись**, адреса сброса и значения записываемых данных равному единице).
|
Note that address `0x24` is the reset address. Upon a **write request** of value `1` to this address, you must reset registers `led_val`, `led_mode`, and all auxiliary registers you created. To implement the reset, you may either create a dedicated register `led_rst` that is written to, with the reset occurring when this register becomes one (in which case you must also reset this register), or create a plain wire that goes high when all specified conditions are met (the conditions of the **write request**, the reset address, and the written data value equaling one).
|
||||||
|
|
||||||
Адресное пространство контроллера:
|
Controller address space:
|
||||||
|
|
||||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
|Address|Access Mode|Valid Values| Functional Description |
|
||||||
|-----|-------------|-------------------|-----------------------------------------------------------------------------------|
|
|-------|-----------|------------|--------------------------------------------------------------------------------|
|
||||||
|0x00 | RW | [0:65535] | Чтение и запись в регистр `led_val` отвечающий за вывод данных на светодиоды |
|
|0x00 | RW | [0:65535] | Read and write to register `led_val`, which controls the data output to the LEDs |
|
||||||
|0x04 | RW | [0:1] | Чтение и запись в регистр `led_mode`, отвечающий за режим "моргания" светодиодами |
|
|0x04 | RW | [0:1] | Read and write to register `led_mode`, which controls the LED blinking mode |
|
||||||
|0x24 | W | 1 | Запись сигнала сброса |
|
|0x24 | W | 1 | Write reset signal |
|
||||||
|
|
||||||
## Реализация схемы контроллера
|
## Controller Circuit Implementation
|
||||||
|
|
||||||
Для начала, добавим на структурную схему входы и выходы модуля:
|
First, add the module's inputs and outputs to the block diagram:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
В первую очередь, спецификация вводит понятия **запрос на чтение** и **запрос на запись**. Создадим вспомогательные провода, которые будут сигнализировать о том, что произошел **запрос на чтение** или **запрос на запись**:
|
The specification introduces the concepts of **read request** and **write request**. Let us create auxiliary wires that signal when a **read request** or **write request** has occurred:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Помимо прочего, спецификация описывает адресное пространство контроллера. Поэтому создадим вспомогательные сигналы, сигнализирующие о том, что текущий адрес соответствует одному из регистров контроллера:
|
Additionally, the specification defines the controller's address space. Let us create auxiliary signals that indicate whether the current address corresponds to one of the controller's registers:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Теперь, когда подготовительные работы выполнены, начнем с реализации сброса этого контроллера. Сброс может произойти в двух случаях: когда `rst_i == 1` либо же в случае **запроса на запись** единицы по адресу `0x24`. Создадим вспомогательный провод `rst`, который будет равен единице в случае, если произойдет любое из этих событий. Этот сигнал будет сбрасывать все созданные в данном модуле регистры.
|
With the preparatory work done, let us begin with the reset logic for this controller. A reset can occur in two cases: when `rst_i == 1`, or when a **write request** of value one is made to address `0x24`. Let us create an auxiliary wire `rst` that is high when either of these events occurs. This signal will reset all registers created inside this module.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Продолжим описание контроллера, создав первый из **архитектурных регистров** — `led_val`. Запись в этот регистр возможна только при запросе на запись по адресу `0x00`. Создадим вспомогательный сигнал `val_en`, который будет равен единице только в случае выполнения этих условий:
|
Continuing the controller description, let us create the first **architectural register** — `led_val`. Writing to this register is only permitted on a write request to address `0x00`. Let us create an auxiliary signal `val_en` that is high only when these conditions are met:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Теперь реализация регистра `lev_val` становится совершенно тривиальной задачей, ведь у нас есть:
|
Now implementing register `led_val` becomes a straightforward task, since we have:
|
||||||
|
|
||||||
- сигнал сброса регистра `rst`;
|
- the register reset signal `rst`;
|
||||||
- сигнал разрешения записи в регистр `val_en`;
|
- the register write-enable signal `val_en`;
|
||||||
- сигнал данных для записи в регистр `write_data_i`(из которого мы будем брать только младшие 16 бит данных).
|
- the write data signal `write_data_i` (from which we take only the lower 16 bits).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Аналогичным образом реализуем еще один **архитектурный регистр** `led_mode`:
|
Similarly, implement the second **architectural register** `led_mode`:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Два этих регистра должны управлять поведением выходного сигнала `led_o` следующим образом:
|
These two registers must control the behavior of the output signal `led_o` as follows:
|
||||||
|
|
||||||
1. В случае `led_mode == 0` на выходе `led_o` должно оказаться значение `led_val`;
|
1. When `led_mode == 0`, the output `led_o` must carry the value of `led_val`;
|
||||||
2. В случае `led_mode == 1` на выходе `led_o` должно циклически меняться значение c `led_val` на `16'd0` и обратно с периодом в одну секунду.
|
2. When `led_mode == 1`, the output `led_o` must cyclically alternate between `led_val` and `16'd0` with a period of one second.
|
||||||
|
|
||||||
Для реализации счета времени нам потребуется вспомогательный **неархитектурный регистр** `cntr`, который станет простейшим счетчиком со сбросом. Мы знаем, что тактовый сигнал нашей схемы будет работать с периодом в 10 МГц. Если каждый такт инкрементировать счетчик на единицу, то за одну секунду счетчик досчитает до 10 миллионов. Первой мыслью может показаться, что нам нужно, чтобы счетчик считал до 10 миллионов, дойдя до которых он бы сбрасывался в ноль, однако в этом случае у нас будут сложности при дальнейшей реализации. Будет куда удобней, если вместо этого счетчик будет считать до 20 миллионов (полного периода смены значения с `led_val` на `16'd0` и обратно). В этом случае, нам останется всего лишь добавить условие вывода значения на мультиплексор:
|
To implement timekeeping, we need an auxiliary **non-architectural register** `cntr`, which acts as a simple resettable counter. We know that our circuit's clock runs at 10 MHz. Incrementing the counter by one each cycle, after one second the counter will reach 10 million. The first instinct might be to count to 10 million and then reset to zero, but this creates complications for the subsequent implementation. It is much more convenient to count to 20 million instead (the full period of alternating between `led_val` and `16'd0`). In this case, we only need to add a multiplexer output condition:
|
||||||
|
|
||||||
- пока значение счетчика меньше 10 миллионов, на выходе `led_o` будет значение `led_val`
|
- while the counter value is less than 10 million, `led_o` outputs `led_val`
|
||||||
- в противном случае, на выходе `led_o` будет значение `16'd0`.
|
- otherwise, `led_o` outputs `16'd0`.
|
||||||
|
|
||||||
Таким образом, поведение счетчика описывается следующим образом:
|
The counter behavior is therefore described as follows:
|
||||||
|
|
||||||
- счетчик сбрасывается, в следующих случаях:
|
- the counter resets in the following cases:
|
||||||
- произошел сброс (`rst == 1`);
|
- a reset occurred (`rst == 1`);
|
||||||
- произошло отключение "моргания" светодиодов (`led_mode == 0`);
|
- LED blinking was disabled (`led_mode == 0`);
|
||||||
- счетчик досчитал до 20 миллионов (`cntr >= 32'd20_000_000`);
|
- the counter reached 20 million (`cntr >= 32'd20_000_000`);
|
||||||
- в остальных ситуациях, счетчик инкрементирует свое значение.
|
- in all other cases, the counter increments its value.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Последним этапом описания контроллера будет добавление логики управления выходным сигналом `read_data_o`.
|
The final step in describing the controller is adding the logic that controls the output signal `read_data_o`.
|
||||||
|
|
||||||
На управление этим сигналом наложены следующие требования:
|
The following requirements apply to this signal:
|
||||||
|
|
||||||
- изменения этого сигнала должны быть **синхронными** (значит перед выходным сигналом должен стоять регистр);
|
- changes to this signal must be **synchronous** (i.e., a register must precede the output signal);
|
||||||
- в случае **запроса на чтение** по поддерживаемому адресу, данный сигнал должен принять значение ассоциированного с этим адресом регистра (дополнив это значение нулями в старших разрядах).
|
- upon a **read request** to a supported address, this signal must take the value of the register associated with that address (zero-extended to the full output width);
|
||||||
- в случае отсутствия **запроса на чтение**, или запроса на чтение по неподдерживаемому адресу, регистр должен сохранить значение
|
- in the absence of a **read request**, or on a read request to an unsupported address, the register must retain its current value.
|
||||||
|
|
||||||
Чтобы регистр сохранял значение между **запросами на чтение** по поддерживаемому адресу, добавим ему сигнал enable, а на вход данных подадим выход с мультиплексора, выбирающего между доступными источниками данных для чтения.
|
To keep the register's value between **read requests** to supported addresses, we add an enable signal to it, and drive its data input from a multiplexer that selects among the available read data sources.
|
||||||
|
|
||||||
Таким образом, итоговая схема примет вид:
|
The final circuit is thus:
|
||||||
|
|
||||||

|

|
||||||
|
|||||||