mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 09:10:10 +00:00
Initial commit
This commit is contained in:
83
Other/Basic definitions.md
Normal file
83
Other/Basic definitions.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Список основных терминов (must know!)
|
||||
|
||||
Ниже приводится перечень основных терминов, понимание которых является обязательным, без чего нельзя заключить вывод о том, что акт передачи знаний студенту совершен! В противном случае, из непонимания какого-то термина следует непонимание тех разделов дисциплины, в которых на него опираются. Некоторые из них имеют критически высокий уровень значимости. К таковым, например, относятся *процессор*, *архитектура*, *система команд.* Непонимание выпускником технической специальности смысла этих слов сравнимо со врачом непонимающим, что такое иммунитет. Это неприемлемо!
|
||||
|
||||
Главное не заучить определения, а именно понимать смысл. Если не ошибаюсь, это сказал Эйнштейн: «если ты не можешь что-то объяснить школьнику, значит ты сам это не понимаешь». На экзамене, в беседе, мы будем проверять понимание нижеизложенного.
|
||||
|
||||
Отдельно подчеркну: нижеизложенное является необходимым, но недостаточным для успешной сдачи экзамена.
|
||||
|
||||
**Процессор** – это программно-управляемое устройство, как правило, выполненное на одной интегральной схеме, осуществляющее цифровую обработку информации и управление этим процессом.
|
||||
|
||||
**Микроконтроллер** – это устройство, конструктивно выполненное на базе одной интегральной схемы и содержащее в себе процессор, оперативное и постоянное запоминающие устройства, а также различные периферийные устройства (например: АЦП, ЦАП, контроллеры интерфейсов, таймеры, модули ШИМ и т.д.).
|
||||
|
||||
**Интегрированный процессор** – это специализированный процессор, функциональные возможности которого отражают специфику решаемых с его помощью задач.
|
||||
|
||||
**Процессор цифровой обработки сигналов** (ПЦОС, Digital Signal Processor, DSP) – это специализированный процессор, ориентированный на реализацию процедур, обеспечивающих преобразование аналоговых сигналов, представленных в цифровой форме.
|
||||
|
||||
**Инструкция** (Команда) – это отдельная операция процессора, определенная системой команд и, которая, содержит в себе закодированную информацию о том, какое действие необходимо совершить и, если это требуется, над какими данными.
|
||||
|
||||
**Программа** – это комбинация инструкций и данных, позволяющая аппаратному обеспечению вычислительной системы выполнять вычисления или функции управления.
|
||||
|
||||
**Слово** – это определяемая архитектурой величина, измеряемая в битах или байтах и равная разрядности регистров процессора и\или шины данных.
|
||||
|
||||
**Арифметико-логическое устройство** (АЛУ) – это устройство, предназначенное для выполнения арифметических и поразрядно-логических операций над многоразрядными словами.
|
||||
|
||||
**Критический путь** – это самый длинный путь прохождения сигнала в комбинационной схеме (характеризует максимальное время распространения сигнала в этой комбинационной схеме: от начала изменений значений на входах, до момента, когда все выходы достигнут установившихся значений).
|
||||
|
||||
**Архитектура** – абстрактная модель совокупности функциональных возможностей процессора.
|
||||
|
||||
**Микроархитектура** – это структурная организация процессора, описывающая, как именно расположены и соединены друг с другом его функциональные узлы (регистры, АЛУ, конечные автоматы, блоки памяти и другие блоки, необходимые для реализации архитектуры).
|
||||
|
||||
**Архитектура системы команд** (Instruction Set Architecture, ISA) – часть архитектуры, определяющая программируемую часть процессора, то есть средства вычислительной машины, которые видны и доступны программисту (система команд, поддерживаемые форматы данных, системы регистров, способы адресации, модели памяти и т.д.).
|
||||
|
||||
**Система команд** – это совокупность команд (инструкций), выполнение которых на аппаратном уровне поддерживает процессор.
|
||||
|
||||
**Устройство управления** – блок процессора, организующий последовательную выборку команд из памяти, их дешифрацию и формирование соответствующих управляющих сигналов для всех блоков процессора.
|
||||
|
||||
**Конвейер команд** (Вычислительный конвейер) – это способ временного распараллеливания исполняемых команд, при котором выполнение команд разделяется на несколько более простых операций (называемых ступенями), под каждую из которых выделен свой блок аппаратуры и организована передача данных между ними, благодаря чему можно одновременно выполнять несколько команд на разных стадиях конвейера.
|
||||
|
||||
**Конфликты конвейера** – это ситуации, которые препятствуют выполнению очередной команды из потока команд в предназначенном для нее такте, по причине нехватки ресурсов (структурный конфликт), зависимости от данных, получаемых в еще незавершенной команде (конфликт по данным) или из-за неопределенности – какую команду загружать после команды условного перехода, до того, как истинность условия стала известной (конфликт по управлению).
|
||||
|
||||
**Прерывание** – это автоматическое изменение хода выполнения программы (запуск подпрограммы обработчика прерывания), вызванное событием (программным или аппаратным) или совокупностью событий, возникших в некоторой части вычислительной системы.
|
||||
|
||||
**Вектор прерывания** – адрес начала подпрограммы обработчика прерывания, который загружается в счетчик команд (Program counter) при возникновении соответствующего прерывания.
|
||||
|
||||
**Исключения** – это нештатные ситуации, возникающие при ошибках в работе процессора, либо ошибках при работе с памятью.
|
||||
|
||||
**Стек** – способ организации памяти, при котором слово данных, записанное последним, при считывании будет доступно первым (Last In, First Out, LIFO).
|
||||
|
||||
**Ассоциативная память** – это способ организации памяти, при котором поиск требуемых данных происходит не по адресу местоположения в памяти, а по уникальным признакам (тегам), хранящимся вместе с соответствующими данными.
|
||||
|
||||
**Локальность по обращению** – это понятие, отражающее закономерность обращений программ к памяти и, с высокой вероятностью, проявляющееся в повторном использовании данных, к которым недавно уже обращались (временная локальность данных), и в использовании в ближайшем будущем данных, находящихся по соседним адресам (пространственная локальность программ и данных).
|
||||
|
||||
**Кэш-память** – память малого объема, работающая значительно быстрее основной памяти – на частоте ядра процессора, и, храня в себе одновременно лишь малую часть основной памяти, призвана повысить скорость доступа к данным за счет их временной и пространственной локальности.
|
||||
|
||||
**Виртуальная память** – это способ автоматического управления иерархической памятью, при котором для нескольких ее уровней организуется единое адресное пространство, благодаря чему можно создать для программиста видимость памяти большого объема, а перемещая данные между уровнями (согласно локальности по обращению) для большинства обращений к памяти обеспечивать скорость доступа, равную скорости более быстрых типов памяти.
|
||||
|
||||
**Транзакция** – операция на шине.
|
||||
|
||||
**Шина** – это группа сигнальных линий, предназначенных для выполнения определенной функции в программно-управляемом процессе передачи данных.
|
||||
|
||||
**Интерфейс** – совокупность механических, электрических и программных средств, с помощью которых компоненты системы объединяются для решения задачи обмена информации.
|
||||
|
||||
**Арбитр магистрали** – это устройство, контролирующее соблюдение правил предоставления общей шины одному из запросивших ее устройств, другими словами, арбитр выбирает какому устройству и на сколько время предоставить управление шиной для передачи информации, вместе с тем контролирует присутствие на общей шине строго не более одного ведущего устройства в любой момент времени.
|
||||
|
||||
**Совмещенное адресное пространство** – это способ построения систем ввода\вывода, при котором определенная область адресов памяти отводится для адресации регистров устройств ввода\вывода.
|
||||
|
||||
**Выделенное адресное пространство** – это способ построения систем ввода\вывода, при котором система памяти и система ввода\вывода имеют собственные, отдельные системы адресов, с изолированными, раздельными линиями адреса, в связи с чем, для управления вводом\выводом используются специальные инструкции.
|
||||
|
||||
**Принстонская архитектура** – это способ организации памяти, при котором для хранения программ и данных используется единая (общая) память с разделенным по времени доступом (по очереди) к командам, либо данным, по общей шине процессор-память.
|
||||
|
||||
**Гарвардская архитектура** – это способ организации памяти, при котором используют отдельную память для хранения программ, и отдельную память для данных, каждая из которых соединена с процессором собственной шиной.
|
||||
|
||||
**CISC** (Complex Instruction Set Computer) – это архитектура с полным набором команд, изначально ориентированная на уменьшении рутины при программировании, она характеризуется наличием большого (около тысяча и более) количества разнообразных простых и сложных команд и множеством различных способов адресации операндов, благодаря чему коды инструкций имеют переменную длину, а в качестве операндов могут использоваться ячейки основной памяти.
|
||||
|
||||
**RISC** (Reduced Instruction Set Computer) – это архитектура с сокращенным набором команд, которая ориентирована на простоту реализации, из-за чего поддерживает, в основном, не более сотни команд, кодируемых словами фиксированной длины, и использующей всего несколько способов адресации операндов, но выполнять операции можно только с данными из регистрового файла, в связи с чем необходимо применять специальные команды пересылки данных между основной памятью и процессором.
|
||||
|
||||
**VLIW** (Very Long Instruction Word) – это архитектура со сверхдлинным командным словом, характеризующаяся увеличенным количеством исполнительных устройств, а сверхдлинная команда, является, по сути, склейкой нескольких выполняющихся одновременно RISC-инструкций, каждая из которых управляет определенным исполнительным устройством, что предоставляет программисту все возможности параллельной обработки.
|
||||
|
||||
**Скалярный процессор** – это процессор, в каждый момент времени осуществляющий работу только над одной порцией данных.
|
||||
|
||||
**Суперскалярный процессор** – это процессор, который одновременно выполняет более чем одну скалярную команду.
|
||||
|
||||
**Суперскалярная архитектура** – это архитектура с увеличенным количеством исполнительных устройств, в которой параллельная обработка достигается за счет выборки сразу нескольких инструкций за раз, динамически распределяя между исполнительными устройствами с целью их максимальной загрузки.
|
149
Other/FAQ.md
Normal file
149
Other/FAQ.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Список типичных ошибок при работе с Vivado и Verilog
|
||||
|
||||
## Содержание
|
||||
|
||||
1. [Ошибки, связанные с САПР Vivado](#ошибки-связанные-с-сапр-vivado)
|
||||
1.1 [Не запускается симуляция: FATAL_ERROR: PrivateChannel: Error creating client socket](#не-запускается-симуляция-fatal_error-privatechannel-error-creating-client-socket)
|
||||
1.2 [Не запускается симуляция: boot::filesystem::remove: Процесс не может получить доступ к файлу, т.к. этот файл занят другим процессом](#не-запускается-симуляция-boot-filesystem-remove-процесс-не-может-получить-доступ-к-файлу)
|
||||
1.3 [Вылетает Vivado при попытке открыть схему](#вылетает-vivado-при-попытке-открыть-схему)
|
||||
1.4 [Не устанавливается Vivado: The following fatal error encountered while installing files: Unable to open archive](#не-устанавливается-vivado-unable-to-open-archive)
|
||||
|
||||
2. [Ошибки синтаксиса языка Verilog](#ошибки-синтаксиса-языка-verilog)
|
||||
2.1 [concurrent assignment to a non-net is not permitted](#concurrent-assignment-to-a-non-net-is-not-permitted)
|
||||
2.2 [procedural assignment to a non-register test is not permitted, left-hand side should be reg/integer/time/genvar](#procedural-assignment-to-a-non-register-test-is-not-permitted-left-hand-side-should-be-reg)
|
||||
2.3 ['имя сигнала' is not a type](#имя-сигнала-is-not-a-type)
|
||||
2.4 [cannot find port on this module](#cannot-find-port-on-this-module)
|
||||
|
||||
## Ошибки связанные с САПР Vivado
|
||||
|
||||
### Не запускается симуляция FATAL_ERROR PrivateChannel Error creating client socket
|
||||
|
||||
**Причина:** ошибка [связана с проблемами Win Sockets](https://support.xilinx.com/s/question/0D52E00006iI37SSAS/isim-124-m81d-fatal-error-privatechannel-error-creating-client-socket?language=en_US), из-за которых симуляция не может быть запущена на сетевых дисках.
|
||||
**Способ воспроизведения ошибки:** создать проект на сетевом диске.
|
||||
**Решение:** Скорее всего, вы создали проект на диске `H:/`. Создайте проект на локальном диске (например, на рабочем столе диске `C:/`)
|
||||
|
||||
---
|
||||
|
||||
### Не запускается симуляция boot filesystem remove Процесс не может получить доступ к файлу
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Скриншот ошибки:</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
**Причина:** вы запустили симуляцию с другим `top level`-модулем, не закрыв предыдущую симуляцию.
|
||||
Скорее всего, после создания тестбенча, вы слишком быстро запустили первую симуляцию. Из-за этого, Vivado не успел обновить иерархию модулей и сделать тестбенч `top-level`-модулем. На запущенной симуляции все сигналы находились в Z и X состояниях, после чего вы попробовали запустить ее снова. К моменту повторного запуска иерархия модулей обновилась, сменился `top-level`, что и привело к ошибке.
|
||||
**Способ воспроизведения ошибки:** запустить симуляцию, создать новый файл симуляции, сделать его `top-level`-модулем, запустить симуляцию.
|
||||
**Решение:** Закройте предыдущую симуляцию (правой кнопкой мыши по кнопки SIMULATION -> Close Simulation) затем запустите новую.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Иллюстрация закрытия симуляции:</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
### Вылетает Vivado при попытке открыть схему
|
||||
|
||||
**Причина:** кириллические символы (русские буквы) в пути рабочей папки Vivado. Скорее всего, причина в кириллице в имени пользователя (**НЕ В ПУТИ УСТАНОВКИ VIVADO**).
|
||||
**Способ воспроизведения ошибки:** (см. решение, только для воспроизведение необходимо сделать обратно, дать папке имя с кириллицей)
|
||||
**Решение:** Чтобы не создавать нового пользователя без кириллицы в имени, проще назначить Vivado новую рабочую папку.
|
||||
Для этого:
|
||||
|
||||
1. Создайте в корне диска `C:/` какую-нибудь папку (например Vivado_temp).
|
||||
2. Откройте свойства ярлыка Vivado (правой кнопкой мыши по ярлыку -> свойства)
|
||||
2.1 Если у вас нет ярлыка Vivado на рабочем столе, вместо этого вы запускаете его из меню пуск, кликните в меню пуск правой кнопкой мыши по значку Vivado -> открыть расположение файла. Если там будет ярлык выполните пункт 2, если там будет исполняемый файл — создайте ярлык для этого файла (правой кнопкой мыши по файлу -> создать ярлык) и выполните пункт 2.
|
||||
3. В поле "Рабочая папка", укажите путь до созданной вами директории (в примере пункта 1 этот путь будет: `C:/Vivado_temp`). Нажмите "ОК".
|
||||
|
||||
---
|
||||
|
||||
### Не устанавливается Vivado Unable to open archive
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Иллюстрация:</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
**Причина:** Скорее всего, проблема в том, что файлы установки (**НЕ ПУТЬ УСТАНОВКИ VIVADO**) расположены по пути с кириллическими символами (например, в какой-то личной папке "Загрузки").
|
||||
**Решение:** Переместите файлы установки в директорию, не содержащую кириллицу в пути.
|
||||
|
||||
---
|
||||
|
||||
## Ошибки синтаксиса языка Verilog
|
||||
|
||||
### concurrent assignment to a non-net is not permitted
|
||||
|
||||
Запрещено выполнять непрерывное присваивание (`assign`) к объектам, не являющимися цепями. Скорее всего, вы пытались выполнить `assign b = a;`, где `b` является регистром.
|
||||
|
||||
```Verilog
|
||||
module alu(input a, input b,
|
||||
input [3:0] alu_op,
|
||||
output reg flag,
|
||||
output reg result
|
||||
);
|
||||
|
||||
assign flag = alu_op[3] ? (a > b) : 1'b0; // ошибка
|
||||
endmodule
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### procedural assignment to a non-register test is not permitted left-hand side should be reg
|
||||
|
||||
Запрещено использовать процедурное присваивание (присваивание в блоке `always` или `initial`) объектам, не являющимися регистрами. Скорее всего, вы пытались выполнить `b = a;` или `b <= a;` блоке `always`/`initial`, где `b` является проводом.
|
||||
|
||||
```Verilog
|
||||
module adder(input a, input b, output c);
|
||||
always @(*) begin
|
||||
c = a ^ b; // ошибка, процедурное присваивание
|
||||
// к проводам запрещено
|
||||
end
|
||||
endmodule
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### имя сигнала is not a type
|
||||
|
||||
Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков `always` и `initial` можно выполнять только непрерывное присваивание (через `assign`).
|
||||
|
||||
```Verilog
|
||||
module adder(input a, input b, output c);
|
||||
c = a ^ b; // ошибка, для непрерывного присваивания
|
||||
// необходимо ключевое слово assign
|
||||
endmodule
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### cannot find port on this module
|
||||
|
||||
Имя порта, указанного при подключении модуля (после точки) не соответствует ни одному имени сигналов подключаемого модуля
|
||||
|
||||
Пример
|
||||
|
||||
```Verilog
|
||||
module adder(input a, input b, output c);
|
||||
assign c = a ^ b;
|
||||
endmodule
|
||||
|
||||
module testbench();
|
||||
reg A, B;
|
||||
wire C;
|
||||
adder DUT(
|
||||
.A(A), // <- здесь будет ошибка,
|
||||
// т.к. в модуле adder нет порта 'A'
|
||||
.b(B),
|
||||
.c(C)
|
||||
);
|
||||
endmodule
|
||||
```
|
45
Other/Students server.md
Normal file
45
Other/Students server.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Учебный сервер для студентов
|
||||
|
||||
Данный сервер поднят для выполнения студентами их [индивидуального задания](../Labs/04.%20Primitive%20programmable%20device#индивидуальные-задания), а так же для тех студентов, кому не хватило места в учебной аудитории. На сервере установлены: `Vivado`, `VSCode`, `gcc`, `git`. Поскольку сервер имеет ограниченные ресурсы, а студенты не имеют привычки закрывать за собой программы при завершении сессии, тут не установлен браузер. Имейте в виду, что если вы закрыли сессию, не закрыв Vivado и там остались несохраненные файлы, то вы рискуете потерять свои изменения.
|
||||
|
||||
## Порядок подключения к серверу
|
||||
|
||||
За каждым студентом закреплена учетная запись на сервере и выданы её логин/пароль.
|
||||
|
||||
Подключение осуществляется из миэтовской сети. Это значит, что для подключения нужно либо подключиться к общажной сети (которая является частью миэтовской), либо воспользоваться [миэтовским vpn](https://vpn.miet.ru/).
|
||||
|
||||
Для подключения, необходимо скачать и установить программу [`X2Go client`](http://code.x2go.org/releases/X2GoClient_latest_mswin32-setup.exe). Во время установки можно оставить все опции без изменений.
|
||||
|
||||
При первом запуске, появится окно настройки подключения (если окно не появилось, нажмите `Ctrl+N`). Вам необходимо заполнить поля:
|
||||
|
||||
- Хост (вводим `82.179.178.13`)
|
||||
- Пользователь (ввводим логин с листочка)
|
||||
- SSH порт (вводим `2222`)
|
||||
- Тип сессии (выбираем `XFCE`)
|
||||
|
||||
Опционально можно настроить `имя сессии` и её `значок`.
|
||||
|
||||
<details>
|
||||
<summary>Пример заполненных настроек</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
После создания сессии, она отобразится в правой части программы. Двойной клик по сессии создаст подключение, в процессе которого от вас потребуется ввести пароль от выданной вам учетной записи.
|
||||
|
||||
## Как работать на сервере
|
||||
|
||||
Запуск `Vivado` осуществляется двумя путями: через `Applications->Development->Vivado`, либо через запуск команды `vivado` в терминале.
|
||||
|
||||
Для копирования своего проекта на сервер можно воспользоваться несколькими путями: клонирование репозитория посредством git, использование утилиты scp, однако для простоты инструкции будет предложено воспользоваться программой с графическим интерфейсом `WinSCP`.
|
||||
|
||||
WinSCP — это программа для Windows с графическим интерфейсом, реализующая передачу файлов между компьютерами поверх инструмента scp (secure copy).
|
||||
|
||||
Руководство по установке и запуску схоже с установкой X2Go:
|
||||
|
||||
1. Необходимо [скачать](https://winscp.net/eng/downloads.php) и установить программу (при установке можно выбрать рекомендованные настройки, можно их кастомизировать под себя).
|
||||
2. При запуске вам предложат ввести данные для подключения. Заполняете поля аналогично тому, как вы делали для X2Go. Выпадающий список `File Protocol` можете оставить без изменений.
|
||||
3. В данной программе вы можете сохранить так же и пароль. Вообще говоря это не безопасно и так делать обычно не рекомендуется.
|
||||
4. Через `Advanced...->Advanced->Directories->Local Directory`, можно настроить папку на вашем компьютере с данными в которой вы сможете взаимодействовать через WinSCP.
|
||||
5. Интерфейс перемещения данных предельно интуитивен: файлы и папки можно перетаскивать, копировать и вставлять, скачивать и загружать, удалять, перемещать и переименовывать. Делайте как вам удобно. В процессе могут появляться подтверждающие всплывающие окна.
|
141
Other/Teachers.md
Normal file
141
Other/Teachers.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Преподаватели АПС 2022
|
||||
|
||||
## Распределение по группам
|
||||
|
||||
| Группа | Расписание лаб | Лектор | Преподаватель | Ассистент |
|
||||
|------------|------------------------------|---------------------------------------------|---------------------------------------------|-------------------------------------------|
|
||||
| **ИБ-31** |Ср. 09:00–12:10 — Числитель-II|[Силантьев](#силантьев-александр-михайлович) |[Солодовников](#солодовников-андрей-павлович)|[Демидов](#демидов-александр-александрович)|
|
||||
| **ИВТ-31** |Пн. 10:40-13:50 — Знаменатель |[Орлов](#орлов-александр-николаевич) |[Солодовников](#солодовников-андрей-павлович)|[Демичев](#демичев-сергей-сергеевич) |
|
||||
| **ИВТ-32** |Пн. 14:30-17:40 — Числитель |[Орлов](#орлов-александр-николаевич) |[Орлов](#орлов-александр-николаевич) | |
|
||||
| **ИВТ-33** |Вт. 14:30-17:40 — Числитель |[Орлов](#орлов-александр-николаевич) |[Хисамов](#хисамов-василь-тагирович) |[Замтарадзе](#замтарадзе-артём-раульевич) |
|
||||
| **ИКТ-31** |Чт. 14:30-17:40 — Числитель-I |[Силантьев](#силантьев-александр-михайлович) |[Хисамов](#хисамов-василь-тагирович) |[Замтарадзе](#замтарадзе-артём-раульевич) |
|
||||
| **ИКТ-32** |Чт. 14:30-17:40 — Числитель-II|[Силантьев](#силантьев-александр-михайлович) |[Хисамов](#хисамов-василь-тагирович) |[Замтарадзе](#замтарадзе-артём-раульевич) |
|
||||
| **ИКТ-33** |Пт. 16:10–19:20 — Числитель-I |[Силантьев](#силантьев-александр-михайлович) |[Солодовников](#солодовников-андрей-павлович)|[Демидов](#демидов-александр-александрович)|
|
||||
| **КТ-31** |Вт. 09:00–12:10 — Знаменатель |[Силантьев](#силантьев-александр-михайлович) |[Солодовников](#солодовников-андрей-павлович)|[Чусов](#чусов-сергей-андреевич) |
|
||||
| **ПИН-35** |Пн. 14:30-17:40 — Знаменатель |[Орлов](#орлов-александр-николаевич) |[Солодовников](#солодовников-андрей-павлович)|[Демичев](#демичев-сергей-сергеевич) |
|
||||
| **ПМ-31** |Вт. 12:50–16:00 — Знаменатель |[Орлов](#орлов-александр-николаевич) |[Солодовников](#солодовников-андрей-павлович)|[Чусов](#чусов-сергей-андреевич) |
|
||||
| **РТ-32** |Чт. 09:00–12:10 — Числитель |[Силантьев](#силантьев-александр-михайлович) |[Хисамов](#хисамов-василь-тагирович) |[Замтарадзе](#замтарадзе-артём-раульевич) |
|
||||
| **РТ-33** |Чт. 09:00–12:10 — Знаменатель |[Силантьев](#силантьев-александр-михайлович) |[Орлов](#орлов-александр-николаевич) | |
|
||||
|
||||
|
||||
## Преподаватели
|
||||
|
||||
|
||||
<!-- ### Барков Евгений Сергеевич
|
||||
|
||||

|
||||
|
||||
Магистр НИУ МИЭТ, инженер-электроник в НИИ ВСиСУ
|
||||
|
||||
***telegram***: [`@barkove`](http://t.me/barkove)
|
||||
|
||||
|
||||
--- -->
|
||||
|
||||
|
||||
### Орлов Александр Николаевич
|
||||
|
||||

|
||||
|
||||
Старший преподаватель, инженер-электроник в НИИ ВСиСУ
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
<!-- ### Рыжкова Дарья Васильевна
|
||||
|
||||

|
||||
|
||||
Магистр НИУ МИЭТ, инженер-электроник в НИИ ВСиСУ
|
||||
|
||||
***telegram***: [`@frarrr`](http://t.me/frarrr)
|
||||
|
||||
|
||||
--- -->
|
||||
### Силантьев Александр Михайлович
|
||||
|
||||

|
||||
|
||||
Старший преподаватель Института МПСУ, инженер-электроник в НИИ ВСиСУ, руководитель группы
|
||||
|
||||
***telegram***: [`@sam_sil`](http://t.me/sam_sil)
|
||||
|
||||
***Консультации***: пока не определено
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Солодовников Андрей Павлович
|
||||
|
||||

|
||||
|
||||
Аспирант НИУ МИЭТ, инженер-электроник в НИИ ВСиСУ
|
||||
|
||||
***telegram***: [`@HepoH`](http://t.me/HepoH)
|
||||
|
||||
***Консультации***:
|
||||
|
||||
| День | Неделя | Время | Аудитория |
|
||||
|------ |------------ |-----------|-----------|
|
||||
|Четверг|Знаменатель-II|18:20-19:50| 4328 |
|
||||
|Пятница|Числитель-II |18:20-19:50| 4338 |
|
||||
|
||||
---
|
||||
|
||||
### Хисамов Василь Тагирович
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
Старший преподаватель Института МПСУ, инженер-электроник в НИИ ВСиСУ
|
||||
|
||||
***telegram***: [`@PascalVT`](http://t.me/PascalVT)
|
||||
|
||||
***e-mail***: Xisamoffvasil[*собака*]mail.ru
|
||||
|
||||
***Консультации***: пока не определено
|
||||
|
||||
### Чусов Сергей Андреевич
|
||||
|
||||

|
||||
|
||||
Аспирант НИУ МИЭТ, инженер-электроник в НИИ ВСиСУ
|
||||
|
||||
***telegram***: [`@srg_chs`](http://t.me/srg_chs)
|
||||
|
||||
---
|
||||
## Ассистенты
|
||||
|
||||
### Замтарадзе Артём Раульевич
|
||||
|
||||

|
||||
|
||||
Магистрант ИВТ (IoT), инженер в НПК ТЦ,
|
||||
|
||||
***telegram***: [`@gad_dam`](http://t.me/gad_dam)
|
||||
|
||||
Почта: artyomzamtaradze[*собака*]yandex.ru
|
||||
|
||||
---
|
||||
|
||||
### Демидов Александр Александрович
|
||||
|
||||

|
||||
|
||||
Магистрант ИВТ
|
||||
|
||||
***telegram***: [`@AlexBee4`](http://t.me/AlexBee4)
|
||||
|
||||
---
|
||||
|
||||
### Демичев Сергей Сергеевич
|
||||
|
||||

|
||||
|
||||
Магистрант ИВТ
|
||||
|
||||
***telegram***: [`@darthajFox`](http://t.me/darthajFox)
|
||||
|
||||
---
|
82
Other/VSCode Verilog Simulation.md
Normal file
82
Other/VSCode Verilog Simulation.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Руководство по интеграции Icarus Verilog в VSCode
|
||||
|
||||
Данное руководство позволяет интегрировать бесплатный Verilog-симулятор с редактором VSCode. После выполнения всех этапов, будет возможно запускать симуляцию прямо из редактора, а затем просматривать временную диаграмму (в ограниченном режиме, об этом ниже).
|
||||
|
||||
Пример использования:
|
||||
|
||||

|
||||
|
||||
Для получения данного результата, необходимо выполнить следующие шаги:
|
||||
|
||||
## Установка ПО
|
||||
|
||||
1. Скачать и установить [Icarus Verilog](https://bleyer.org/icarus/) (при установке убедитесь, что стоят галочки `Install GTKWave (x64)`, `Add executable folder(s) to the user PATH`)
|
||||
2. Скачать, установить и запустить [Visual Studio Code](https://code.visualstudio.com/Download)
|
||||
3. После запуска VSCode, необходимо перейти на вкладку "Расширения" (можно открыть через `Ctrl+Shift+X`)
|
||||
4. Устанавливаем следующие расширения:
|
||||
1. `Verilog-HDL/SystemVerilog/Bluespec SystemVerilog support for VS Code`
|
||||
2. `Verilog Testbench Runner`
|
||||
3. `WaveTrace`
|
||||
|
||||
Расширение `Bluespec SystemVerilog support for VS Code` добавляет подсветку синтаксиса языка Verilog.
|
||||
Расширение `Verilog Testbench Runner` добавляет на панель Verilog-файла кнопку `▶`, позволяющую запустить симуляцию без вызова команд `Icarus Verilog` в терминале.
|
||||
Расширение `WaveTrace` позволяет просматривать временные диаграммы прямо в VSCode.
|
||||
|
||||
На этом все настройки завершены.
|
||||
|
||||
## Изменение Verilog-файлов
|
||||
|
||||
Для того, чтобы при компиляции тестбенча, подхватывались файлы описанных модулей, необходимо в самый верх тестбенча дописать директиву (см. пример использования, 1):
|
||||
|
||||
```Verilog
|
||||
`include "имя файла, содержащего тестируемый модуль"
|
||||
```
|
||||
|
||||
А внутрь модуля `testbench` необходимо добавить блок:
|
||||
|
||||
```Verilog
|
||||
initial begin
|
||||
$dumpfile("tb.vcd");
|
||||
$dumpvars(0, fulladder32_tb); // fulladder32_tb <- имя модуля тестбенча
|
||||
end
|
||||
```
|
||||
|
||||
(см. пример использования, 2)
|
||||
|
||||
---
|
||||
|
||||
Кроме того, необходимо убедиться, что в модуле тестбенча нет системных функций: `$stop` (проверьте через поиск, если есть — удалите). Если в процессе симуляции произойдет вызов этой системной функции, её не удастся продолжить (в отличие от Vivado).
|
||||
|
||||
---
|
||||
|
||||
После этого нажимаем на зеленую кнопку `▶` (пример использования, 3), в логе будут либо сообщения об ошибках компиляции, либо результатах симуляции (пример использования, 4).
|
||||
Если симуляция будет завершена успешно, в подпапке build появится файл с расширением `.vcd` (пример использования, 5). При открытии этого файла, появится вкладка расширения `WaveTrace` (вкладку можно расположить в соседней панели, перетянув ее).
|
||||
Чтобы увидеть временную диаграмму, необходимо добавить отображаемые сигналы (пример использования, 6). Ограничение бесплатной версии `WaveTrace` заключается в том, что можно отобразить изменения только восьми сигналов одновременно (если понадобятся еще сигналы, придется сперва удалить какие-то предыдущие).
|
||||
После всех этих действий вы сможете увидеть временную диаграмму (пример использования, 7).
|
||||
|
||||
## Как запустить симуляцию с предоставленными мне файлами?
|
||||
|
||||
Если вы пропустили, или не сделали какую-то из лаб, вам потребуется взять готовые модули из ветки [Я-не-смог](https://github.com/MPSU/APS/tree/%D0%AF-%D0%BD%D0%B5-%D1%81%D0%BC%D0%BE%D0%B3). Модули в этих ветках являются нетлистами (описанием модуля на языке Verilog, полученным [после этапа синтеза](../Vivado%20Basics/Implementation%20steps.md)).
|
||||
Для того, чтобы симулятор Icarus Verilog мог работать с этим файлом, необходимо предоставить ему библиотеку примитивов из которых был собран нетлист. Для этого, необходимо выполнить следующие шаги:
|
||||
|
||||
1. [Скачать](../../Я-не-смог/unisims.zip) библиотеку примитивов.
|
||||
2. Распаковать её в папку вашего проекта.
|
||||
3. Добавить еще одну директиву `ˋinclude` в тестбенч: `ˋinclude "glbl.v"`
|
||||
4. Добавить в настройки расширения `Verilog Testbench Runner` указание использовать библиотеку `unisims`. Для этого:
|
||||
1. Откройте `Файл->Настройки->Параметры` (`File->Preferences->Settings`).
|
||||
2. В поле поиска введите: `verilog.icarusCompileArguments`.
|
||||
3. В поле найденной опции введите `-y unisims/`.
|
||||
|
||||
### Что делать, если мне нужно отобразить больше, чем 8 сигналов?
|
||||
|
||||
В этом случае, необходимо воспользоваться внешней программой по отображению временных диаграмм: `GTK Wave`. Она должна была быть установлена вами на этапе установке `Icarus Verilog` (см. [Установка ПО](#установка-по)).
|
||||
|
||||
В теории, после завершения симуляции, расширение `Verilog Testbench Runner`
|
||||
должно предлагать запустить GTK Wave. Если этого не происходит, выполните команду в терминале VSCode:
|
||||
|
||||
```bash
|
||||
gtkwave build/tb.vcd
|
||||
```
|
||||
|
||||
где `tb.vcd` имя временной диаграммы, которое вы указали в блоке `initial` (см. [Изменение Verilog-файлов](#изменение-verilog-файлов)).
|
||||
Откроется окно GTK Wave. Внутри этого окна, слева, есть вкладка `SST`, где будет расположен модуль вашего тестбенча. Нажав на кнопку `+` слева от имени модуля вы увидите объект `DUT` (имя сущности тестируемого модуля). Если нажать по этому объекту `ПКМ -> Recurse Import -> Append`, вы добавите все внутренние сигналы этого модуля в область просмотра временной диаграммы.
|
187
Other/rv32i.md
Normal file
187
Other/rv32i.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# RV32I - Стандартный набор целочисленных инструкций RISC-V
|
||||
|
||||
Разделы статьи:
|
||||
|
||||
- [Краткая справка по RISC-V и RV32I](#краткая-справка-по-risc-v-и-rv32i)
|
||||
- [RV32I](#rv32i)
|
||||
- [Псевдоинструкции](#псевдоинструкции)
|
||||
- [Переведенные фрагменты спецификации RISC-V](#переведенные-фрагменты-спецификации-risc-v)
|
||||
|
||||
## Краткая справка по RISC-V и RV32I
|
||||
|
||||
RISC-V — открытая и свободная система набора команд (ISA) на основе концепции RISC. Чтобы понять архитектуру любого компьютера, нужно в первую очередь выучить его язык, понять, что он умеет делать. Слова в языке компьютера называются «инструкциями», или «командами», а словарный запас компьютера – «системой команд».
|
||||
|
||||
В архитектуре RISC-V имеется обязательный для реализации минимальный список команд – набор инструкций **I** (Integer). В этот набор входят различные логические и арифметические операции с целыми числами, работа с памятью, и команды управления. Этого достаточно для обеспечения поддержки компиляторов, ассемблеров, компоновщиков и операционных систем (с дополнительными привилегированными инструкциями). Плюс, таким образом обеспечивается удобный "скелет" ISA и программного инструментария, вокруг которого могут быть построены более специализированные ISA процессоров путем добавления дополнительных инструкций.
|
||||
|
||||
Строго говоря RISC-V - это семейство родственных ISA, из которых в настоящее время существует четыре базовые ISA. Каждый базовый целочисленный набор инструкций характеризуется `шириной целочисленных регистров` и соответствующим `размером адресного пространства`, а также `количеством целочисленных регистров`. Существует два основных базовых целочисленных варианта, `RV32I` и `RV64I`, которые, соответственно, обеспечивают 32- или 64-битное адресное пространство и соответствующие размеры регистров регистрового файла. На основе базового набора инструкций `RV32I` существует вариант подмножества `RV32E`, который был добавлен для поддержки небольших микроконтроллеров и имеет вдвое меньшее количество целочисленных регистров – 16, вместо 32. Разрабатывается вариант `RV128I` базового целочисленного набора инструкций, поддерживающий плоское 128-битное адресное пространство. Также, стоит подчеркнуть, что размеры регистров и адресного пространства, во всех перечисленных стандартных наборах инструкций, не влияют на размер инструкций – во всех случаях они кодируются 32-битными числами. То есть, и для `RV32I`, и для `RV64I` одна инструкция будет кодироваться 32 битами. Базовые целочисленные наборы команд используют представление знаковых целых чисел в дополнительном коде.
|
||||
|
||||
В рамках дисциплины АПС затрагивается только `RV32I`, то есть стандартный набор целочисленных инструкций, предусматривающий в процессоре регистровый файл из 32-х 32-битных регистров, и использующий 32-битное адресное пространство памяти.
|
||||
|
||||
Кроме обязательного подмножества целочисленных инструкций, RISC-V предусматривает несколько стандартных опциональных расширений. Вот некоторые из них:
|
||||
|
||||
- **M** — Целочисленное умножение и деление (Integer Multiplication and Division)
|
||||
- **A** — Атомарные операции (Atomic Instructions), инструкции для атомарного чтения-изменения-записи в память для межпроцессорной синхронизации
|
||||
- **F** — Стандартное расширение для арифметических операций с плавающей точкой одинарной точности (Single-Precision Floating-Point) добавляет регистры с плавающей точкой, инструкции вычислений с одинарной точностью, а также инструкции загрузки и сохранения в регистровый файл для чисел с плавающей точкой
|
||||
- **D** — Стандартное расширение с плавающей точкой двойной точности (Double-Precision Floating-Point) расширяет регистры с плавающей точкой до 64 бит и добавляет инструкции вычислений с двойной точностью, загрузку и сохранение
|
||||
- **C** — Набор сжатых инструкций (Compressed Instructions), позволяющий кодировать инструкции 16-битными словами, что позволяет уплотнить программный код (если одну и ту же программу можно писать 16-битными словами вместо 32-битных, значит её размер сократится в 2 раза). Разумеется у такого уплотнения есть своя цена, иначе инструкции просто кодировали бы 16-ю битами вместо 32. У сжатых инструкций меньший диапазон адресов и констант.
|
||||
- **Zicsr** — Инструкции для работы с контрольными и статусными регистрами (Control and Status Register (CSR) Instructions). Используется, например, при работе с прерываниями/исключениями и виртуальной памятью
|
||||
- **Zifencei** — Инструкции синхронизации потоков команд и данных (Instruction-Fetch Fence)
|
||||
|
||||
Поддерживаемые процессором команды отражаются в названии набора инструкций. Например, `RV64IMC` это архитектура RISC-V с 64-битными регистрами и 64-битным адресным пространством, поддерживающая кроме стандартных целочисленных операций умножение и деление **M**, и может выполнять сжатые инструкции **C**.
|
||||
|
||||
Одной из целей проекта RISC-V является его использование в качестве стабильного объекта для разработки программного обеспечения. Для этого ее разработчики определили комбинацию базового ISA (`RV32I` или `RV64I`) и некоторых стандартных расширений (**IMAFD + Zicsr + Zifencei**) как "general-purpose" ISA (набор инструкций общего назначения), а для комбинации расширений набора команд **IMAFDZicsrZifencei** стали использовать аббревиатуру **G**. То есть `RV32G` это тоже самое, что и `RV32IMAFDZicsrZifencei`.
|
||||
|
||||
> Чтобы устройство управления понимало когда оно имеет дело с набором сжатых команд **C**, то есть с 16-битными инструкциями, а когда с другими наборами команд, то есть с инструкциями длиной 32 бита, каждая 32-битная инструкция в младших битах имеет `11`. Если в двух младших битах что-то отличное от `11`, значит это 16-битная инструкция!
|
||||
|
||||
На рисунке ниже показана видимая пользователю структура для основного подмножества команд для целочисленных вычислений `RV32I`. Она содержит `регистровый файл`, состоящий из 31 регистра общего назначения **x1** – **x31**, каждый из которых может содержать целочисленное значение, и регистра **x0**, жестко привязанного к константе 0. В случае `RV32`, регистры **xN**, и вообще все регистры, имеют длину в 32 бита. Также есть `АЛУ`, выполняющее операции над данными в регистровом файле (концепция RISC - load&store), и `память` с побайтовой адресацией и шириной адреса 32 бита.
|
||||
|
||||
Также существует еще один дополнительный видимый пользователю регистр: счетчик команд – `pc` (program counter), который содержит адрес текущей инструкции. `pc` изменяется либо автоматически, указывая на следующую инструкцию, либо в результате использования инструкций управления (операции условного и безусловного переходов).
|
||||
|
||||

|
||||
|
||||
RISC-V является load&store архитектурой (все операции с числами выполняются над данными только в регистровом файле), поэтому глядя на рисунок выше можно легко заключить, что функционально все инструкции сводятся к трём типам:
|
||||
|
||||
- Операции на АЛУ над числами в регистровом файле
|
||||
- Операции обмена данными между регистровым файлом и памятью
|
||||
- Манипуляции с `pc` (другими словами – управление программой)
|
||||
|
||||
Как было сказано ранее, память имеет 32-битную шину адреса и имеет побайтовую адресацию. Это значит, что каждый из 2<sup>32</sup> байт памяти имеет свой уникальный адрес, по которому к нему можно обратиться, чтобы считать из него или записать в него новую информацию. Однако, инструкции кодируются 32-битными числами, а один байт это всего 8 бит, значит одна инструкция занимает сразу 4 адреса в памяти. Подразумевается, что из такой памяти можно читать одновременно из нескольких последовательных адресов, то есть устройство управления процессора сообщает памяти начальный адрес требуемой ячейки, и количество ячеек (одну, две или четыре), которые нужно прочитать или записать.
|
||||
|
||||
Одна ячейка называется `байт` - 8 бит. Две последовательные 8-битные ячейки называются `полуслово` - 16 бит. Четыре последовательные 8-битные ячейки называются `словом` - 32 бита. Например, если процессор собирается выполнить инструкцию, которая занимает четыре байта по адресам `0x00000007 – 0x00000004`, то он обращается к памяти, сообщая, что "нужны 4 байта начиная с адреса 0x00000004", взамен процессор получает 32-битное число – инструкцию, которая была слеплена из байт, хранящихся в памяти по адресам: 4, 5, 6 и 7, для данного примера. К памяти также можно обратиться за полусловом или за байтом. Предполагается реализация выровненного доступа к памяти, то есть адреса слов и полуслов должны быть кратны 4 и 2, соответственно.
|
||||
|
||||
Аппаратное обеспечение компьютера «понимает» только нули и единицы, поэтому инструкции закодированы двоичными числами в формате, который называется машинным языком.
|
||||
|
||||
Инструкция компьютера кодирует в себе операцию, которую нужно исполнить, и данные, которые ей для этого потребуются. Такими данными могут быть адреса операндов и результата, различные константы.
|
||||
|
||||
В архитектуре RISC-V каждая несжатая инструкция представлена 32-разрядным словом. Микропроцессоры – это цифровые системы, которые читают и выполняют команды машинного языка. Для людей чтение и разработка компьютерных программ на машинном языке представляются нудным и утомительным делом, поэтому мы предпочитаем представлять инструкции в символическом формате, который называется языком ассемблера. Ассемблер позволяет выполнить взаимооднозначный переход от машинного кода к тестовому и обратно.
|
||||
|
||||
## RV32I
|
||||
|
||||
В таблице ниже приводятся 40 команд стандартного набора целочисленных инструкций `RV32I`: мнемоники языка ассемблера, функции, описания, форматы кодирования и значения соответствующих полей при кодировании. В RISC-V предусмотрено несколько форматов кодирования инструкций (следующий рисунок, еще ниже), то есть договоренность какая информация в каком месте 32-битной инструкции хранится и как она представлена. У всех операций есть поле `opcode` (operation code - код операции), в котором закодировано "что нужно сделать". По полю `opcode` устройство управления понимает что требуется сделать процессору и каким именно способом закодирована инструкция (**R**, **I**, **S**, **B**, **U** или **J**). В 32-битных инструкциях два младших бита всегда равны `11`.
|
||||
|
||||
Почти все инструкции имеют поле `Func3`, и некоторые – поле `Func7`. Их названия определены их разрядностью: 3 и 7 бит, соответственно. В этих полях, если они есть у инструкции, закодировано уточнение операции. Например, код операции 0010011 указывает на то, что будет выполняться некоторая операция на АЛУ между значением из регистрового файла и константой. Поле `Func3` уточняет операцию, для данного примера, если оно будет равно 0x0, то АЛУ выполнит операцию сложения между значением из регистра и константой из инструкции. Если `Func3` равно 0x6, то логическое ИЛИ.
|
||||
|
||||

|
||||
|
||||
На рисунке ниже приводится фрагмент из [`оригинальной спецификации RISC-V`](https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf). Сверху приводятся 6 форматов кодирования инструкций: **R**, **I**, **S**, **B**, **U** и **J**, а ниже приводятся конкретные значения полей внутри инструкции. Под `rd` подразумевается 5-битный адрес регистра назначения, `rs1` и `rs2` - 5-битные адреса регистров источников, `imm` — константа, расположение и порядок битов которой указывается в квадратных скобках. Обратите внимание, что в разных форматах кодирования константы имеют различную разрядность, а их биты упакованы по-разному. Для знаковых операций константу предварительно знаково расширяют до 32 бит. Для беззнаковых расширяют нулями до 32 бит.
|
||||
|
||||
Обратите внимание на операции `slli`, `srli` и `srai`, это операции сдвига на константную величину. У этих инструкций немного измененный формат кодирования **I\***. Формат кодирования **I** предоставляет 12-битную константу. Сдвиг 32-битного числа более, чем на 31 не имеет смысла. Для кодирования числа 31 требуется всего 5 бит. Выходит, что из 12 бит константы используется только 5 бит для операции сдвига, а оставшиеся 7 бит – не используются. А, главное (какое совпадение!), эти 7 бит находятся ровно в том же месте, где у других инструкций находится поле `Func7`. Поэтому, чтобы у инструкций `slli`, `srli` и `srai` использующих формат **I** не пропадала эта часть поля, к ней относятся как к полю `Func7`.
|
||||
|
||||

|
||||
|
||||
Ниже, для наглядности, приводится пример кодирования пары инструкций из книги Харриса и Харриса "Цифровая схемотехника и архитектура компьютера" из ассемблерных инструкций в 16-ричные цифры.
|
||||
|
||||

|
||||
|
||||
Примечание: `s2`, `s3`, `s4`, `to`, `t1`, `t2` — это синонимы регистров `x18`,`x19`,`x20`,`x5`,`x6`,`x7` соответственно. Введены **соглашением о вызовах** (calling convention) для того, чтобы стандартизировать функциональное назначение регистров. Подробнее об этом будет в лабораторной работе по программированию.
|
||||
|
||||
## Псевдоинструкции
|
||||
|
||||
В архитектуре RISC-V размер команд и сложность аппаратного обеспечения минимизированы путем использования лишь небольшого количества команд. Тем не менее RISC-V определяет псевдокоманды, которые на самом деле не являются частью набора команд, но часто используются программистами и компиляторами. При преобразовании в машинный код псевдокоманды транслируются в одну или несколько команд RISC-V. Например, псевдокоманда безусловного перехода `j`, преобразуется в инструкцию безусловного перехода с возвратом `jal` с регистром `x0` в качестве регистра-назначения, то есть адрес возврата не сохраняется.
|
||||
|
||||

|
||||
|
||||
## Переведенные фрагменты спецификации RISC-V
|
||||
|
||||
Далее приводится переведенный фрагмент второй главы [`оригинальной спецификации RISC-V`](https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf).
|
||||
|
||||
### Основные типы команд
|
||||
|
||||
В основе ISA лежит четыре основных типа команд (R/I/S/U), которые изображены на рисунке ниже. Все они имеют фиксированную длину в 32 бита и должны быть выровнены в памяти по четырехбайтовой границе. Если адрес перехода (в случае безусловного перехода, либо успешного условного перехода) не выровнен, генерируется исключение о невыровненном адресе инструкции. Исключение не генерируется в случае невыполненного условного перехода.
|
||||
|
||||

|
||||
|
||||
Для упрощения декодирования, архитектура команд RISC-V сохраняет положение адресов регистров-источников (`rs1` и `rs2`) и регистра назначения (`rd`) между всеми типами инструкций.
|
||||
|
||||
За исключением 5-битных непосредственных операндов, используемых в командах CSR, все непосредственные операнды (`imm`) проходят знаковое расширение. Для уменьшения сложности оборудования, константа размещается в свободные (от полей `func3`/`func7`/`rs1`/`rd`) биты инструкции, начиная от левого края. В частности, благодаря этому ускоряется схема знакового расширения, поскольку знаковый бит всех непосредственных операндов всегда находится в 31-ом бите инструкции.
|
||||
|
||||
### Способы кодирования непосредственных операндов
|
||||
|
||||
Существует еще формата кодирования констант в инструкции (**B**/**J**-типа), представленные на рисунке ниже.
|
||||
|
||||
Единственное различие между форматами **S** и **B** заключается в том, что в формате **B**, 12-битная константа используется для кодирования кратных двум смещений адреса при ветвлении (примечание: кратность двум обеспечивается сдвигом числа на 1 влево). Вместо того, чтобы сдвигать непосредственный операнд относительно всех бит инструкции на 1 влево, средние биты (`imm[10:1]`) и знаковый бит остаются в прежних местах, а оставшийся младший бит константы формата **S** (`inst[7]`) кодирует `imm[11]` бит константы в формате **B**.
|
||||
|
||||
Аналогично, единственное различие между форматами **U** и **J** состоит в том, что в формате **U** 20-разрядная константа сдвигается влево на 12 бит, в то время как в формате **J** — на 1. Расположение бит в непосредственных значениях формата **U** и **J** выбирались таким образом, чтобы максимально увеличить перекрытие с другими форматами и между собой.
|
||||
|
||||

|
||||
|
||||
На рисунке ниже показаны непосредственные значения (константы), создаваемые каждым из основных форматов команд, также они помечены, чтобы показать, какой бит команды (`inst[y]`) какому биту непосредственного значения соответствует.
|
||||
|
||||

|
||||
|
||||
> Знаковое расширение — одна из самых важных операций над непосредственными значениями (особенно в `RV64I`). Поэтому в RISC-V знаковый бит всех непосредственных значений всегда содержится в 31-м бите инструкции. Это позволяет выполнять знаковое расширение параллельно с декодированием команды.
|
||||
>
|
||||
> Не смотря на то, что более сложные микроархитектурные реализации имеющие отдельные сумматоры для вычисления адресов условных и безусловных переходов, могут не получить выигрыш от одинакового расположения битов непосредственных значений во всех типах команд, прежде всего мы хотели снизить аппаратные затраты для простейших реализаций.
|
||||
>
|
||||
> Меняя местами биты в кодировке непосредственных значений инструкций **B** и **J**-типа вместо использования динамических мультиплексоров для умножения константы на 2, мы уменьшили разветвленность сигнала команды и затраты на мультиплексирование примерно в 2 раза. Скремблированное кодирование непосредственных значений добавит незначительную задержку при статической компиляции. Для динамической генерации инструкций есть небольшие дополнительные издержки, однако для наиболее частых коротких ветвлений вперед предусмотрено простое кодирование непосредственных значений.
|
||||
|
||||
### Команды для целочисленных вычислений
|
||||
|
||||
Большинство инструкций целочисленных вычислений работают с 32-битными значениями, хранящимся в регистровом файле. Такие команды либо кодируются как операции `константа-регистр`, используя формат **I**-типа, либо как операции `регистр-регистр`, используя формат **R**-типа. В обоих случаях результат сохраняется в регистр `rd` . Ни одна инструкция целочисленных вычислений не вызывает арифметических исключений.
|
||||
|
||||
> Мы стали добавлять поддержку специального набора команд для проверок на переполнение целочисленных арифметических операций в основной набор команд, поскольку многие проверки на переполнение могут быть достаточно дешево реализованы в RISC-V с использованием инструкций ветвления. Проверка на переполнение для беззнакового сложения требует только одной дополнительной команды перехода после сложения:
|
||||
>
|
||||
> ```asm
|
||||
> add t0, t1, t2
|
||||
> bltu t0, t1, overflow
|
||||
> ```
|
||||
>
|
||||
> Для знакового сложения, если известен знак одного операнда, проверка на переполнение требует только одного ветвления после сложения:
|
||||
>
|
||||
> ```asm
|
||||
> addi t0, t1, +imm;
|
||||
> blt t0, t1, overflow.
|
||||
> ```
|
||||
>
|
||||
> Этот метод в общем случае подходит при сложении с непосредственным операндом. В остальных случаях при знаковом сложении требуются три дополнительные команды после сложения, использующих утверждение, что сумма должна быть меньше, чем один из операндов, тогда и только тогда, когда другой операнд отрицателен.
|
||||
>
|
||||
> ```asm
|
||||
> add t0, t1, t2
|
||||
> slti t3, t2, 0
|
||||
> slt t4, t0, t1
|
||||
> bne t3, t4, overflow
|
||||
> ```
|
||||
>
|
||||
> В RV64 проверки 32-разрядных знаковых сложений могут быть дополнительно оптимизированы путем сравнения результатов выполнения команд ADD и ADDW для каждого из операндов.
|
||||
|
||||
### Команда типа константа-регистр
|
||||
|
||||

|
||||
|
||||
`ADDI` суммирует знакорасширенную 12-битную константу с регистром `rs1`. Арифметическое переполнение игнорируется, и результатом являются младшие 32 бита результата. Команда `ADDI rd, rs1, 0` используется для реализации ассемблерной псевдоинструкции `MV rd, rs1`.
|
||||
|
||||
`SLTI` (установить, если меньше чем константа) помещает значение 1 в регистр `rd`, если регистр `rs1` меньше, чем расширенное непосредственное значение, когда оба значения обрабатываются как знаковые числа, иначе в `rd` записывается 0. `SLTIU` аналогична, но сравнивает значения как беззнаковые числа (то есть непосредственное значение сначала расширяется до 32 бит, а затем обрабатывается как число без знака). Обратите внимание, что команда `SLTIU rd, rs1, 1` устанавливает `rd` в 1, если `rs1` равен нулю, в противном случае `rd` устанавливается в 0 (псевдоинструкция ассемблера `SEQZ rd, rs`).
|
||||
|
||||
Примечание: у студентов часто возникает вопрос: зачем вообще нужны инструкции вида `SLT`, если есть инструкции вида `BLT`? Например, они могут использоваться для вычисления сложных условий переходов. Один из примеров таких условий вы видели выше, в примере обработке результата сложения на переполнение. Кроме того, не смотря на ограниченность этих инструкций (все они проверяют только на **строго меньше**), мы можем добиться операции **строго больше** поменяв операнды местами, а если результат обоих операций даст `0` — значит операнды равны. Поскольку идея RISC архитектуры в том, чтобы переложить организацию всех этих ухищрений на компилятор, этих оказывается достаточно.
|
||||
|
||||
`ANDI`, `ORI`, `XORI` - это логические операции, которые выполняют побитовое И, ИЛИ и исключающее ИЛИ над регистром `rs1` и непосредственным 12-битным значением с знаковым расширением и помещают результат в `rd`. Обратите внимание, что команда `XORI rd, rs, -1` выполняет побитовую логическую инверсию значения регистра `rs1` (псевдоинструкция `NOT rd, rs`).
|
||||
|
||||

|
||||
|
||||
Сдвиги на константу кодируются как разновидность формата команд **I**-типа. Операнд, который должен быть сдвинут, находится в `rs1`, а величина сдвига кодируется в младших 5 битах поля непосредственного значения. Тип сдвига вправо определяется 30-ым битом. `SLLI` - логический сдвиг влево (нули задвигаются в младшие биты); `SRLI` - логический сдвиг вправо (нули задвигаются в старшие биты); `SRAI` - арифметический сдвиг вправо (исходный знаковый бит задвигается в старшие биты).
|
||||
|
||||

|
||||
|
||||
`LUI` (загрузка старшей части непосредственного значения) используется для получения 32-битных констант и использует формат **U**-типа. `LUI` помещает непосредственное значение **U**-типа в старшие 20 бит регистра назначения `rd`, заполняя младшие 12 бит нулями.
|
||||
`AUIPC` (прибавить старшую часть непосредственного значения к `pc`) используется для построения адресов относительно `pc`, и использует формат **U**-типа. `AUIPC` формирует 32-битное смещение из 20-битного непосредственного значения **U**-типа, заполняя младшие 12 битов нулями, прибавляет это смещение к значению `pc`, а затем размещает результат в регистре `rd`.
|
||||
|
||||
> Команда `AUIPC` поддерживает последовательности из двух команд для получения произвольных смещений `pc` как для передачи потока управления, так и для доступа к данным. Комбинация `AUIPC` и 12-битного непосредственного значения в `JALR` может передавать управление на любой 32-битный адрес `pc`, в то время как `AUIPC` сложенное с 12-битным непосредственным значением смещения в обычных командах загрузки или сохранения позволяет получить доступ к любому 32-битному адресу данных относительно `pc`.
|
||||
>Текущее значение `pc` можно получить, установив непосредственное значение **U**-типа в 0. Несмотря на то, что команда `JAL+4` также позволяет получить значение `pc`, она может вызывать остановки конвейера в более простых микроархитектурах или засорять структуры буфера предсказания переходов (BTB) в более сложных микроархитектурах.
|
||||
|
||||
### Команды типа регистр-регистр
|
||||
|
||||
В `RV32I` определено несколько арифметических операций **R**-типа. Все операции берут исходные операнды из регистров `rs1` и `rs2` и записывают результат в регистр `rd`. Полями `funct7` и `funct3` задается тип операции.
|
||||
|
||||

|
||||
|
||||
`ADD` и `SUB` выполняют сложение и вычитание соответственно. Переполнения игнорируются, и младшие 32 бита результатов записываются в место назначения. `SLT` и `SLTU` выполняют знаковое и беззнаковое сравнения соответственно, записывая 1 в `rd`, если `rs1 < rs2`, или 0 в противном случае. Обратите внимание, что команда `SLTU rd, x0, rs2` устанавливает `rd` в 1, если `rs2` не равно нулю, иначе устанавливает `rd` в ноль (псевдоинструкция ассемблера `SNEZ rd, rs`). `AND`, `OR` и `XOR` выполняют побитовые логические операции.
|
||||
|
||||
`SLL`, `SRL` и `SRA` выполняют соответственно логический сдвиг влево, логический сдвиг вправо и арифметический сдвиг вправо значения в регистре `rs1` на величину сдвига, содержащуюся в младших 5 битах регистра `rs2`.
|
||||
|
||||
### Команда NOP
|
||||
|
||||

|
||||
|
||||
Инструкция `NOP` не изменяет **архитектурное состояние** процессора, за исключением увеличения `pc` и опциональных счетчиков производительности. `NOP` кодируется как `ADDI x0, x0, 0`.
|
||||
|
||||
> Команды `NOP` могут быть использованы для выравнивания сегментов кода по микроархитектурно значимым границам адресов или для резервирования места для модификаций встраиваемого кода. Хотя существует множество возможных способов кодирования `NOP`, мы использовали каноническое кодирование `NOP`, чтобы обеспечить возможность микроархитектурной оптимизации, а также для более читаемого вывода при дизассемблировании.
|
7
Other/vector_abs/README.md
Normal file
7
Other/vector_abs/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Модуль приближенного вычисления длины вектора
|
||||
|
||||
Модуль `vector_abs` предназначен для вычисления приближенной длины вектора в евклидовом пространстве (выражения `sqrt(a^2+b^2)`). Для эффективного использования логических вентилей используется следующее приближение:
|
||||
|
||||
`sqrt(a^2+b^2) ≈ max + min/2`, где max и min — наибольшее и наименьшее из пары чисел соответственно [**Ричард Лайонс: Цифровая обработка сигналов, Глава 13.2, стр. 475**].
|
||||
|
||||
Для определения максимума/минимума используется модуль `max_min`, для вычисления деления пополам используется модуль `half_divider`.
|
8
Other/vector_abs/half_divider.v
Normal file
8
Other/vector_abs/half_divider.v
Normal file
@@ -0,0 +1,8 @@
|
||||
module half_divider(
|
||||
input [31:0] numerator,
|
||||
output[31:0] quotient
|
||||
);
|
||||
|
||||
assign quotient = numerator << 1'b1;
|
||||
|
||||
endmodule
|
19
Other/vector_abs/max_min.v
Normal file
19
Other/vector_abs/max_min.v
Normal file
@@ -0,0 +1,19 @@
|
||||
module max_min(
|
||||
input [31:0] a,
|
||||
input [31:0] b,
|
||||
output reg[31:0] max,
|
||||
output reg[ 3:0] min
|
||||
);
|
||||
|
||||
always @(*) begin
|
||||
if(a > b) begin
|
||||
max = a;
|
||||
min = b;
|
||||
end
|
||||
else begin
|
||||
max = b;
|
||||
min = b;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
57
Other/vector_abs/tb.v
Normal file
57
Other/vector_abs/tb.v
Normal file
@@ -0,0 +1,57 @@
|
||||
module tb();
|
||||
|
||||
reg [31:0] a;
|
||||
reg [31:0] b;
|
||||
wire [31:0] res;
|
||||
|
||||
vector_abs dut(
|
||||
.x(a),
|
||||
.y(b),
|
||||
.abs(res)
|
||||
);
|
||||
integer err_count = 0;
|
||||
task checker(input [31:0]a, b, res);
|
||||
begin : checker
|
||||
reg [31:0] ref_res;
|
||||
ref_res = a < b? a/2 + b : a + b/2;
|
||||
if (res !== ref_res) begin
|
||||
$display("Incorrect res at time %0t:", $time);
|
||||
$display("a = %0d, b = %0d", a, b);
|
||||
$display("design res = %0d", res);
|
||||
$display("reference res = %0d", ref_res);
|
||||
$display("------------------");
|
||||
err_count = err_count + 1'b1;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin : test
|
||||
integer i;
|
||||
$timeformat(-9,0,"ns");
|
||||
a = 0; b = 0;
|
||||
#5;
|
||||
checker(a,b,res);
|
||||
|
||||
|
||||
a = 1; b = 1;
|
||||
#5;
|
||||
checker(a,b,res);
|
||||
|
||||
a = 3; b = 4;
|
||||
#5;
|
||||
checker(a,b,res);
|
||||
|
||||
|
||||
for(i = 0; i < 100; i=i+1) begin
|
||||
a = $random()&32'hff; b = $random()&32'hff;
|
||||
#5;
|
||||
checker(a,b,res);
|
||||
end
|
||||
|
||||
$display("Test has been finished with %d errors", err_count);
|
||||
if(err_count == 0) begin
|
||||
$display("SUCCESS!");
|
||||
end
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
25
Other/vector_abs/vector_abs.v
Normal file
25
Other/vector_abs/vector_abs.v
Normal file
@@ -0,0 +1,25 @@
|
||||
module vector_abs(
|
||||
input [31:0] x,
|
||||
input [31:0] y,
|
||||
output[31:0] abs
|
||||
);
|
||||
|
||||
|
||||
wire [31:0] min;
|
||||
wire [31:0] min_half;
|
||||
|
||||
max_min max_min_unit(
|
||||
.a(x),
|
||||
.b(y),
|
||||
.max(max),
|
||||
.min(min)
|
||||
);
|
||||
|
||||
half_divider div_unit(
|
||||
.numerator(min),
|
||||
.quotient(min_half)
|
||||
);
|
||||
|
||||
assign abs = max + min_half;
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user