WIP: APS cumulative update (#98)

* WIP: APS cumulative update

* Update How FPGA works.md

* Перенос раздела "Последовательностная логика" в отдельный док

* Исправление картинки

* Исправление оформления индексов

* Переработка раздела Vivado Basics

* Добавление картинки в руководство по созданию проекта

* Исправление ссылок в анализе rtl

* Обновление изображения в sequential logic

* Исправление ссылок в bug hunting

* Исправление ссылок

* Рефактор руководства по прошивке ПЛИС

* Mass update

* Update fig_10

* Restore fig_02
This commit is contained in:
Andrei Solodovnikov
2024-09-02 10:20:08 +03:00
committed by GitHub
parent 78bb01ef95
commit a28002e681
195 changed files with 3640 additions and 2664 deletions

View File

@@ -1,4 +1,4 @@
# Лабораторная работа 15 "Программатор"
# Лабораторная работа 15 "Программатор"
Чтобы выпустить микроконтроллер в "дикую природу", то есть, чтобы его можно было использовать не в лабораторных условиях, а независимо от всего этого дополнительного оборудования, необходимо предусмотреть механизм замены исполняемой программы.
@@ -54,7 +54,7 @@
Опишем данный автомат в виде графа переходов:
![https://upload.wikimedia.org/wikipedia/commons/9/9e/Turnstile_state_machine_colored.svg](https://upload.wikimedia.org/wikipedia/commons/9/9e/Turnstile_state_machine_colored.svg)
![../../.pic/Labs/lab_15_programming_device/fig_01.svg](../../.pic/Labs/lab_15_programming_device/fig_01.svg)
_Рисунок 1. Граф переходов конечного автомата для турникета[[1]](https://en.wikipedia.org/wiki/Finite-state_machine)._
@@ -62,17 +62,17 @@ _Рисунок 1. Граф переходов конечного автомат
Как мы видим, повторное опускание жетона в разблокированном состоянии приводит к сохранению этого состояния (но турникет не запоминает, что было опущено 2 жетона, и после первого же прохода станет заблокирован). В случае попытки поворота треноги в заблокированном состоянии, автомат так и останется в заблокированном состоянии.
Так же необходимо оговорить приоритет переходов: в первую очередь проверяется попытка поворота треноги, в случае если такой попытки не было, проверяется опускание монетки. Такой приоритет можно было бы указать и на графе, показав на ребрах что переход в состояние unlocked возможен только при отсутствии сигнала `push`.
Так же необходимо оговорить приоритет переходов: в первую очередь проверяется попытка поворота треноги, в случае если такой попытки не было, проверяется опускание монетки. Такой приоритет можно было бы указать и на графе, показав на рёбрах что переход в состояние unlocked возможен только при отсутствии сигнала `push`.
### Реализация конечных автоматов в SystemVerilog
Глядя на описание составляющих конечного автомата, вы могли задаться вопросом: чем автомат отличается от последовательностной логики, ведь она состоит из тех же компонент. Ответом будет: ничем. Конечные автоматы являются математической абстракцией над функцией последовательностной логики[[3]](https://www.allaboutcircuits.com/textbook/digital/chpt-11/finite-state-machines/). Иными словами — конечный автомат, это просто другой способ представления последовательностной логики, а значит вы уже умеете их реализовывать.
Глядя на описание составляющих конечного автомата, вы могли задаться вопросом: чем автомат отличается от последовательностной логики, ведь она состоит из тех же компонент. Ответом будет: ничем. Конечные автоматы являются математической абстракцией над функцией последовательностной логики[[2]](https://www.allaboutcircuits.com/textbook/digital/chpt-11/finite-state-machines/). Иными словами — конечный автомат, это просто другой способ представления последовательностной логики, а значит вы уже умеете их реализовывать.
Для реализации регистра состояния конечного автомата будет удобно воспользоваться специальным типом языка **SystemVerilog**, который называется `enum` (**перечисление**).
Перечисления позволяют объявить объединенный набор именованных констант. В дальнейшем, объявленные имена можно использовать вместо перечисленных значений, им соответствующих, что повышает читаемость кода. Если не указано иного, первому имени присваивается значение `0`, каждое последующее увеличивается на `1` относительно предыдущего значения.
```SystemVerilog
```Verilog
module turnstile_fsm(
input logic clk,
input logic rst,
@@ -81,26 +81,27 @@ module turnstile_fsm(
output logic is_locked
)
enum logic {LOCKED=1, UNLOCKED=0} state;
enum logic {LOCKED=1, UNLOCKED=0} state;
assign is_locked = state == LOCKED;
assign is_locked = state == LOCKED;
always_ff @(posedge clk) begin
if(rst) begin
always_ff @(posedge clk) begin
if(rst) begin
state <= LOCKED;
end
else begin
if(push) begin
state <= LOCKED;
end
else if (coin) begin
state <= UNLOCKED;
end
else begin
if(push) begin
state <= LOCKED;
end
else if (coin) begin
state <= UNLOCKED;
end
else begin
state <= state;
end
state <= state;
end
end
end
endmodule
```
_Листинг 1. Пример реализации конечного автомата для турникета._
@@ -111,9 +112,9 @@ _Листинг 1. Пример реализации конечного авто
_Рисунок 2. Вывод значений объекта `enum` на временную диаграмму._
Для описания регистра состояния часто используют отдельный комбинационный сигнал, который подается непосредственно на его вход (часто именуемый как `next_state`). Приведенный выше автомат турникета слишком простой, чтобы показать преимущества такого подхода. Предположим, что в момент перехода из состояния `locked` в состояние `unlocked` мы хотим, чтобы загоралась и сразу гасла зеленая лампочка. Без сигнала `next_state` подобный модуль можно было бы описать как:
Для описания регистра состояния часто используют отдельный комбинационный сигнал, который подаётся непосредственно на его вход (часто именуемый как `next_state`). Приведённый выше автомат турникета слишком простой, чтобы показать преимущества такого подхода. Предположим, что в момент перехода из состояния `locked` в состояние `unlocked` мы хотим, чтобы загоралась и сразу гасла зелёная лампочка. Без сигнала `next_state` подобный модуль можно было бы описать как:
```SystemVerilog
```Verilog
module turnstile_fsm(
input logic clk,
input logic rst,
@@ -123,36 +124,37 @@ module turnstile_fsm(
output logic green_light
)
enum logic {LOCKED=1, UNLOCKED=0} state;
enum logic {LOCKED=1, UNLOCKED=0} state;
assign is_locked = ststate == LOCKED;
assign is_locked = ststate == LOCKED;
// (!push) && coin — условие перехода в состояние UNLOCKED
assign green_light = (state == LOCKED) && (!push) && coin;
// (!push) && coin — условие перехода в состояние UNLOCKED
assign green_light = (state == LOCKED) && (!push) && coin;
always_ff @(posedge clk) begin
if(rst) begin
always_ff @(posedge clk) begin
if(rst) begin
state <= LOCKED;
end
else begin
if(push) begin
state <= LOCKED;
end
else if (coin) begin
state <= UNLOCKED;
end
else begin
if(push) begin
state <= LOCKED;
end
else if (coin) begin
state <= UNLOCKED;
end
else begin
state <= state;
end
state <= state;
end
end
end
endmodule
```
_Листинг 2. Пример реализации конечного автомата для усложненного турникета._
_Листинг 2. Пример реализации конечного автомата для усложнённого турникета._
Используя сигнал `next_state`, автомат мог бы быть переписан следующим образом:
```SystemVerilog
```Verilog
module turnstile_fsm(
input logic clk,
input logic rst,
@@ -162,37 +164,38 @@ module turnstile_fsm(
output logic green_light
)
enum logic {LOCKED=1, UNLOCKED=0} state, next_state;
enum logic {LOCKED=1, UNLOCKED=0} state, next_state;
assign is_locked = state;
assign is_locked = state;
assign green_light = (state == LOCKED) && (next_state == UNLOCKED);
assign green_light = (state == LOCKED) && (next_state == UNLOCKED);
always_ff @(posedge clk) begin
if(rst) begin
state <= LOCKED;
end
else begin
state <= next_state
end
always_ff @(posedge clk) begin
if(rst) begin
state <= LOCKED;
end
always_comb begin
if(push) begin
next_state = LOCKED;
end
else if (coin) begin
next_state = UNLOCKED;
end
else begin
next_state = state;
end
else begin
state <= next_state
end
end
always_comb begin
if(push) begin
next_state = LOCKED;
end
else if (coin) begin
next_state = UNLOCKED;
end
else begin
next_state = state;
end
end
endmodule
```
_Листинг 3. Пример реализации конечного автомата для усложненного турникета с использованием сигнала next\_state._
_Листинг 3. Пример реализации конечного автомата для усложнённого турникета с использованием сигнала next\_state._
На первый взгляд может показаться, что так даже сложнее. Во-первых, появился дополнительный сигнал. Во-вторых, появился еще один `always`-блок. Однако представьте на секунду, что условиями перехода будут не однобитные входные сигналы, а какие-нибудь более сложные условия. И что от них будет зависеть не один выходной сигнал, а множество как выходных сигналов, так и внутренних элементов памяти помимо регистра состояний. В этом случае, сигнал `next_state` позволит избежать дублирования множества условий.
На первый взгляд может показаться, что так даже сложнее. Во-первых, появился дополнительный сигнал. Во-вторых, появился ещё один `always`-блок. Однако представьте на секунду, что условиями перехода будут не однобитные входные сигналы, а какие-нибудь более сложные условия. И что от них будет зависеть не один выходной сигнал, а множество как выходных сигналов, так и внутренних элементов памяти помимо регистра состояний. В этом случае, сигнал `next_state` позволит избежать дублирования множества условий.
Важно отметить, что объектам типа `enum` можно присваивать только перечисленные константы и объекты того же типа. Иными словами, `state` можно присваивать значения `LOCKED`/`UNLOCKED` и `next_state`, но нельзя, к примеру, присвоить `1'b0`.
@@ -206,9 +209,9 @@ _Листинг 3. Пример реализации конечного авто
### Перезаписываемая память инструкций
Поскольку ранее из памяти инструкций можно было только считывать данные, но не записывать их в нее, программатор не сможет записать принятую из внешнего мира программу. Поэтому необходимо добавить в память инструкций порт на запись. Для того, чтобы различать реализации памяти инструкций, данный модуль будет называться `rw_instr_mem`:
Поскольку ранее из памяти инструкций можно было только считывать данные, но не записывать их в неё, программатор не сможет записать принятую из внешнего мира программу. Поэтому необходимо добавить в память инструкций порт на запись. Для того, чтобы различать реализации памяти инструкций, данный модуль будет называться `rw_instr_mem`:
```SystemVerilog
```Verilog
module rw_instr_mem
import memory_pkg::INSTR_MEM_SIZE_BYTES;
import memory_pkg::INSTR_MEM_SIZE_WORDS;
@@ -269,7 +272,7 @@ _Рисунок 3. Граф перехода между состояниями
Ниже представлен прототип модуля с частично реализованной логикой:
```SystemVerilog
```Verilog
module bluster
(
input logic clk_i,
@@ -393,7 +396,6 @@ uart_tx tx(
.tx_valid_i (tx_valid )
);
endmodule
```
@@ -441,21 +443,21 @@ _Листинг 5. Готовая часть программатора._
Для работы логики переходов, необходимо реализовать счетчики `size_counter`, `flash_counter`, `msg_counter`.
`size_counter` должен сбрасываться в значение `4`, а также принимать это значение во всех состояниях кроме: `RCV_SIZE`, `RCV_NEXT_COMMAND`. В данных двух состояниях счетчик должен декрементироваться в случае, если `rx_valid` равен единице.
`size_counter` должен сбрасываться в значение `4`, а также принимать это значение во всех состояниях кроме: `RCV_SIZE`, `RCV_NEXT_COMMAND`. В данных двух состояниях счётчик должен декрементироваться в случае, если `rx_valid` равен единице.
`flash_counter` должен сбрасываться в значение `flash_size`, а также принимать это значение во всех состояниях кроме `FLASH`. В этом состоянии счетчик должен декрементироваться в случае, если `rx_valid` равен единице.
`flash_counter` должен сбрасываться в значение `flash_size`, а также принимать это значение во всех состояниях кроме `FLASH`. В этом состоянии счётчик должен декрементироваться в случае, если `rx_valid` равен единице.
`msg_counter` должен сбрасываться в значение `INIT_MSG_SIZE-1`_Листинге 5_ объявлены параметры `INIT_MSG_SIZE`, `FLASH_MSG_SIZE` и `ACK_MSG_SIZE`).
Счетчик должен инициализироваться следующим образом:
счётчик должен инициализироваться следующим образом:
- в состоянии `FLASH` счетчик должен принимать значение `FLASH_MSG_SIZE-1`,
- в состоянии `RCV_SIZE` счетчик должен принимать значение `ACK_MSG_SIZE-1`,
- в состоянии `RCV_NEXT_COMMAND` счетчик должен принимать значение `INIT_MSG_SIZE-1`.
- в состоянии `FLASH` счётчик должен принимать значение `FLASH_MSG_SIZE-1`,
- в состоянии `RCV_SIZE` счётчик должен принимать значение `ACK_MSG_SIZE-1`,
- в состоянии `RCV_NEXT_COMMAND` счётчик должен принимать значение `INIT_MSG_SIZE-1`.
В состояниях: `INIT_MSG`, `SIZE_ACK`, `FLASH_ACK` счетчик должен декрементироваться в случае, если `tx_valid` равен единице.
В состояниях: `INIT_MSG`, `SIZE_ACK`, `FLASH_ACK` счётчик должен декрементироваться в случае, если `tx_valid` равен единице.
Во всех остальных ситуациях счетчик должен сохранять свое значение.
Во всех остальных ситуациях счётчик должен сохранять свое значение.
##### Реализация сигналов, подключаемых к uart_tx
@@ -469,11 +471,11 @@ _Листинг 5. Готовая часть программатора._
Сигнал `tx_data` должен нести очередной байт одного из передаваемых сообщений:
- в состоянии `INIT_MSG` передается очередной байт сообщения `init_msg`
- в состоянии `SIZE_ACK` передается очередной байт сообщения `flash_size`
- в состоянии `FLASH_ACK` передается очередной байт сообщения `flash_msg`.
- в состоянии `INIT_MSG` передаётся очередной байт сообщения `init_msg`
- в состоянии `SIZE_ACK` передаётся очередной байт сообщения `flash_size`
- в состоянии `FLASH_ACK` передаётся очередной байт сообщения `flash_msg`.
В остальных состояниях он равен нулю. Для отсчета байт используется счетчик `msg_counter`.
В остальных состояниях он равен нулю. Для отсчёта байт используется счётчик `msg_counter`.
##### Реализация интерфейсов памяти инструкций и данных
@@ -531,7 +533,7 @@ _Рисунок 4. Интеграция программатора в `riscv_uni
Необходимо подключить отладочный стенд к последовательному порту компьютера (в случае платы Nexys A7 — достаточно просто подключить плату usb-кабелем, как это делалось на протяжении всех лабораторных для прошивки). Необходимо будет узнать COM-порт, по которому отладочный стенд подключен к компьютеру. Определить нужный COM-порт на операционной системе Windows можно через "Диспетчер устройств", который можно открыть через меню пуск. В данном окне необходимо найти вкладку "Порты (COM и LPT)", раскрыть ее, а затем подключить отладочный стенд через USB-порт (если тот еще не был подключен). В списке появится новое устройство, а в скобках будет указан нужный COM-порт.
Подключив отладочный стенд к последовательному порту компьютера и сконфигурировав ПЛИС вашим проектом остается проинициализировать память. Сделать это можно с помощью предоставленного скрипта, пример запуска которого приведен в листинге 6.
Подключив отладочный стенд к последовательному порту компьютера и сконфигурировав ПЛИС вашим проектом, остается проинициализировать память. Сделать это можно с помощью предоставленного скрипта, пример запуска которого приведен в листинге 6.
```bash
# Пример использования скрипта. Сперва указываются опциональные аргументы
@@ -563,35 +565,28 @@ _Листинг 6. Пример использования скрипта для
## Порядок выполнения задания
1. Опишите модуль `rw_instr_mem`, используя код, представленный в _листинге 4_.
2. Добавьте пакет [`bluster_pkg`](bluster_pkg.sv), содержащий объявления параметров, используемых модулем и вспомогательных вызовов, используемых тестбенчем.
2. Добавьте пакет [`bluster_pkg`](bluster_pkg.sv), содержащий объявления параметров и вспомогательных вызовов, используемых модулем и тестбенчем.
3. Опишите модуль `bluster`, используя код, представленный в _листинге 5_. Завершите описание этого модуля.
1. Опишите конечный автомат используя сигналы `state`, `next_state`, `send_fin`, `size_fin`, `flash_fin`, `next_round`.
2. [Реализуйте](#реализация-конечного-автомата) логику счетчиков `size_counter`, `flash_counter`, `msg_counter`.
3. [Реализуйте](#реализация-сигналов-подключаемых-к-uart_tx) логику сигналов `tx_valid`, `tx_data`.
4. [Реализуйте](#реализация-интерфейсов-памяти-инструкций-и-данных) интерфейсы памяти инструкций и данных.
5. [Реализуйте](#реализация-оставшейся-части-логики) логику оставшихся сигналов.
4. После описания модуля, его необходимо проверить с помощью тестового окружения.
1. Тестбенч находится [здесь](lab_15_tb_bluster.sv).
2. Для работы тестбенча потребуется потребуется пакет [`peripheral_pkg`](../13.%20Peripheral%20units/peripheral_pkg.sv) из ЛР№13, а также файлы [`lab_15_char.mem`](lab_15_char.mem), [`lab_15_data.mem`](lab_15_data.mem), [`lab_15_instr.mem`](lab_15_instr.mem) из папки [mem_files](mem_files).
3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (`lab_15_tb_bluster`).
4. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
5. **По завершению симуляции убедитесь, что в логе есть сообщение о завершении теста!**
5. Интегрируйте программатор в модуль `riscv_unit`.
1. Замените память инструкцией модулем `rw_instr_mem`.
2. Добавьте модуль программатор.
3. Подключите программатор к процессорной системе.
4. Проверьте модуль с помощью верификационного окружения, представленного в файле [`lab_15.tb_bluster.sv`](lab_15.tb_bluster.sv). В случае, если в TCL-консоли появились сообщения об ошибках, вам необходимо [найти](../../Vivado%20Basics/05.%20Bug%20hunting.md) и исправить их.
1. Перед запуском моделирования, убедитесь, что у вас выбран корректный модуль верхнего уровня в `Simulation Sources`.
2. Для работы тестбенча потребуется пакет [`peripheral_pkg`](../13.%20Peripheral%20units/peripheral_pkg.sv) из ЛР№13, а также файлы [`lab_15_char.mem`](lab_15_char.mem), [`lab_15_data.mem`](lab_15_data.mem), [`lab_15_instr.mem`](lab_15_instr.mem) из папки [mem_files](mem_files).
5. Интегрируйте программатор в модуль `processor_system`.
1. В модуле `processor_system` замените память инструкцией модулем `rw_instr_mem`.
2. Добавьте в модуль `processor_system` экземпляр модуля-программатора.
1. Интерфейс памяти инструкций подключается к порту записи модуля `rw_instr_mem`.
2. Интерфейс памяти данных мультиплексируется с интерфейсом памяти данных модуля `LSU`.
3. Замените сигнал сброса модуля `riscv_core` сигналом `core_reset_o`.
4. В случае если у вас есть периферийное устройство `uart_tx` его выход `tx_o` необходимо мультиплексировать с выходом `tx_o` программатора аналогично тому, как был мультиплексирован интерфейс памяти данных.
6. После интеграции модуля, его необходимо проверить с помощью тестового окружения.
1. Тестовое окружение находится [здесь](lab_15_tb_system.sv).
1. Данный тестбенч необходимо обновить под свой вариант. Найдите строки со вспомогательным вызовом `program_region`, первыми аргументами которого являются "YOUR_INSTR_MEM_FILE" и "YOUR_DATA_MEM_FILE". Обновите эти строки под имена файлов, которыми вы инициализировали свои память инструкций и данных в ЛР№13. Если память данных вы не инициализировали, можете удалить/закомментировать соответствующий вызов. При необходимости вы можете добавить столько вызовов, сколько вам потребуется.
2. В .mem-файлах, которыми вы будете инициализировать вашу память необходимо сделать доработку. Вам необходимо указать адрес ячейки памяти, с которой необходимо начать инициализировать память. Это делается путем добавления в начало файла строки вида: `@hex_address`. Пример `@FA000000`. Строка обязательно должна начинаться с символа `@`, а адрес обязательно должен быть в шестнадцатеричном виде. Для памяти инструкций нужен нулевой адрес, а значит можно использовать строку `@00000000`. Для памяти данных необходимо адрес, превышающий размер памяти инструкций, но не попадающий в адресное пространство других периферийных устройств (старший байт адреса должен быть равен нулю). Поскольку система использует байтовую адресацию, адрес ячеек будет в 4 раза меньше адреса по которому обратился бы процессор. Это значит, что если бы вы хотели проинициализировать память VGA-контроллера, вам нужно было бы использовать не адрес `@07000000`, а `@01C00000` (`01C00000 * 4 = 07000000`). Таким образом, для памяти данных оптимальным адресом инициализации будет `@00200000`, поскольку эта ячейка с адресом `00200000` соответствует адресу `00800000` — этот адрес не накладывается на адресное пространство других периферийных устройств, но при этом заведомо больше возможного размера памяти инструкций. Примеры использования начальных адресов вы можете посмотреть в файлах [`lab_15_char.mem`](lab_15_char.mem), [`lab_15_data.mem`](lab_15_data.mem), [`lab_15_instr.mem`](lab_15_instr.mem) из папки [mem_files](mem_files).
3. Тестбенч будет ожидать завершения инициализации памяти, после чего сформирует те же тестовые воздействия, что и в тестбенче к ЛР№13. А значит, если вы использовали для инициализации те же самые файлы, поведение вашей системы после инициализации не должно отличаться от поведения на симуляции в ЛР№13.
2. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (`lab_15_tb_system`).
3. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
4. **По завершению симуляции убедитесь, что в логе есть сообщение о завершении теста!**
6. Проверьте процессорную систему после интеграции программатора с помощью верификационного окружения, представленного в файле [`lab_15.tb_processor_system.sv`](lab_15.tb_processor_system.sv).
1. Данный тестбенч необходимо обновить под свой вариант. Найдите строки со вспомогательным вызовом `program_region`, первыми аргументами которого являются "YOUR_INSTR_MEM_FILE" и "YOUR_DATA_MEM_FILE". Обновите эти строки под имена файлов, которыми вы инициализировали свои память инструкций и данных в ЛР№13. Если память данных вы не инициализировали, можете удалить/закомментировать соответствующий вызов. При необходимости вы можете добавить столько вызовов, сколько вам потребуется.
2. В .mem-файлах, которыми вы будете инициализировать вашу память необходимо сделать доработку. Вам необходимо указать адрес ячейки памяти, с которой необходимо начать инициализировать память. Это делается путем добавления в начало файла строки вида: `@hex_address`. Пример `@FA000000`. Строка обязательно должна начинаться с символа `@`, а адрес обязательно должен быть в шестнадцатеричном виде. Для памяти инструкций нужен нулевой адрес, а значит можно использовать строку `@00000000`. Для памяти данных необходимо адрес, превышающий размер памяти инструкций, но не попадающий в адресное пространство других периферийных устройств (старший байт адреса должен быть равен нулю). Поскольку система использует байтовую адресацию, адрес ячеек будет в 4 раза меньше адреса по которому обратился бы процессор. Это значит, что если бы вы хотели проинициализировать память VGA-контроллера, вам нужно было бы использовать не адрес `@07000000`, а `@01C00000` (`01C00000 * 4 = 07000000`). Таким образом, для памяти данных оптимальным адресом инициализации будет `@00200000`, поскольку эта ячейка с адресом `00200000` соответствует адресу `00800000` — этот адрес не накладывается на адресное пространство других периферийных устройств, но при этом заведомо больше возможного размера памяти инструкций. Примеры использования начальных адресов вы можете посмотреть в файлах [`lab_15_char.mem`](lab_15_char.mem), [`lab_15_data.mem`](lab_15_data.mem), [`lab_15_instr.mem`](lab_15_instr.mem) из папки [mem_files](mem_files).
3. Тестбенч будет ожидать завершения инициализации памяти, после чего сформирует те же тестовые воздействия, что и в тестбенче к ЛР№13. А значит, если вы использовали для инициализации те же самые файлы, поведение вашей системы после инициализации не должно отличаться от поведения на симуляции в ЛР№13.
4. Перед запуском моделирования, убедитесь, что у вас выбран корректный модуль верхнего уровня в `Simulation Sources`.
7. Переходить к следующему пункту можно только после того, как вы полностью убедились в работоспособности системы на этапе моделирования (увидели, что в память инструкций и данных были записаны корректные данные, после чего процессор стал обрабатывать прерывания от устройства ввода). Генерация битстрима будет занимать у вас долгое время, а итогом вы получите результат: заработало / не заработало, без какой-либо дополнительной информации, поэтому без прочного фундамента на моделировании далеко уехать у вас не выйдет.
8. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
9. Проверьте работу вашей процессорной системы на отладочном стенде с ПЛИС.
@@ -603,3 +598,5 @@ _Листинг 6. Пример использования скрипта для
## Список источников
1. [Finite-state machine](https://en.wikipedia.org/wiki/Finite-state_machine).
2. [All about circuits — Finite State Machines](https://www.allaboutcircuits.com/textbook/digital/chpt-11/finite-state-machines/)
3.