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

@@ -0,0 +1,44 @@
# Создание нового проекта в Vivado
Для того, чтобы создать новый проект в Vivado для отладочного стенда Nexys A7, следуйте следующему порядку выполнения действий.
1. Запустите Vivado.
2. Нажмите `Create Project`.
3. В открывшемся окне нажмите `Next`.
4. Введите название проекта (никаких пробелов и кириллических символов) → Выберите папку для проектов → Установите селектор `Create project subdirectory` → Нажмите `Next`.
5. Выберите RTL Project → Установите селектор `Do not specify sources at this time` → Нажмите `Next`.
6. Выставьте следующие фильтры, чтобы сузить список ПЛИС:
- Family: `Artix 7`
- Package: `csg324`,
- Speed: `-1`.
На _рис. 1_ показано окно с примененными фильтрами.
7. В списке выберите ПЛИС `xc7a100tcsg324-1` (расположена в самом низу) → Нажмите `Next`.
8. Нажмите `Finish`
![../.pic/Vivado%20Basics/01.%20New%20project/fig_01.png](../.pic/Vivado%20Basics/01.%20New%20project/fig_01.png)
_Рисунок 1. Пример заполнения фильтров для выбора ПЛИС, используемой в Nexys A7._
После нажатия на `Finish`, откроется окно созданного проекта. Выполним его настройку. Для этого, в окне `Flow Navigator`, расположенном в левой части Vivado необходимо нажать на кнопку `Settings`.
В первую очередь, нам необходимо указать какое количество времени работы схемы будет моделироваться при запуске симуляции. Для этого, в группе `Project Settings` необходимо выбрать `Simulation`. В открывшейся странице выбрать вкладку `Simulation`, и в поле `xsim.simulate.runtime` указать значение `1s`, что означает, что по умолчанию будет запускаться симуляция одной секунды времени работы схемы. На _рис. 2_. показан пример данной настройки. Пока что не закрывайте окно настроек.
![../.pic/Vivado%20Basics/01.%20New%20project/fig_02.png](../.pic/Vivado%20Basics/01.%20New%20project/fig_02.png)
_Рисунок 2. Пример настройки времени симуляции._
Одна секунда — это очень большое значение, на многие порядки превышающее время симуляции в большинстве лабораторных работ. Однако верификационное окружение во всех лабораторных будет досрочно останавливать моделирование. Установив подобное большое значение, мы избавимся от необходимости указывать нужное нам время симуляции при каждой симуляции: она просто будет идти, пока не остановится, но в случае, если верификационное окружение почему-то не остановит моделирование, мы будем знать, что оно остановится само по достижении времени в 1с.
Выполним также настройку этапа предобработки (пункт `Elaboration` в группе `Project Settings`). Здесь необходимо установить переключатель в положение `Blackbox model (Stub file)`. На самом деле, в курсе лабораторных работ мы не будем пользоваться ничем, на что влияет эта настройка, однако установив переключатель в данное положение, мы отключим появление ненужного информационного окна каждый раз, когда мы будем выполнять предобработку проекта. После выполнения данной настройки можно нажать на `OK`.
![../.pic/Vivado%20Basics/01.%20New%20project/fig_03.png](../.pic/Vivado%20Basics/01.%20New%20project/fig_03.png)
_Рисунок 3. Пример настройки предобработки проекта._
Все эти настройки можно сделать в автоматическом режиме, введя следующие команды в поле для ввода `Tcl Console`, помеченном текстом `Type a Tcl command here`:
```tcl
set_property -name {xsim.simulate.runtime} -value {1s} -objects [get_filesets sim_1]
set_property elab_link_dcps false [current_fileset]
```

View File

@@ -0,0 +1,24 @@
# Навигатор по маршруту проектирования (Flow Navigatior)
После создания нового проекта, откроется основное окно проекта Vivado, представленного на _рис. 1_.
![../.pic/Vivado%20Basics/02.%20Flow%20Navigator/fig_01.png](../.pic/Vivado%20Basics/02.%20Flow%20Navigator/fig_01.png)
_Рисунок 1. Окно пустого проекта Vivado._
Визуально, основное окно Vivado разделено на две части: тонкую полоску окна `Flow Navigator`, расположенную слева, и основное окно `Project Manager`, расположенную справа. Дело в том, что Vivado представляет собой мощную многофункциональную интегрированную среду разработки (Integrated Design Environment, IDE), состоящую из нескольких подпрограмм, которые для удобства упакованы в одну общую графическую оболочку. `Flow Navigator` позволяет переключаться между этими подпрограммами в рамках одного окна.
Маршрут проектирования подразумевает цикличное повторение шагов:
1. Написание кода.
2. Анализ получившейся схемы на предмет легко обнаруживаемых ошибок.
3. Симуляция схемы
4. Синтез
5. Имплементация
6. Генерация двоичного кода для прошивки ПЛИС
Подробнее о некоторых из этапов рассказано в главе "Этапы реализации проекта в ПЛИС".
Если на каком-то из этапов обнаруживается ошибка, происходит возврат на шаг 1 и повторение всего процесса заново. Благодаря `Flow Navigator` вам не нужно постоянно запускать для каждого этапа новую программу, вы можете быстро переходить от этапа к этапу в рамках одного графического окна.
При этом, в зависимости от того, какую именно подпрограмму вы активировали во `Flow Navigator`, соответствующим образом изменится основная часть окна Vivado. После создания проекта автоматически активируется программа `Project Manager` (выделено бирюзовым в окне `Flow Navigator`), именно поэтому в основном окне открылся менеджер проекта.

View File

@@ -0,0 +1,351 @@
# Менеджер проекта (Project Manager)
Окно Project Manager позволяет управлять проектом: добавлять и редактировать исходные коды проекта, изучить краткое ревью по утилизации ресурсов ПЛИС, используемых для реализации проекта, просматривать логи и сообщения о результатах сборки проекта и многое другое.
В первую очередь нас интересует окно исходных кодов проекта, которое называется `Design Sources` и представлено на _рис. 1_.
## Окно Design Sources
Данное окно находится по умолчанию в верхнем левом углу окна Project Manager (в случае, если вы случайно закрыли это окно, вы можете вернуть его обратно через меню `Windows->Sources`).
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_01.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_01.png)
_Рисунок 1. Окно исходных кодов проекта._
Данное окно разделено на три вкладки:
1. Иерархия (Hierarchy)
2. Библиотеки (Libraries)
3. Порядок сборки (Compile Order)
В определенных ситуациях в данном окне может появиться и вкладка IP Cores, но в рамках данного курса она нас не интересует.
Рассмотрим по порядку данные вкладки.
### Вкладка Hierarchy
Данная вкладка состоит из четырех "папок":
1. Design Sources;
2. Constraints;
3. Simulation Sources;
4. Utility Sources.
В рамках текущего курса лабораторных работ мы будем взаимодействовать только с первыми тремя из них.
Помните, что несмотря на использование слова "папка", речь идет не о директориях операционной системы. Папки проекта — это всего лишь удобная абстракция для управления иерархией проекта.
В папке `Design Sources` строится иерархия проектируемых модулей (исходников цифровых схем, которые в будущем могут быть воспроизведены в ПЛИС или заказной микросхеме).
Папка `Constraints` содержит файлы ограничений, помогающих реализовать проект на конкретной ПЛИС (см. ["Этапы реализации проекта в ПЛИС"](../Introduction/Implementation%20steps.md#implementation)).
`Simulation Sources` хранит в себе иерархию верификационного окружения, **включая модули из папки** `Design Sources` — т.е. все модули (как синтезируемые, так и не синтезируемые), которые будут использованы при моделировании.
> Обратите внимание на то, вкладка `Hierarchy` не содержит файлов. Здесь отображается иерархия модулей проекта. Один модуль может быть использован несколько раз — и в этом случае он будет столько же раз отображён в иерархии, хотя файл, хранящий описание этого модуля останется один (см. _рис. 6_).
#### Добавление файла в проект
Для того, чтобы добавить в проект новый файл, необходимо нажать на значок `+`, расположенный в верхней части окна `Sources` (либо использовать комбинацию горячих клавиш `Alt+A`).
Появится окно добавления исходников. На первой странице этого окна будет необходимо выбрать тип добавляемого файла (см. _рис. 2_).
- файлы ограничений для синтеза схемы под конкретную ПЛИС (`Constraints`);
- файлы проектируемой схемы (`Design Sources`);
- файлы верификационного окружения для верификации схемы (`Simulation Sources`).
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_02.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_02.png)
_Рисунок 2. Первая страница окна добавления исходников._
В первую очередь мы хотим описать какую-нибудь простую схему, поэтому необходимо убедиться, что активным выбран пункт `Design Sources`. Выбрав, нажимаем `Next`.
Появится страница, представленная на _рис. 3_, которая предлагает три варианта добавления исходников.
1. добавить существующий файл;
2. добавить все имеющиеся файлы в заданной директории;
3. создать новый файл.
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_03.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_03.png)
_Рисунок 3. Вторая страница окна добавления исходников._
Создадим новый файл, нажав на соответствующую кнопку окна. Появится всплывающее окно, предлагающее выбрать тип файла и его имя (см. _рис. 4_). В поле `File Type` выберите `SystemVerilog` (этот тип будет использоваться в качестве основного на протяжении всего курса кроме случаев, когда будет сказано иное). В поле `File Name` задайте имя новому файлу (в рамках примера, имя файла будет `max_min`). Указывать расширение файла не нужно — САПР автоматически его добавит в зависимости от выбранного типа файла. Когда всё будет готово, нажмите на `OK`. После того, как были добавлены (или созданы) все необходимые источники, можно нажать кнопку `Finish` в окне `Add Sources`.
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_04.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_04.png)
_Рисунок 4. Окно создания нового файла._
В случае, если создавался новый файл, после нажатия на кнопку `Finish` появится окно, предлагающее автоматически создать прототип модуля, указав в графическом интерфейсе направление и разрядность его портов (см. _рис. 5_). В рамках данного примера, откажемся от данного предложения, нажав кнопки `Cancel->Yes`.
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_05.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_05.png)
_Рисунок 5. Окно описания входов и выходов модуля._
После добавления файлов с исходными кодами, Vivado автоматически начнет обновлять иерархию проекта. Вы можете заметить это по появившейся надписи `Updating` с анимацией крутящейся стрелки, показанной на _рис. 6_.
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_06.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_06.png)
_Рисунок 6. Уведомление об обновлении иерархии проекта._
Пока в окне есть данное уведомление, не рекомендуется запускать подпрограммы во `Flow Navigator` (к примеру, пытаться открыть схематик, запустить симуляцию/синтез и т.п.), поскольку иерархия проекта еще не построена и в конечном итоге может либо произойти ошибка, либо будет выполнено действие не для нужного вам модуля.
> В зависимости от того, какие подпрограммы запущены через `Flow Navigator`, в момент вызова окна `Add Sources`, Vivado автоматически будет стараться выбрать наиболее подходящий пункт (что не всегда будет совпадать с вашим намереньем). К примеру, вы описали модуль, запустили симуляцию, чтобы его проверить, а затем решили описать следующий модуль. Из-за того, что в момент вызова окна `Add Sources` в фоне запущена симуляция, в этом окне по умолчанию будет выбран пункт `Simulation Sources`.
После того, как Vivado закончит обновлять иерархию (и, если при создании файла вы отказались указывать порты модуля, нажав на кнопку `Cancel`), рядом с папкой `Design Sources` появится стрелка, позволяющая развернуть эту папку, внутри которой обнаружится подпапка `Non-module Files` с созданным нами файлом. Новый файл пометили таким образом, поскольку он не содержит модуля. Как только в нем окажется описание какого-нибудь модуля, эта подпапка пропадёт.
Откроем редактор двойным кликом по файлу `max_min.sv` и опишем в нём код, приведённый в листинге 1. В коде _листингов 1-3_ могут содержаться логические ошибки — они запланированы и будут найдены и исправлены в главе "Руководство по поиску и исправлению ошибок".
```Verilog
module max_min(
input logic [31:0] a,
input logic [31:0] b,
output logic [31:0] max,
output logic [ 3:0] min
);
always_comb begin
if(a > b) begin
max = a;
min = b;
end
else begin
max = b;
min = b;
end
end
endmodule
```
_Листинг 1. Описание модуля max\_min._
Не забудьте сохранить файл после описания в нем модуля нажав в редакторе на значок дискеты, или комбинацию клавиш `Ctrl+S`.
Аналогичным образом, добавьте в `Design Sources` проекта файлы `half_divider` и `vector_abs` и опишите в них модули, представленные в _листингах 2-3_ соответственно (все файлы листингов находятся в репозитории в папке [Vivado Basics/vector_abs](./vector_abs/)). На второй странице окна добавления исходников, представленном на _рис. 3_, вы можете создавать сразу несколько новых файлов. При создании убедитесь, что вы выбрали корректный тип файла.
```Verilog
module half_divider(
input logic [31:0] numerator,
output logic [31:0] quotient
);
assign quotient = numerator << 1'b1;
endmodule
```
_Листинг 2. Описание модуля half\_divider._
```Verilog
module vector_abs(
input logic [31:0] x,
input logic [31:0] y,
output logic [31:0] abs
);
logic [31:0] min;
logic [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
```
_Листинг 3. Описание модуля vector\_abs._
В `Simulation Sources` добавьте файл tb_vector_abs, описываемый _листингом 4_.
```Verilog
module tb_vector_abs();
logic [31:0] a;
logic [31:0] b;
logic [31:0] res;
vector_abs dut(
.x(a),
.y(b),
.abs(res)
);
integer err_count = 0;
task check_result(input logic [31:0]a, b, res);
begin : check_result
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;
check_result(a,b,res);
a = 1; b = 1;
#5;
check_result(a,b,res);
a = 3; b = 4;
#5;
check_result(a,b,res);
for(i = 0; i < 100; i=i+1) begin
a = $random()&32'hff; b = $random()&32'hff;
#5;
check_result(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
```
_Листинг 4. Описание модуля tb\_vector\_abs._
#### Построение иерархии модулей
После создания указанных файлов и описания в них модулей из листингов 2-4, иерархия модулей примет следующий вид, представленный на _рис. 7_.
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_07.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_07.png)
_Рисунок 7. Иерархия проекта, представленная в свёрнутом виде._
Нажав на стрелку слева от модуля `vector_abs`, иерархия развернётся (_рис. 8_).
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_08.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_08.png)
_Рисунок 8. Иерархия проекта, представленная в развёрнутом виде._
Обратите внимание на то, что модуль `vector_abs` выделен жирным относительно других модулей. Такое выделение означает, что данный модуль выбран в качестве **модуля верхнего уровня** (**top-level module**). Это означает, это данный модуль и представляет итоговую схему, которую мы проектируем, и что другие подпрограммы во `Flow Navigator`, такие как `RTL ANALYSIS`, `SYNTHESIS`, `IMPLEMENTATION` и `PROGRAM AND DEBUG` будут обрабатывать именно этот модуль. Если вдруг вы захотите работать с другим модулем (например, с модулем, `half_divider`) — его необходимо пометить вручную в качестве модуля верхнего уровня. Для этого необходимо нажать по нему правой кнопкой мыши, и в выпадающем меню выбрать `Set as Top` (см. _рис. 9_).
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_09.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_09.png)
_Рисунок 9. Выбор модуля верхнего уровня (показана середина выпадающего списка)._
Обратите внимание, как строится иерархия проекта. Модули, являющиеся объектами других модулей "вложены" в эти модули. Причем в иерархии проекта сперва указывается имя объекта модуля, затем через двоеточие имя самого модуля. В скобках указывается имя файла, где модуль описан. Модуль, который не содержится в других модулях не имеет имени объекта модуля (т.к. нет сущности, которая бы этот объект создавала). Если модуль будет содержать несколько объектов одного и того же модуля, в иерархии будут отображены все эти объекты — именно поэтому нужно понимать, чем иерархия модулей отличается от дерева файлов. Несмотря на то, что модуль описан всего в одном файле, в иерархии проекта может встречаться несколько экземпляров одного и того же модуля.
Добавьте в `Simulation Sources` файл `tb_vector_abs`, содержимое которого представлено в _листинге 4_.
```Verilog
module tb_vector_abs();
logic [31:0] a;
logic [31:0] b;
logic [31:0] res;
vector_abs dut(
.x(a),
.y(b),
.abs(res)
);
integer err_count = 0;
task check_result(input logic [31:0]a, b, res);
begin : check_result
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;
check_result(a,b,res);
a = 1; b = 1;
#5;
check_result(a,b,res);
a = 3; b = 4;
#5;
check_result(a,b,res);
for(i = 0; i < 100; i=i+1) begin
a = $random()&32'hff; b = $random()&32'hff;
#5;
check_result(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
```
_Листинг 4. Описание модуля tb\_vector\_abs._
#### Ошибки иерархии
В случае, если при создании какого-либо из файлов вы ошиблись с папкой назначения (добавили файл, предназначенный для `Design Sources` в `Simulation Sources` или наоборот), вы можете перенести этот файл в нужную папку без необходимости его удаления и повторного добавления. Для этого кликните по нужному файлу правой кнопкой мыши и выберите `Move to Design/Simulation sources` (см. _рис. 10_).
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_10.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_10.png)
_Рисунок 10. Перенос модуля в нужную папку._
После добавления модуля `tb_vector_abs`, обратите внимание на иерархию `Simulation Sources`. Обратите внимание на то, что все модули `Design Sources` продублированы в `Simulation Sources`. Это ещё одно отличие от дерева файлов. Физически каждый модуль находится всего в одном файле, здесь представлена иерархия модулей.
Можно также заметить, что модуль верхнего уровня в `Simulation Sources` другой. Модуль верхнего уровня в `Simulation Sources` определяет то, какой модуль будет использоваться при симуляции (обычно это тестбенч, внутри которого создан объект проверяемого модуля). Модули верхнего уровня в `Design Sources` и `Simulation Sources` не связаны друг с другом (вам не нужно выбирать модулем верхнего уровня в `Design Sources` тот модуль, что вы будете проверять с помощью тестбенча в `Simulation Sources`).
Давайте изменим в модуле `tb_vector_abs` название модуля `vector_abs`, использовавшееся при создании объекта `DUT` (например на `vector`). Получившаяся иерархия модулей представлена на _рис. 11_.
![../.pic/Vivado%20Basics/03.%20Project%20manager/fig_11.png](../.pic/Vivado%20Basics/03.%20Project%20manager/fig_11.png)
_Рисунок 11. Иерархия проекта с отсутствующим модулем._
Иерархия обновилась, но поскольку в проекте не существует модуля с названием `vector`, это отобразилось соответствующим образом. Поскольку модуль `vector_abs` не является частью модуля `tb_vector_abs`, он перестал быть вложенным модулем и разместился рядом в `Simulation Sources``Design Sources` иерархия осталась прежде, т.к. изменения коснулись только модуля `tb_vector_abs`, расположенного в `Simulation Sources`).
### Вкладка Libraries
В данной вкладке находятся файлы проекта, сгруппированные по библиотекам. В рамках данного курса, эта вкладка использоваться не будет.
### Вкладка Compile Order
Обычно Vivado сам определяет порядок компиляции по иерархии проекта. Однако, в некоторых ситуациях он может определить что-то неправильно. На данной вкладке вы можете исправить порядок компиляции (скорее всего, вам может потребоваться эта вкладка, для указания порядка компиляции пакетов SystemVerilog).
## Дополнительные материалы
Более подробную информацию по окну `Sources` вы можете найти в руководстве пользователя Vivado: ["Vivado Design Suite User Guide: Using the Vivado IDE (UG893)"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide) (раздел ["Using the Sources Window"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide/Using-the-Sources-Window)).

View File

@@ -0,0 +1,72 @@
# Как запустить симуляцию в Vivado
Симуляция — это один из видов моделирования. Моделирование используется для проверки поведения разработанного устройства. Для этого, на входы модуля подаются тестовые воздействия, а с его выходов считывается результат. Параллельно этому процессу, те же самые тестовые воздействия отправляются и в эталонную модель устройства. Результат модели сверяют с результатом проектируемого устройства и, в случае расхождения, сигнализируют об ошибке.
Генерация тестовых воздействий, подача их на верифицируемое устройство и модель, сверка результатов и логирование ошибок — все это выполняется средствами верификационного окружения, которое в рамках данных лабораторных работ будет именоваться как "тестбенч". Тестбенчи — это несинтезируемые модули, поэтому они не должны находиться в папке `Design Sources`, вместо этого для них есть папка `Simulation Sources` (см. ["Менеджер проекта"](03.%20Project%20manager.md)).
Для каждого верифицируемого модуля в репозитории есть отдельный тестбенч. Перед запуском моделирования, необходимо убедиться, что в качестве модуля верхнего уровня в папке `Simulation Sources` выбран тестбенч того модуля, который вы собираетесь верифицировать.
Есть несколько способов запустить симуляцию, рассмотрим два из них:
1. На панели слева, в разделе `SIMULATION`, нажать `Run Simulation``Run Behavioral Simulation`.
![../.pic/Vivado%20Basics/04.%20Simulation/fig_01.png](../.pic/Vivado%20Basics/04.%20Simulation/fig_01.png)
_Рисунок 1. Запуск симуляции через вкладку `SIMULATION` окна `Flow Navigator`._
1. В иерархии проекта нажать по папке `sim_1` правой кнопкой мыши, далее выбрать `Run Simulation``Run Behavioral Simulation`.
![../.pic/Vivado%20Basics/04.%20Simulation/fig_02.png](../.pic/Vivado%20Basics/04.%20Simulation/fig_02.png)
_Рисунок 2. Запуск симуляции через контекстное меню папки `sim_1` в `Simulation Sources`._
После запуска симуляции будет промоделировано определенное количество времени, задаваемое через настройки проекта (после создания проекта мы сделали это количество равное одной секунде), после чего моделирование приостанавливается. Моделирование может быть остановлено досрочно самим тестбенчем.
## Окна для работы с симуляцией
После запуска симуляции в основной части окна Vivado откроется окно симуляции, представленное на _рис. 3_.
![../.pic/Vivado%20Basics/04.%20Simulation/fig_03.png](../.pic/Vivado%20Basics/04.%20Simulation/fig_03.png)
_Рисунок 3. Окно симуляции._
Данное окно состоит из 4-х под-окон:
1. окно с вкладками `Scope` и `Sources`;
2. окно с вкладками `Objects` и `Protocol Instances`;
3. окно редактора с открытыми файлами и появившимся там окном временной диаграммы (которая также представляет собой файл);
4. Окно c вкладками `Tcl Console`, `Messages` и `Log`.
## Окно с вкладками Scope и Sources
Вкладка Sources является той же самой вкладкой, что использовалась вами при добавлении и описании исходников и подробно разобрана в главе "[Менеджер проекта](./03.%20Project%20manager.md)".
Вкладка Scope отображает область видимости симуляции, верхним уровнем в которой является модуль верхнего уровня `Simulation Sources` и библиотека `glbl`, которую в рамках данного курса можно будет игнорировать. Раскрыв модуль верхнего уровня, можно увидеть иерархию модулей подобную иерархии в `Simulation Sources`. Выбрав конкретный модуль во вкладке `Scope`, можно "отправить" его на временную диаграмму: либо перетащив его в область сигналов, либо нажав по нему правой кнопкой мыши, и выбрав `Add to Wave Window`. В этом случае, на временную диаграмму добавятся входы и выходы этого модуля, а также его внутренние сигналы. Кроме того, выбор модуля во вкладке `Scope` влияет на отображение содержимого окна с вкладкой `Objects`.
На вкладке `Objects` находятся все объекты, связанные с модулем, выбранным во вкладке `Scope`: его входы и выходы, внутренние провода и регистры, параметры этого модуля и т.п. С помощью данной вкладки можно добавлять отдельные объекты выбранного модуля.
## Панель инструментов симуляции
После запуска симуляции, вверху окна Vivado меняется панель инструментов. На _рис. 3_ обозначены следующие кнопки:
1. сбросить симуляцию (горячая клавиша `Ctrl+Shift+F5`);
2. запустить симуляцию до тех пор, пока она не будет остановлена тестбенчем или вручную (горячая клавиша `F3`);
3. запустить симуляцию указанного справа от кнопки промежутка времени (горячая клавиша `Shift+F2`);
4. перезапустить симуляцию (по умолчанию горячей клавиши нет, но может быть добавлена в настройках);
5. закрыть симуляцию.
Отличие сброса симуляции от её перезапуска отличается в следующем. При сбросе симуляции очищаются промоделированные значения добавленных на временную диаграмму сигналов (сами сигналы остаются на месте), при этом время симуляции перемещается на нулевую отметку (т.е симуляция начнется заново). Подобное действие может быть необходимо в случае отладки, или же посреди моделирования вы добавили на временную диаграмму новые сигналы, и хотите увидеть их поведение с самого начала симуляции. При сбросе симуляции не выполняется компиляция исходников (даже если их содержимое было изменено).
Перезапуск симуляции аналогичен закрытию симуляции и повторному её открытию. При этом, если в исходниках происходили изменения — файлы будут перекомпилированы. Обратите внимание, что Vivado в первую очередь обнаруживает только изменения, сделанные из собственного редактора. В случае, если файлы были изменены извне (в особенности это касается `mem`-файлов, которые начинают использоваться начиная с четвертой лабораторной работы) — Vivado может не обнаружить новых изменений. В случае, если симуляция ранее уже запускалась и с тех пор Vivado не обнаружил изменений в файлах — повторная компиляция, не производится и симуляция запускается средствами уже скомпилированных объектов. В случае, если изменения были сделаны извне, но Vivado их не обнаружил, можно очистить предыдущую сборку нажав правой кнопкой мыши по кнопки `Simulation` в окне `Flow Navigator` и выбрав `Reset Behavioral Simulation` (см. _рис. 4_).
![../.pic/Vivado%20Basics/04.%20Simulation/fig_04.png](../.pic/Vivado%20Basics/04.%20Simulation/fig_04.png)
_Рисунок 4. Сброс файлов симуляции._
Таким образом, в случае если вы добавили сигналы на временную диаграмму, и хотите увидеть их поведение с нулевого момента времени, или же вы хотите очистить лог сообщений и увидеть сообщения только до определенного момента (т.е. все действия, которые не связаны с повторной компиляцией исходных кодов), имеет смысл сбросить симуляцию и выполнить моделирование повторно.
В случае, если вы изменили исходный код какого-то из модулей, и хотите выполнить моделирование обновленного кода, симуляцию можно закрыть и запустить повторно теми же способами, которыми вы запустили её в прошлый раз, либо перезапустить симуляцию в с помощью кнопки `4`, представленной на _рис. 3_.
> Если вы изменили модуль верхнего уровня в `Simulation Sources`, вам необходимо закрыть текущую симуляцию. Без этого новая не сможет запуститься и будет выдавать ошибку "boost filesystem remove: Процесс не может получить доступ к файлу". Подробнее об этой ошибке рассказано в главе "Список типичных ошибок в Vivado".
Подробнее о поиске ошибок и работе с временной диаграммой рассказано в главе "Руководство по поиску ошибок".

View File

@@ -1,17 +1,18 @@
# Руководство по поиску и исправлению ошибок в проекте
# Руководство по поиску функциональных ошибок
## Цель
При выполнении лабораторных работ вы непременно будете сталкиваться с множеством ошибок. И это нормально: **"Не ошибается тот, кто ничего не делает" — © Джейсон Стейтем**.
Важно воспитать в себе положительное восприятие обнаружения ошибок (ведь это приводит к улучшению вашего творения). Если относиться к обнаружению ошибок отрицательно, то вы подсознательно будете пытаться найти ошибки спустя рукава, но, если вы "в домике", и ошибок не видите — это не значит, что их нет.
При выполнении лабораторных работ вы непременно будете сталкиваться с множеством ошибок. И это нормально: **"Не ошибается тот, кто ничего не делает" — © Джейсон Стейтем**.
При должном отношении, поиск ошибок может превратиться в увлекательное детективное расследование, где у вас есть "место преступления" (обнаруженное несоответствие в поведении, обычно это не сама ошибка, а ее следствие, круги на воде) и какой-то "набор улик" (фрагменты лога, исходный код). И вы по чуть-чуть будете разматывать "нераспутываемую паутину лжи", получая все новые улики, ведущие к истинной ошибке.
Важно воспитать в себе положительное восприятие обнаружения ошибок (ведь это приводит к улучшению вашего творения). Если относиться к обнаружению ошибок отрицательно, то вы подсознательно будете пытаться найти ошибки спустя рукава, но, если вы "в домике", и ошибок не видите — это не значит, что их нет.
Этот документ посвящен практикуму по поискам подобных ошибок в **SystemVerilog**-коде.
При должном отношении, поиск ошибок может превратиться в увлекательное детективное расследование, где у вас есть "место преступления" (обнаруженное несоответствие в поведении, обычно это не сама ошибка, а ее следствие, круги на воде) и какой-то "набор улик" (фрагменты лога, исходный код). И вы, по чуть-чуть, будете разматывать "нераспутываемую паутину лжи", получая всё новые улики, ведущие к истинной ошибке.
Этот документ представляет собой практикум по поиску подобных ошибок в **SystemVerilog**-коде.
> Обратите внимание на то, как ставится ударение в словосочетании "временна́я диаграмма" (не "вре́менная"). В обиходе это словосочетание заменяется словом "времянка".
- [Руководство по поиску и исправлению ошибок в проекте](#руководство-по-поиску-и-исправлению-ошибок-в-проекте)
- [Руководство по поиску функциональных ошибок](#руководство-по-поиску-функциональных-ошибок)
- [Цель](#цель)
- [Алгоритм поиска ошибок](#алгоритм-поиска-ошибок)
- [Работа с логом при появлении ошибок](#работа-с-логом-при-появлении-ошибок)
@@ -27,78 +28,82 @@
## Алгоритм поиска ошибок
1. Обычно всё начинается с сообщения в логе тестов (никто не проверяет глазами временную диаграмму сложных проектов, состоящую из тысяч сигналов, меняющихся миллионы раз за микросекунду), но на наших простых лабах, этот шаг иногда может быть и пропущен.
Сообщение в логе обычно содержит следующую ключевую информацию: имя сигнала, на котором установилось неверное значение, и время когда это произошло. Чем лучше написаны тесты, тем больше ключевой информации будет отражено в сообщении, поэтому написание тестов является своего рода искусством.
2. Получив имя сигнала и время, мы отправляемся на временную диаграмму и проверяем нашу ошибку. Как это сделать? Необходимо определить по коду, какие сигналы и каким образом управляют нашим сигналом. Вариантов может быть несколько:
1. Обычно всё начинается с сообщения в логе тестов (никто не проверяет глазами временную диаграмму сложных проектов, состоящую из тысяч сигналов, меняющихся миллионы раз за микросекунду), но на наших лабораторных работах с относительно простыми модулями, этот шаг иногда может быть и пропущен.
Сообщение в логе обычно содержит следующую ключевую информацию: имя сигнала, на котором установилось неверное значение, и время, когда это произошло. Чем лучше написано верификационное окружение, тем больше ключевой информации будет отражено в сообщении, поэтому его написание является своего рода искусством.
1. Получив имя сигнала и время, мы отправляемся на временную диаграмму и проверяем нашу ошибку. Как это сделать? Необходимо определить по коду, какие сигналы и каким образом управляют нашим сигналом. Вариантов может быть несколько:
1. Управляющие сигналы имеют корректное значение, но логика, по которой они управляют сигналом неверна, из-за этого на нем возникает неверное значение.
Это идеальный случай, при возникновении которого мы сразу же находим причину проблемы и исправляем ее.
2. Логика управления верна, а какая-то часть управляющих сигналов имеет неверное значение (пусть для примера, неверное значение будет на управляющем сигнале `X`). Это означает, что обнаруженное несоответствие сигналов является уже следствием какой-то ошибки, и мы должны вернуться к шагу 2, проверяя источники сигналов для сигнала `X`. Так происходит до тех пор, пока мы не попадаем в тип 1.
2. Логика управления верна, а какая-то часть управляющих сигналов имеет неверное значение (пусть для примера, неверное значение будет на управляющем сигнале `X`). Это означает, что обнаруженное несоответствие сигналов является уже следствием какой-то ошибки, и мы должны вернуться к шагу 2, проверяя источники для сигнала со значением `X`. Так происходит до тех пор, пока мы не попадаем в тип 1.
3. Логика управления и значения управляющих сигналов верны. Это самый сложный тип ошибок, который заключается либо в ошибке в спецификации разрабатываемого устройства, либо в САПРе или компонентах, влияющих на его работу. В рамках данного курса вас не должны заботить данные ошибки, и при их возникновении вам стоит обратиться к преподавателю (предварительно убедившись, что ошибка совершенно точно не подходит под первые два варианта).
4. Любая возможная комбинация всех предыдущих типов.
3. Обнаружив первопричину ошибки, мы исправляем ее (возможно дополняя набор тестов, или внеся правки в спецификацию), и повторно запускаем все тесты, чтобы убедиться в двух вещах:
2. Обнаружив первопричину ошибки, мы исправляем ее (возможно дополняя набор тестов, или внеся правки в спецификацию), и повторно запускаем все тесты, чтобы убедиться в двух вещах:
1. ошибка действительно исправлена
2. исправление ошибки не породило новых ошибок
Давайте отработаем эти шаги на примере отладки ошибок в проекте по [вычислению приблизительной длины вектора](../Other//vector_abs/).
Давайте отработаем эти шаги на примере отладки ошибок в проекте по [вычислению приблизительной длины вектора](./vector_abs/), создание которого было описано в документе "[Менеджер проекта](./03.%20Project%20manager.md)".
## Работа с логом при появлении ошибок
После запуска симуляции мы видим в логе множество ошибок:
![../.pic/Vivado%20Basics/Debug%20manual/fig_01.png](../.pic/Vivado%20Basics/Debug%20manual/fig_01.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_01.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_01.png)
_Рисунок 1. Пример сообщения об ошибках в тесте._
В любой ситуации с множеством ошибок, сначала надо разбираться с самой первой из них, поскольку она может быть причиной появления всех остальных. Поэтому листаем лог до момента первой ошибки:
![../.pic/Vivado%20Basics/Debug%20manual/fig_02.png](../.pic/Vivado%20Basics/Debug%20manual/fig_02.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_02.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_02.png)
_Рисунок 2. Пример конкретной ошибки в тесте._
В логе сказано, что в момент времени `5ns`, на дизайн подавались координаты вектора, равные `0` и `0`, модель посчитала, что длина вектора равна нулю, в то время как дизайн вернул значение `x`.
В логе сказано, что в момент времени `5ns`, на вход схемы подавались координаты вектора, равные `0` и `0`, модель посчитала, что длина вектора равна нулю, в то время как схема вернула значение `x`.
## Поиск ошибки на временной диаграмме
Давайте найдем это место на временной диаграмме. Обычно, сразу после запуска симуляции на временной диаграмме отображено место, где симуляция остановилась (возможно с очень неподходящим масштабом). Для начала подгоним масштаб таким образом, чтобы вся временная диаграмма умещалась в окне. Это делается либо нажатием правой кнопкой мыши по в области отображения сигналов, с выбором "Full View" во всплывающем меню, либо нажатием соответствующей кнопки на панели временной диаграммы (см. _рис. 4_), либо нажатием комбинации клавиш `Ctrl+0`. Затем найдем приблизительное место рядом с тем временем, что нас интересует, установим там курсор, и приблизим масштаб (покрутив колесиком мыши при зажатой клавише `Ctrl`), периодически уточняя местоположения курсора, пока не найдем интересующее нас место.
![../.pic/Vivado%20Basics/Debug%20manual/fig_03.png](../.pic/Vivado%20Basics/Debug%20manual/fig_03.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_03.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_03.png)
_Рисунок 3. Пример временной диаграммы сразу поле остановки моделирования._
![../.pic/Vivado%20Basics/Debug%20manual/fig_04.png](../.pic/Vivado%20Basics/Debug%20manual/fig_04.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_04.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_04.png)
_Рисунок 4. Пример установки масштаба временной диаграммы таким образом, чтобы та помещалась в текущем окне._
![../.pic/Vivado%20Basics/Debug%20manual/fig_05.png](../.pic/Vivado%20Basics/Debug%20manual/fig_05.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_05.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_05.png)
_Рисунок 5. Пример временной диаграммы после подгонки масштаба._
![../.pic/Vivado%20Basics/Debug%20manual/fig_06.png](../.pic/Vivado%20Basics/Debug%20manual/fig_06.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_06.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_06.png)
_Рисунок 6. Установка курсора в начало моделирования, чтобы, при увеличении масштаба, временная диаграмма сходилась к началу._
![../.pic/Vivado%20Basics/Debug%20manual/fig_07.png](../.pic/Vivado%20Basics/Debug%20manual/fig_07.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_07.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_07.png)
_Рисунок 7. Временная диаграмма, отмасштабированная к времени ошибки с рис. 2._
Мы видим ровно ту информацию, которую нам предоставил тестбенч. Теперь надо разобраться в причинах возникновения X-состояния. Такое может произойти в двух ситуациях: какой-то из сигналов, формирующих этот находится в `X` или `Z` состоянии, либо же два каких-то сигнала одновременно пытаются выставить разные значения (подобный вариант встречается куда реже и в цикле ваших лабораторных вряд ли встретится).
Мы видим ровно ту информацию, которую нам предоставил тестбенч. Теперь надо разобраться в причинах возникновения X-состояния. Такое может произойти по множеству причин, вот три из них:
1. какой-то из сигналов, формирующих этот находится в `X` или `Z` состоянии;
2. два каких-то сигнала одновременно пытаются выставить разные значения на целевой сигнал;
3. этот сигнал является выходом модуля, но был описан с ключевым словом `input`.
## Открытие файла исходного кода проблемного сигнала
В любом случае, первым делом необходимо определить, источник формирования значения сигнала `res`. Для этого, откроем файл с исходным кодом, где определен данный сигнал. Для этого, нажмем правой кнопкой мыши по имени сигнала на временной диаграмме, и выберем `Go To Source Code`:
В любом случае, первым делом необходимо определить, источник формирования значения сигнала `res`. Откроем файл с исходным кодом, где определен данный сигнал. Для этого, нажмем правой кнопкой мыши по имени сигнала на временной диаграмме, и выберем `Go To Source Code`:
![../.pic/Vivado%20Basics/Debug%20manual/fig_08.png](../.pic/Vivado%20Basics/Debug%20manual/fig_08.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_08.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_08.png)
_Рисунок 8. Переход к месту объявления "проблемного" сигнала._
Открывается следующий код (с курсором на строчке `wire [31:0] res;`):
Откроется код, представленный в _листинге 1_ (с курсором на строчке `logic [31:0] res;`):
```SystemVerilog
module tb();
```Verilog
module tb_vector_abs();
reg [31:0] a;
reg [31:0] b;
wire [31:0] res;
logic [31:0] a;
logic [31:0] b;
logic [31:0] res;
vector_abs dut(
.x(a),
@@ -108,9 +113,11 @@ vector_abs dut(
//...
```
Выделив `res` мы видим, что у нас подсветился `res` в строке `abs(res)`. Это означает, что мы завели наш провод внутрь объекта `dut` модуля `vector_abs`, и у нас проблема второго типа (X-состояние передалось от выхода `abs` модуля `vector_abs` проводу `res` модуля `tb`).
_Листинг 1. Начало кода симулируемого тестбенча._
В этом можно убедиться, если вытащить сигналы модуля `vector_abs` на временную диаграмму. Чтобы это сделать, надо переключиться на окно `Scope`, где размещена иерархия объектов нашего тестбенча
Выделив `res` мы видим, что у нас подсветился `res` в строке `abs(res)`. Это означает, что мы завели наш провод внутрь объекта `dut` модуля `vector_abs`, и у нас проблема второго типа (в логике работы провода `res` нет ошибок, он принял некорректное значение, поскольку ему таковое передали).
В этом можно убедиться, если вытащить сигналы модуля `vector_abs` на временную диаграмму. Чтобы это сделать, надо переключиться на окно `Scope`, где размещена иерархия моделируемых объектов.
## Добавление сигналов объектов на временную диаграмму
@@ -118,20 +125,20 @@ vector_abs dut(
Выделим объект `dut`. В окне `Objects` справа отобразятся все внутренние сигналы (входы/выходы, внутренние провода и регистры) объекта `dut`:
![../.pic/Vivado%20Basics/Debug%20manual/fig_09.png](../.pic/Vivado%20Basics/Debug%20manual/fig_09.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_09.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_09.png)
_Рисунок 9. Отображение внутренних сигналов проверяемого модуля._
Вообще говоря, мы уже видим, что выход `abs` (к которому подключен наш провод `res`) находится в X-состоянии, но для отработки навыков, разберемся с добавлением на временную диаграмму. Можно поступить двумя способами:
Вообще говоря, мы уже видим, что выход `abs` (к которому подключен наш провод `res`) находится в X-состоянии, но для отработки навыков, разберемся с добавлением новых сигналов на временную диаграмму. Можно поступить двумя способами:
1. Добавить все сигналы (то, что видно в окне `Objects` на временную диаграмму) из окна `Scope` для этого, либо перетаскиваем нужный нам объект, зажав левую кнопку мыши на временную диаграмму, либо жмем правой кнопкой мыши по нужному объекту, и выбираем `Add to Wave Window`
2. Добавить отдельные сигналы из окна `Objects`. Для этого выделяем их (возможно множественное выделение через модификаторы `shift` или `ctrl`), и как и в прошлом случае, либо перетаскиваем сигналы левой кнопкой мыши, либо добавляем их через правую кнопку мыши.
![../.pic/Vivado%20Basics/Debug%20manual/fig_10.png](../.pic/Vivado%20Basics/Debug%20manual/fig_10.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_10.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_10.png)
_Рисунок 10. Добавление сигналов модуля на временную диаграмму._
![../.pic/Vivado%20Basics/Debug%20manual/fig_11.png](../.pic/Vivado%20Basics/Debug%20manual/fig_11.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_11.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_11.png)
_Рисунок 11. Результат добавления сигналов модуля на временную диаграмму._
@@ -139,22 +146,22 @@ _Рисунок 11. Результат добавления сигналов м
Для того чтобы объединить сигналы в группу, необходимо их выделить. Это можно сделать двумя способами:
1. "прокликав" интересующие сигналы при зажатой клавише `Ctrl`;
1. кликнув левой кнопкой мыши по каждому из интересующих сигналов при зажатой клавише `Ctrl`;
2. если речь идет о диапазоне сигналов, можно выбрать сигнал с одного края, после чего, при зажатой клавише `Shift`, выбрать сигнал с другого края этого диапазона.
После выбора, необходимо нажать правой кнопкой мыши по выделенным сигналам, и в низу выпадающего списка выбрать `New Group`.
![../.pic/Vivado%20Basics/Debug%20manual/fig_12.png](../.pic/Vivado%20Basics/Debug%20manual/fig_12.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_12.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_12.png)
_Рисунок 12. Пример создания группы сигналов (контекстное меню было обрезано для удобства отображения)._
После создания группы, ей нужно будет дать имя. В случае, если все сигналы принадлежат одному модулю, удобно называть группу сигналов именем этого модуля.
![../.pic/Vivado%20Basics/Debug%20manual/fig_13.png](../.pic/Vivado%20Basics/Debug%20manual/fig_13.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_13.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_13.png)
_Рисунок 13. Пример созданной группы сигналов._
Данну группу можно сворачивать и разворачивать, нажимая на соответствующую стрелку слева от имени группы.
Данную группу можно сворачивать и разворачивать, нажимая на соответствующую стрелку слева от имени группы.
> Обратите внимание, что часть сигналов отображают какое-то значение (сигнал `abs` отображает X-состояние), а часть не отображают ничего. Так произошло, потому что провод `abs` **непрерывно связан** с проводом `res`, с точки зрения симулятора это одна сущность, и записывая во время моделирования значения для сигнала `res`, симулятор неявно записывал значения для сигнала `abs`, чего не скажешь про остальные сигналы, которых не было во время моделирования на временной диаграмме.
@@ -164,7 +171,7 @@ _Рисунок 13. Пример созданной группы сигнало
Для этого, необходимо на панели симуляции нажать кнопку `Restart` (`|◀`), а затем кнопку `Run all` (`▶`) или `Run for` (`▶t`). Положение кнопок в окне Vivado иллюстрирует _рис. 14_.
![../.pic/Vivado%20Basics/Debug%20manual/fig_14.png](../.pic/Vivado%20Basics/Debug%20manual/fig_14.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_14.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_14.png)
_Рисунок 14. Расположение кнопок, управляющих моделированием в окне Vivado._
@@ -179,52 +186,53 @@ _Рисунок 14. Расположение кнопок, управляющи
`Run all` отличается от `Run for` тем, что в качестве количества моделируемого времени указывается "бесконечность", и моделирование будет остановлено только вручную, либо вызовом соответствующей инструкции.
> Обратите внимание, что для добавления недостающих значений добавленных сигналов лучше всего выполнять описанную выше инструкцию. Аналогичного результата можно добиться и нажатием на кнопку `Relaunch Simulation`, однако эта команда запускает повторную компиляцию и запуск симуляции, что для крупных проектов выльется в потерю времени на излишнюю компиляцию.
> Обратите внимание, что для добавления недостающих значений добавленных сигналов лучше всего выполнять описанную выше инструкцию. Аналогичного результата можно добиться и нажатием на кнопку `Relaunch Simulation`, однако эта команда работает дольше и, если вы не меняли исходный код модулей, не нужна.
Кроме того, чтобы курсор и лог снова не ушли далеко от места первой ошибки, можно сразу указать, необходимое нам время моделирования перед выполнением команды `Run for`: `5ns`.
![../.pic/Vivado%20Basics/Debug%20manual/fig_15.png](../.pic/Vivado%20Basics/Debug%20manual/fig_15.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_15.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_15.png)
_Рисунок 15. Пример моделирования 5ns._
На _рис. 16_ представлен результат моделирования с новыми сигналами.
![../.pic/Vivado%20Basics/Debug%20manual/fig_16.png](../.pic/Vivado%20Basics/Debug%20manual/fig_16.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_16.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_16.png)
_Рисунок 16. Результат повторного моделирования после добавления на временную диаграмму новых сигналов._
Видим два сигнала в Z-состоянии и один сигнал в X-состоянии. Обычно, сигналы с Z-состоянием проще всего исправить, т.к. зачастую это забытое или некорректное подключение провода. Кроме того, сигнал, зависящий от сигнала с Z-состоянием, может оказаться в X-состоянии, так что это может быть решением нашей проблемы, поэтому займемся проводами `min` и `min_half`. Сперва займемся сигналом `min` и перейдем к шагу 2 нашего алгоритма (нажимаем правой кнопкой мыши и выбираем `Go To Source Code`):
Видим два сигнала в Z-состоянии и один сигнал в X-состоянии. Обычно, сигналы с Z-состоянием проще всего исправить, т.к. зачастую это забытое или некорректное подключение провода. Кроме того, сигнал, зависящий от сигнала с Z-состоянием, может оказаться в X-состоянии, так что это может быть решением нашей проблемы, поэтому проверим провода `min` и `min_half`. Сперва займемся сигналом `min` и перейдем к шагу 2 нашего алгоритма (нажимаем правой кнопкой мыши и выбираем `Go To Source Code`):
```SystemVerilog
module vector_abs(
input [31:0] x,
input [31:0] y,
output[31:0] abs
);
```Verilog
module vector_abs(
input logic [31:0] x,
input logic [31:0] y,
output logic [31:0] abs
);
wire [31:0] min;
wire [31:0] min_half;
logic [31:0] min;
logic [31:0] min_half;
max_min max_min_unit(
.a(x),
.b(y),
.max(max),
.min(min)
);
max_min max_min_unit(
.a(x),
.b(y),
.max(max),
.min(min)
);
//...
```
## Исправление сигналов с Z-состоянием
Мы видим, что сигнал `min` подключен к выходу `min` объекта `max_min_unit` модуля `max_min`. Добавим сигналы этого модуля на временную диаграмму. Для этого, необходимо раскрыть список объектов, содержащихся в объекте `dut` иерархии объектов `Scope` и выбрать там объект `max_min_unit`.
![../.pic/Vivado%20Basics/Debug%20manual/fig_17.png](../.pic/Vivado%20Basics/Debug%20manual/fig_17.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_17.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_17.png)
_Рисунок 17. Добавление сигналов вложенных модулей на временную диаграмму._
Добавляем внутренние сигналы на временную диаграмму, группируем их под именем `max_min`, и повторяем моделирование.
![../.pic/Vivado%20Basics/Debug%20manual/fig_18.png](../.pic/Vivado%20Basics/Debug%20manual/fig_18.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_18.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_18.png)
_Рисунок 18. Результат добавления и группировки сигналов подмодуля `max_min`._
@@ -234,39 +242,39 @@ _Рисунок 18. Результат добавления и группиро
Если присмотреться к этим двум сигналам еще пристальней, то можно увидеть, что у сигнала `min` объекта `dut` разрядность 32 бита, в то время как разрядность сигнала `min` объекта `max_min_unit` составляет 4 бита.
Это и является проблемой: мы подключили 4 бита сигнала 4-разрядного сигнала `min` к младшим 4 битам 32-разрядного сигнала `min`, а остальные разряды остались не подключенными.
Это и является проблемой: мы подключили 4 бита 4-разрядного сигнала `min` к младшим 4 битам 32-разрядного сигнала `min`, а остальные разряды остались не подключенными.
По всей видимости, при написании модуля `max_min`, была указана неверная разрядность сигнала `min`, вместо `31` было написано `3`. Исправим это и повторим моделирование.
> Обратите внимание, что поскольку мы изменили исходный код, в этот раз необходимо нажать на кнопку `Relaunch Simulation`, поскольку нужна повторная компиляция проекта.
![../.pic/Vivado%20Basics/Debug%20manual/fig_19.png](../.pic/Vivado%20Basics/Debug%20manual/fig_19.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_19.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_19.png)
_Рисунок 19. Результат моделирования после исправления разрядности сигнала `min`._
В логе сообщается о 102 найденных ошибках. Ровно на одну ошибку меньше, чем было ранее. Это не означает, что в проекте осталось 102 ошибки, только то, что, исправив данную ошибку — мы действительно что-то исправили, и один из тестовых сценариев, который ранее завершался ошибкой, теперь завершился без нее.
В логе сообщается о 102 найденных ошибках. Ровно на одну ошибку меньше, чем было ранее. Это не означает, что в проекте осталось 102 ошибки, только то, что, исправив данную ошибку — мы действительно что-то исправили, и один из тестовых сценариев, который ранее завершался ошибкой, теперь завершился без неё.
Помните, что если в проекте много ошибок, то часть ошибок может выправлять поведение других ошибок (хоть и не всегда, но иногда минус на минус может выдать плюс контексте ошибок проекта), поэтому надо осторожно полагаться на число найденных ошибок, если их больше нуля.
Помните, что если в проекте много ошибок, то часть ошибок может выправлять поведение других ошибок (хоть и не всегда, но иногда минус на минус может выдать плюс контексте ошибок проекта), поэтому надо осторожно полагаться на число найденных ошибок, если это число больше нуля.
Посмотрим на нашу временную диаграмму снова, и выберем дальнейшие действия:
![../.pic/Vivado%20Basics/Debug%20manual/fig_20.png](../.pic/Vivado%20Basics/Debug%20manual/fig_20.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_20.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_20.png)
_Рисунок 20. Временная диаграмма после исправления разрядности сигнала `min`._
Мы видим, что на временной диаграмме не осталось сигналов в X или Z-состоянии, а значит мы собрали все "низковисящие" улики нашего с вами расследования. Вернемся к месту преступления и попробуем поискать новые улики:
![../.pic/Vivado%20Basics/Debug%20manual/fig_21.png](../.pic/Vivado%20Basics/Debug%20manual/fig_21.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_21.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_21.png)
_Рисунок 21. Первая ошибка в новом логе моделирования._
## Поиск ошибки в сигналах, формирующих проблемный сигнал
Мы видим, что первой ошибкой в логе стала не та ошибка, что была прежде. Раньше первый неверный результат мы видели в момент времени `5ns`, когда на дизайн подавались значения `0` и `0`, теперь же первой ошибкой стал момент времени `10ns`, когда на дизайн подаются значения `1` и `1`. Наше устройство считает, что результат должен равняться `3`, в то время как модель считает, что результат должен равняться `1`. Проверим, нет ли ошибки в модели и посчитаем результат самостоятельно:
Мы видим, что первой ошибкой в логе стала не та ошибка, что была прежде. Раньше первый неверный результат мы видели в момент времени `5ns`, когда на схему подавались значения `0` и `0`, теперь же первой ошибкой стал момент времени `10ns`, когда на схему подаются значения `1` и `1`. Наше устройство считает, что результат должен равняться `3`, в то время как модель считает, что результат должен равняться `1`. Проверим, нет ли ошибки в модели и посчитаем результат самостоятельно:
Для определения приблизительной длины вектора в евклидовом пространстве(вычисления квадратного корня из суммы квадратов / длины гипотенузы прямоугольного треугольника) можно воспользоваться формулой:
Для определения приблизительной длины вектора в евклидовом пространстве (т.е. длины гипотенузы прямоугольного треугольника, которая равна квадратному корню из суммы квадратов катетов) можно воспользоваться формулой:
`sqrt(a^2 + b^2) ≈ max + min/2`, где `max` и `min` — большее и меньшее из пары чисел соответственно [**Ричард Лайонс: Цифровая обработка сигналов, Глава 13.2, стр. 475**].
`sqrt(a^2 + b^2) ≈ max + min/2`, где `max` и `min` — большее и меньшее из пары чисел соответственно [**Ричард Лайонс: Цифровая обработка сигналов, стр. 475**].
Подставим наши числа в формулу (поскольку оба числа равны, не важно какое из них будет максимумом, а какое минимумом):
@@ -274,7 +282,7 @@ _Рисунок 21. Первая ошибка в новом логе модел
1 + 1/2 = 1.5
```
Ни модель, ни дизайн не правы?
Ни модель, ни схема не правы?
На самом деле, наше устройство поддерживает только целочисленную арифметику, поэтому результат будет:
@@ -284,26 +292,27 @@ _Рисунок 21. Первая ошибка в новом логе модел
Модель правильно отразила особенность нашего устройства и дала корректный результат.
Значит надо смотреть как формируется результат в нашем устройстве, посмотрим на выход `abs` в модуле `vector_abs`:
Значит надо смотреть как формируется результат в нашем устройстве. Посмотрим на выход `abs` в модуле `vector_abs`:
```SystemVerilog
```Verilog
assign abs = max + min_half;
```
Выход `abs` зависит от двух внутренних сигналов: max и `min_half`. В соответствии с нашим алгоритмом, либо проблема в логике, связывающей эти два сигнала (операции сложения), либо в значении какого-то из этих сигналов, либо комбинации этих вариантов.
Изучив модуль, мы понимаем, что в логике этого присваивания проблем нет, т.к. оно повторяет логику формулы `max + min/2`, складывая максимум с половиной минимума. Значит проблема в значении какого-то из этих сигналов (или обоих из них). Посчитаем значения этих сигналов самостоятельно (для сложного проекта эти значения бы посчитала модель):
Изучив модуль, мы понимаем, что в логике этого присваивания проблем нет, т.к. оно повторяет логику формулы `max + min/2`, складывая максимум с половиной минимума. Значит проблема в значении какого-то из этих сигналов (или обоих из них). Посчитаем значения этих сигналов самостоятельно (для сложного проекта эти значения посчитала бы модель):
`1` и `0`.
Смотрим, какие значения установлены на сигналах `max` и `min_half` в момент времени `10ns`.
![../.pic/Vivado%20Basics/Debug%20manual/fig_22.png](../.pic/Vivado%20Basics/Debug%20manual/fig_22.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_22.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_22.png)
_Рисунок 22. Значения сигналов `max` и `min_half` в момент времени `10 ns`
_Рисунок 22. Значения сигналов `max` и `min_half` в момент времени `10 ns` (интересующие нас сигналы выделены зелёным)_
> Обратите внимание: вы можете менять и цвета сигналов временной диаграммы через контекстное меню выделенных сигналов.
> Обратите внимание: вы можете менять цвета сигналов временной диаграммы через контекстное меню выделенных сигналов.
Мы видим, что в момент времени `10 ns` значения `max` и `min_half` изменились ак `1 -> 4` и `2 -> 8` соответственно. Нас интересуют значения `1` и `2`, т.к. в момент времени `10ns` на выходе дизайна в этот момент был установившийся результат для предыдущих значений (еще не успел посчитаться результат для новых значений).
Мы видим, что в момент времени `10 ns` значения `max` и `min_half` изменились как `1 -> 4` и `2 -> 8` соответственно. Нас интересуют значения `1` и `2`, т.к. в момент времени `10ns` на выходе схемы в этот момент был установившийся результат для предыдущих значений (еще не успел посчитаться результат для новых значений).
Значение `max=1` совпадает с ожидаемым, в то время как `min_half=2` явно нет.
@@ -311,7 +320,7 @@ _Рисунок 22. Значения сигналов `max` и `min_half` в м
Как и с сигналом `abs`, необходимо определить сигналы, влияющие на значение сигнала `min_half`. Данный сигнал подключен к выходу `quotient` модуля `half_divider`, поэтому мы будем смотреть исходный код данного модуля:
```SystemVerilog
```Verilog
module half_divider(
input [31:0] numerator,
output[31:0] quotient
@@ -326,11 +335,11 @@ endmodule
Выход данного модуля зависит от входа `numerator` и логики сдвига влево на 1. Это значит, что проблема либо в логике, либо в значении, подаваемом на вход. Выведем сигнал `numerator` на временную диаграмму и посмотрим на его значение в момент времени `10ns.
![../.pic/Vivado%20Basics/Debug%20manual/fig_23.png](../.pic/Vivado%20Basics/Debug%20manual/fig_23.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_23.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_23.png)
_Рисунок 23. Значение сигнала `numerator` в момент времени `10 ns`._
Мы помним, что в момент, когда дизайн начал выдавать неправильный результат, на его входы подавались числа `1` и `1`, это значит, что на вход `numerator` пришло корректное значение: минимум из этих двух чисел и правда равен `1`. Проверим логику данного модуля.
Мы помним, что в момент, когда схема начала выдавать неправильный результат, на его входы подавались числа `1` и `1`, это значит, что на вход `numerator` пришло корректное значение: минимум из этих двух чисел и правда равен `1`. Проверим логику данного модуля.
## Исправление логики проблемного сигнала
@@ -344,19 +353,19 @@ _Рисунок 23. Значение сигнала `numerator` в момент
Повторяем моделирование.
![../.pic/Vivado%20Basics/Debug%20manual/fig_24.png](../.pic/Vivado%20Basics/Debug%20manual/fig_24.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_24.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_24.png)
_Рисунок 24. Результат моделирования после исправления оператора сдвига._
Снова на одну ошибку меньше. Не унываем, вряд ли в проекте число ошибок больше, чем число непустых строк самого проекта. Возвращаемся к начальной ошибке:
![../.pic/Vivado%20Basics/Debug%20manual/fig_25.png](../.pic/Vivado%20Basics/Debug%20manual/fig_25.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_25.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_25.png)
_Рисунок 25. Первая ошибка в повторном моделировании._
Мы продвинулись во времени безошибочного моделирования до `15 ns`, начинаем наше расследование с начала:
На вход дизайна подаются значения `3` и `4`, дизайн считает, что результатом вычисления `max + min/2` будет `2`, модель считает, что `5`. Посчитаем сами:
На вход схемы подаются значения `3` и `4`, схема считает, что результатом вычисления `max + min/2` будет `2`, модель считает, что `5`. Посчитаем сами:
```text
max=4
@@ -368,31 +377,31 @@ max + min/2 = 4 + 3/2 = 4 + 1 = 5
## Проблема необъявленных сигналов
К этому моменту на вашей временной диаграмме скорей всего стало уже очень много сигналов. Уберем лишние, оставив только внутренние сигналы модуля `vector_abs` (для этого выделяем не нужные сигналы, и удаляем их с помощью клавиши `Delete`).
К этому моменту на вашей временной диаграмме скорей всего стало уже очень много сигналов. Уберем лишние, оставив только внутренние сигналы модуля `vector_abs` (для этого выделяем ненужные сигналы, и удаляем их с помощью клавиши `Delete`).
![../.pic/Vivado%20Basics/Debug%20manual/fig_26.png](../.pic/Vivado%20Basics/Debug%20manual/fig_26.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_26.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_26.png)
_Рисунок 26. Поведение внутренних сигналов модуля `vector_abs` на временной диаграмме._
В глаза сразу же бросается, что сигнал `max` внешне отличается от всех остальных — он ведет себя как однобитный сигнал. Если все остальные сигналы 32-разрядные, то и сигнал `max` должен быть таким же. Перейдем к объявлению этого сигнала, чтобы это исправить (нажав правой кнопкой мыши, и выбрав `Go To Source Code`):
```SystemVerilog
module vector_abs(
input [31:0] x,
input [31:0] y,
output[31:0] abs
);
```Verilog
module vector_abs(
input logic [31:0] x,
input logic [31:0] y,
output logic [31:0] abs
);
wire [31:0] min;
wire [31:0] min_half;
logic [31:0] min;
logic [31:0] min_half;
max_min max_min_unit(
.a(x),
.b(y),
.max(max),
.min(min)
);
max_min max_min_unit(
.a(x),
.b(y),
.max(max),
.min(min)
);
//...
```
@@ -400,7 +409,7 @@ _Рисунок 26. Поведение внутренних сигналов м
Для исправления этой ошибки, объявим сигнал `max` с корректной разрядностью и повторим моделирование.
![../.pic/Vivado%20Basics/Debug%20manual/fig_27.png](../.pic/Vivado%20Basics/Debug%20manual/fig_27.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_27.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_27.png)
_Рисунок 27. Результат моделирования после объявления пропущенного сигнала._
@@ -408,13 +417,13 @@ _Рисунок 27. Результат моделирования после о
Число ошибок сократилось до 40! Мы явно на верном пути. Повторяем предыдущие шаги, вернувшись к первой ошибке:
![../.pic/Vivado%20Basics/Debug%20manual/fig_28.png](../.pic/Vivado%20Basics/Debug%20manual/fig_28.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_28.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_28.png)
_Рисунок 28. Первая ошибка в повторном моделировании._
В этот раз первая ошибка осталась прежней, только теперь дизайн считает, что результат должен равняться шести (в прошлый раз дизайн выдавал `2`). Мы уже убедились, что в этом случае модель дает правильный результат, поэтому сразу перейдем к формирующим результат сигналам:
В этот раз первая ошибка осталась прежней, только теперь схема считает, что результат должен равняться шести (в прошлый раз схема выдавала `2`). Мы уже убедились, что в этом случае модель дает правильный результат, поэтому сразу перейдем к формирующим результат сигналам:
![../.pic/Vivado%20Basics/Debug%20manual/fig_29.png](../.pic/Vivado%20Basics/Debug%20manual/fig_29.png)
![../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_29.png](../.pic/Vivado%20Basics/05.%20Bug%20hunting/fig_29.png)
_Рисунок 29. Поведение внутренних сигналов модуля `vector_abs` на временной диаграмме._
@@ -422,4 +431,4 @@ _Рисунок 29. Поведение внутренних сигналов м
Не отходя далеко от кассы, мы замечаем, что значение `min`, формирующее сигнал `min_half` неверно: его значение `4`, а должно быть `3`.
Используя [файлы исходного кода проекта](../Other/vector_abs/), попробуйте разобраться в последней обнаруженной нами ошибке.
Используя [файлы исходного кода проекта](./vector_abs/), попробуйте разобраться в последней обнаруженной нами ошибке.

View File

@@ -0,0 +1,37 @@
# Анализ RTL
**RTL** (**register transfer level** — **уровень межрегистровых передач**) — это один из уровней абстракции при проектировании цифровой схемы, когда та описывается в виде регистров и логики передачи данных между этими регистрами.
Vivado предоставляет средства по анализу RTL-кода, позволяя обнаруживать и исправлять ошибки на раннем этапе, до выполнения моделирования и попытки синтезировать проект. Для того чтобы провести анализ, необходимо выполнить предобработку проекта (`Open Elaborated Design`, см. _рис. 1_).
![../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_1.png](../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_1.png)
_Рисунок 1. Инструменты анализа RTL в окне `Flow Navigator`._
Итогом предобработки станет отображение графической схемы (подробнее рассказано в документе "[Этапы реализации проекта в ПЛИС](../Introduction/Implementation%20steps.md)"). Если схема не отобразилось, можно нажать на кнопку `Schematic`.
![../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_2.png](../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_2.png)
_Рисунок 2. Пример построения схемы для схемы, описанной в документе "[Менеджер проекта](./03.%20Project%20manager.md)"._
Допустим нашли ошибку, изменили код модуля и хотите увидеть обновленную схему. Вы нажимаете на кнопку `Schematic` у вас появляется новая вкладка, но схема на ней осталась без изменений. Дело в том, что открытие новой схемы требует повторной предобработки проекта. Для этого необходимо либо закрыть окно `Elaborated Design`, и открыть его заново, либо нажать на кнопку `Reload Design` вверху окна Vivado, которая появляется в информационном сообщении при обновлении кода модуля (см. _рис. 3_).
![../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_3.png](../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_3.png)
_Рисунок 3. Информационное сообщение о том, что предобработанный проект устарел в виду изменения исходников. Кнопка Reload позволяет выполнить повторную предобработку для обновленного кода._
Помимо построения схемы, Vivado выполнит её анализ, а обнаруженные проблемы будут отображены во вкладке `Messages`, которая расположена внизу окна Vivado (_рис. 4_).
![../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_4.png](../.pic/Vivado%20Basics/06.%20RTL%20Analysis/fig_4.png)
_Рисунок 4. Окно с сообщениями о результатах выполненных операциях. Для удобства отображения, информационные сообщения скрыты, оставлены только предупреждения._
Проблема окна сообщений заключается в том, что их число быстро накапливается и превращается в огромный поток, с которым тяжело работать даже с включенными фильтрами. Более того, сообщения сохраняются между запусками анализа, т.е. даже если вы исправите какую-то проблему — сообщение о ней так и останется до тех пор, пока вы не очистите окно сообщений.
Начиная с версии 2023.1 в Vivado появился специальный инструмент — линтер, который анализирует код и сообщает о проблемах в отдельном окне. Проблемы группируются по типам и список проблем очищается и генерируется повторно каждый раз, когда запускается линтер.
Если вы уже прочли документ "[Руководство по поиску функциональных ошибок](./05.%20Bug%20hunting.md)", вы можете заметить, что предупреждения, которые Vivado вывел в окно сообщений напрямую связаны с ошибками, которые мы обнаружили в процессе симуляции. Разница заключается в том, что Vivado вывел сообщения об этих ошибках практически мгновенно, в то время как нам для этого потребовалось проводить целое расследование. Именно в этом и заключается мощь данного инструмента — он позволяет найти большинство простых ошибок, давая возможность сосредоточиться на более сложных.
## Дополнительные материалы
Подробнее о взаимодействии с окном схемы можно прочитать в руководстве пользователя Vivado: ["Vivado Design Suite User Guide: Using the Vivado IDE (UG893)"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide) (раздел ["Using the Schematic Window"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide/Using-the-Schematic-Window)).

View File

@@ -0,0 +1,31 @@
# Как прошить ПЛИС
После того как вы описали и верифицировали модуль, остается запрототипировать его в ПЛИС. Для этого в большинстве папок лабораторных работ есть подпапка `board_files` в которой хранятся необходимые файлы. Обычно там будет находиться модуль верхнего уровня и файл ограничений, которые позволяют связать вашу логику с периферией, расположенной на плате `Nexys-A7`.
Для сборки итогового проекта вам необходимо:
1. Добавить модуль верхнего уровня (содержащийся в файле с расширением `.sv`) в `Design Sources` вашего проекта.
2. Выбрать добавленный модуль в качестве модуля верхнего уровня вашего проекта.
1. Для этого нажмите по нему правой кнопкой мыши.
2. В контекстном меню выберете `Set as Top`.
3. Добавить файл ограничений (с расширением `.xdc`) в `Constraints` вашего проекта. Если такой файл уже есть в вашем проекте (а он будет в нём уже после первой лабораторной), вам необходимо заменить содержимое старого файла содержимым нового. Ограничения меняются от лабораторной к лабораторной.
После выполнения указанных шагов, ваш проект готов к генерации битстрима — двоичного файла, с помощью которого реконфигурируется ПЛИС.
По сути, весь процесс генерации битстрима и конфигурациии оным ПЛИС сводится к последовательному нажатию следующих четырех кнопок в группе `PROGRAM AND DEUBG` окна `Flow Navigator`, которые представлены на _рис. 1_.
![../.pic/Vivado%20Basics/07.%20Program%20and%20debug/fig_1.png](../.pic/Vivado%20Basics/07.%20Program%20and%20debug/fig_1.png)
_Рисунок 1. Порядок выполнения действий для компиляции проекта и прошивки ПЛИС._
Нажатие на кнопку Generate Bitstream позволяет сгенерировать двоичный код для конфигурации ПЛИС. В случае, если перед этим не были выполнены этапы синтеза и имплементации, появятся всплывающие окна, предлагающие выполнить эти этапы. Вам достаточно утвердительно отвечать во всех всплывающих окнах (варианты `YES`/`OK`, в зависимости от состояния вашего проекта, число появляющихся окон будет различным). Последним окном, информирующим о том, что двоичный файл готов будет `Bitstream Generation Completed` (в случае, если все этапы были выполнены без ошибок).
Остаётся прошить ПЛИС. Для этого подключите отладочный стенд к USB-порту компьютера и включите на стенде питание.
Затем запустите менеджер аппаратуры Vivado. Для этого нажмите на кнопку `Open Hardware Manager` (кнопка 2 на _рис. 1_).
После, необходимо подключиться к ПЛИС. Для этого необходимо нажать на кнопку `Open Target` (кнопка 3 на _рис. 1_) и в контекстном меню выбрать вариант `Auto Connect`.
И последним шагом остается прошить ПЛИС нажатием на кнопку `Program Device` (кнопка 4 на _рис. 1_). Появится всплывающее окно, предлагающее выбрать двоичный файл конфигурации, поле которого будет автоматически заполнено путем к последнему сгенерированному файлу. Вам не нужно ничего менять, только нажать на кнопку `Program`.
После этого появится окно с индикатором реконфигурации ПЛИС. Когда окно закроется, ПЛИС будет сконфигурирована под прототип вашего модуля.

View File

@@ -0,0 +1,27 @@
# Руководство по работе с ошибками обработки кода
Некоторые ошибки (например ошибки синтаксиса или иерархии) могут привести к тому, что САПР не сможет построить схему или запустить симуляцию.
Без должного опыта, при подобных ошибках можно растеряться, т.к. всплывающие окна, сообщающие об этих ошибках малоинформативны (см. _рис. 1-2_).
Предположим, мы забыли поставить точку с запятой в конце одного из присваиваний, и попробовали запустить моделирование.
В результате, всплывающие окна, представленные на _рис. 1-2_.
![../.pic/Vivado%20Basics/08.%20Code%20processing%20errors/fig_01.png](../.pic/Vivado%20Basics/08.%20Code%20processing%20errors/fig_01.png)
_Рисунок 1. Первое всплывающее окно при попытке запустить моделирование проекта с синтаксической ошибкой._
![../.pic/Vivado%20Basics/08.%20Code%20processing%20errors/fig_02.png](../.pic/Vivado%20Basics/08.%20Code%20processing%20errors/fig_02.png)
_Рисунок 2. Второе всплывающее окно при попытке запустить моделирование проекта с синтаксической ошибкой._
Во втором окне есть кнопка `Open Messages View`. Нажмём её. Будет активировано окно сообщений, представленное на _рис. 3_.
![../.pic/Vivado%20Basics/08.%20Code%20processing%20errors/fig_03.png](../.pic/Vivado%20Basics/08.%20Code%20processing%20errors/fig_03.png)
_Рисунок 3. Окно сообщений после неудачной попытки запуска симуляции._
Сообщения из раздела `Vivado commands` на _рис. 2_ дают мало информации. Однако здесь же есть критические предупреждения о синтаксической ошибке с возможностью перейти к строчке в файле, вызвавшей это предупреждение. Разумеется, не всегда САПР может сообщить доступным языком в чем именно ошибка, в данном случае, он просто обнаружил что ключевое слово `end` встретилось не там, где оно должно было бы быть (оно встретилось до завершения оператора присваивания, который должен был быть завершен символом `;`). В этом случае, вам необходимо самим разобраться в чем именно заключается ошибка (для этого вы можете кликнуть по гиперссылке в критическом предупреждении — откроется редактор с местом ошибки).
Помните, что большая часть сообщений в данном окне сохраняется даже если ошибка будет исправлена, поэтому рекомендуется очищать окно сообщений, в случае если появились ошибки и уже сложно понять какие из них старые, а какие из них новые. Сделать это можно, нажав на иконку корзины в окне сообщений. При этом удалятся не все ошибки, а только те, которые были вызваны процессами, запущенными пользователем. К примеру, если очистить окно сообщений, не исправив указанную ошибку, пропадут только ошибки из раздела `Vivado commands`. Дело в том, что критические предупреждения появились не после того, как мы попытались запустить моделирования, а после того, как Vivado автоматически запустил инструменты анализа кода. Делает он это автоматически каждый раз, когда сохраняется файл. Эти ошибки пропадут только когда повторный анализ покажет, что они были исправлены.

View File

@@ -1,34 +0,0 @@
# Инструкция по работе с ошибками элаборации
Итак, вы описали модуль на языке SystemVerilog и хотите открыть логическую схему или запустить симуляцию, чтобы убедиться, что описание верно.
Однако, в результате какого-то из этих действий появляется окно с сообщением о непонятной ошибке:
![../.pic/Vivado%20Basics/Elaboration%20failed/simFail.png](../.pic/Vivado%20Basics/Elaboration%20failed/simFail.png)
_Рисунок 1. Пример окна ошибки при попытке запустить моделирование._
Ничего страшного — ошибки, это часть учебного и рабочего процесса.
Смело нажимаем `OK`, не читая сообщения (и поступаем так же, с еще одним открывшимся окном).
Мы собираемся получить информацию об ошибки из более подробного источника: вкладки `Tcl Console`.
![../.pic/Vivado%20Basics/Elaboration%20failed/err_log.png](../.pic/Vivado%20Basics/Elaboration%20failed/err_log.png)
_Рисунок 2. Элементы `Tcl Console`, содержащей лог сообщений нашего взаимодействия с Vivado`._
На _рис. 2_ представлено:
1. Место последнего запуска (конец синего текста) — лог хранит информацию по всем попыткам запуска моделирования / открытия схемы. Каждая такая попытка будет начинаться с текста синего цвета, а значит по нему можно отслеживать начало нашего лога.
2. Если попыток запуска было много, навигация по логу может быть осложнена. Для упрощения навигации, можно сворачивать неинтересующие нас попытки через кнопку, обозначенную на _рис. 2_ меткой `2`.
3. Кроме того, вместо сворачивания ненужных логов, можно очистить от сообщений всю `Tcl Console`, чтобы начать работу "с чистого листа". Это можно сделать нажав на кнопку с иконкой корзины, обозначенной меткой `3`.
4. Чтение ошибок в логе должно начинаться с самой первой, т.к. одна ошибка может причиной последующих.
5. Найдя первую ошибку, необходимо внимательно ознакомиться с сообщением этой ошибки (обозначено меткой `5`).
6. Сообщение об ошибке обычно сопровождается номером строки в конкретном файле, вызвавшей эту ошибку.
Чаще всего этого сообщения будет достаточно, чтобы понять в чем дело.
В случае, если вы все ещё не понимаете в чем проблема, сверьтесь со [списком типовых ошибок](../Other/FAQ.md).
Если не помог и он, обратитесь к преподавателю.

View File

@@ -1,43 +0,0 @@
# Как открыть цифровую схему проекта
Одним из способов первичной оценки результатов описания модуля является просмотр логической схемы, построенной по описанию этого модуля. Порядок открытия схемы следующий:
Сохраняем модуль → Слева на панели управления раскрываем вкладку `RTL ANALYSIS` → Раскрываем вкладку `Open Elaborated Design` → Нажимаем на `Schematic`.
![../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_1.png](../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_1.png)
_Рисунок 1. Расположение кнопки `Schematic`._
Нажатие на `Schematic` приведет к появлению окна `Elaborate Design`, в котором необходимо будет нажать на кнопку `OK`.
![../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_2.png](../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_2.png)
_Рисунок 2. Окно `Elaborate Design`._
После нажатия на `OK`, появится окно `Open Elaborated Design`, которое автоматически пропадет по завершению процесса. В случае если вы компилируете крупный проект и хотите продолжить работу во время компиляции, вы можете нажать на кнопку `Background`.
![../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_3.png](../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_3.png)
_Рисунок 3. Окно `Open Elaborated Design`._
После этого в окне `Project Manager` появится вкладка `Schematic`, где вы должны увидеть свою схему:
![../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_4.png](../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_4.png)
_Рисунок 4. Открывшаяся схема модуля._
> Обратите внимание, что во вкладках SYNTHESIS и IMPLEMENTATION также есть возможность открыть Schematic. Запуск в них строит схему на основе примитивов ПЛИС (см. "Этапы реализации проекта в ПЛИС"). В рамках лабораторных работ нам будет интересна именно цифровая схема, собранная из логических элементов, которая открывается при нажатии на `Schematic` во вкладке RTL ANALYSIS.`
## Как обновить схему после правок модуля
После правок в модуле, необходимо отобразить обновленную схему. Повторное нажатие на `Schematic` приведет лишь к открытию ещё одной вкладки со старой версией схемы.
Однако, после изменения модуля вы можете обратить внимание на появление светло-жёлтого уведомления вверху окна `Project Manager`, где будет сказано о том, что построенный проект устарел, т.к. исходники были изменены, а рядом с ним — кнопку "Reload" (см. _рис. 5_). Нажатие по этой кнопке приведет к рекомпиляции проекта и открытию обновленной схемы.
![../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_5.png](../.pic/Vivado%20Basics/How%20to%20open%20a%20schematic/fig_5.png)
_Рисунок 5. Кнопка повторной загрузки схемы._
## Дополнительные материалы
Подробнее о взаимодействии с окном схемы можно прочитать в руководстве пользователя Vivado: ["Vivado Design Suite User Guide: Using the Vivado IDE (UG893)"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide) (раздел ["Using the Schematic Window"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide/Using-the-Schematic-Window)).

View File

@@ -1,32 +0,0 @@
# Как прошить ПЛИС
После того как вы описали и верифицировали модуль, остается запрототипировать его в ПЛИС. Для этого в большинстве папок лабораторных работ есть подпапка `board_files` в которой хранятся необходимые для этого файлы. Обычно там будет находиться модуль верхнего уровня и файл ограничений, которые позволяют связать вашу логику с периферией, расположенной на плате `Nexys-A7`.
Для сборки итогового проекта вам необходимо:
1. Добавить модуль верхнего уровня (содержащийся в файле с расширением `.sv`) в `Design Sources` вашего проекта.
2. Выберете добавленный модуль в качестве модуля верхнего уровня вашего проекта.
1. Для этого нажмите по нему правой кнопкой мыши.
2. В контекстном меню выберете `Set as Top`.
3. Добавьте файл ограничений (с расширением `.xdc`) в `Constraints` вашего проекта. Если такой файл уже есть в вашем проекте (а он будет в нем уже после первой лабораторной), вам необходимо заменить старого файла содержимым нового. Ограничения меняются от лабы к лабе.
После выполнения указанных шагов, ваш проект готов к генерации битстрима — двоичного файла, с помощью которого реконфигурируется ПЛИС.
Для генерации битстрима вам необходимо нажать на `Generate Bitstream` во вкладке `PROGRAM AND DEBUG` окна `Flow Navigator` (левый нижний угол окна программы).
![../.pic/Vivado%20Basics/How%20to%20program%20an%20fpga%20board/fig_1.png](../.pic/Vivado%20Basics/How%20to%20program%20an%20fpga%20board/fig_1.png)
_Рисунок 1. Расположение кнопки `Generate Bitstream`._
После нажатия на эту кнопку, нажимайте утвердительно во всех всплывающих окнах (варианты `YES`/`OK`, в зависимости от состояния вашего проекта, число появляющихся окон будет различным). После успешной генерации битстрима откроется окно `Bitstream Generation Completed`.
Остается прошить ПЛИС. Для этого подключите отладочный стенд к USB-порту компьютера и включите на стенде питание. Затем откройте окно `HARDWARE MANAGER` для этого:
1. Убедитесь, что выбран пункт `Open Hardware Manager` в окне `Bitstream` и нажмите на OK.
2. Кликните `Open target``Auto Connect``Program device``Program`.
![../.pic/Vivado%20Basics/How%20to%20program%20an%20fpga%20board/fig_2.png](../.pic/Vivado%20Basics/How%20to%20program%20an%20fpga%20board/fig_2.png)
_Рисунок 2. Последовательность действий для прошивки ПЛИС._
После этого появится окно с индикатором реконфигурации ПЛИС. Когда окно закроется, в ПЛИС окажется прототип вашего модуля.

View File

@@ -1,146 +0,0 @@
# Окно исходников проекта Vivado
Данный документ расскажет вам об одном из основных окон программы Vivado: `Sources`. Данное оно расположено в левом верхнем углу. Если вы его не видите, данное окно можно активировать через меню: `Window > Sources`. Окно состоит из следующих вкладок:
1. Hierarchy;
2. Libraries;
3. Compile Order.
В определенных ситуациях в данном окне может появиться и вкладка `IP Cores`, но в рамках данного курса она нас не интересует.
Рассмотрим первые три вкладки.
## Иерархия модулей проекта
Рассмотрим _рис. 1_.
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_01.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_01.png)
_Рисунок 1. Окно `Sources`, открытое на вкладке `Hierarchy`._
Данная вкладка состоит из четырех "папок":
1. Design Sources;
2. Constraints;
3. Simulation Sources;
4. Utility Sources.
В рамках текущего курса лабораторных работ мы будем взаимодействовать только с тремя из них.
Помните, что несмотря на использование слова "папка", речь идет не о директориях операционной системы. Папки проекта — это всего лишь удобная абстракция для управления иерархией проекта.
В папке `Design Sources` строится иерархия проектируемых модулей (реальных схем, которые в будущем могут быть воспроизведены в ПЛИС или заказной микросхеме).
Папка `Constraints` содержит файлы ограничений, помогающих реализовать проект на конкретной ПЛИС (см. ["Этапы реализации проекта в ПЛИС"](../Introduction/Implementation%20steps.md#implementation)).
`Simulation Sources` хранит в себе иерархию верификационного окружения, включая модули из папки `Design Sources` — т.е. все модули (как синтезируемые, так и не синтезируемые), которые будут использованы пр моделировании.
> Обратите внимание на то, вкладка `Hierarchy` не содержит файлов. Здесь отображается иерархия модулей проекта. Один модуль может быть использован несколько раз — и в этом случае он будет столько же раз отображён в иерархии, хотя файл, хранящий описание этого модуля останется один (см. _рис. 5_).
Допустим, мы создали модуль полного однобитного сумматора `fulladder`, а также создали модуль полного четырехбитного сумматора `fulladder4`, содержимое которого мы только планируем описать, подключив внутри него четыре однобитных сумматора.
Раскрыв папку `Design Sources` мы увидим два модуля `fulladder` и `fulladder4`, которые пока что никак друг с другом не связаны. Двойное нажатие на название модуля приведёт к открытию файла, содержащего описание этого модуля.
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_02.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_02.png)
_Рисунок 2. Содержимое папки `Design Sources`._
Модуль `fulladder4` является модулем верхнего уровня (top-level module). Это значит, что при попытке запуска моделирования или синтеза, Vivado будет работать именно с этим модулем. Чтобы сменить модуль верхнего уровня, необходимо нажать правой кнопкой мыши на интересующий модуль и выбрать `Set a top`.
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_03.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_03.png)
_Рисунок 3. Пример смены модуля верхнего уровня._
Опишем логику работы четырехбитного сумматора таким образом, чтобы тот содержал четыре однобитных сумматора. После сохранения окно изменится так:
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_04.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_04.png)
_Рисунок 4. Обновленное содержимое папки `Design Sources`._
После раскрытия ветки `fulladder4` будет отображено 4 подключенных модуля `fulladder`.
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_05.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_05.png)
_Рисунок 5. Иерархия проекта с четырьмя копиями модуля `fulladder`._
В `Simulation Sources` мы видим один файл тестбенча, к которому что-то подключено, и модуль `fulladder4` с подключенными к нему другими модулями:
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_06.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_06.png)
_Рисунок 6. Иерархия модулей `Simulation Sources`._
Модули из `Design Sources` автоматически попадают в `Simulation Sources`, так как эти модули используются при моделировании.
Помните, что здесь отображается иерархия модулей. В реальности модуль `fulladder` описан всего один раз.
Каждый раз, когда вы меняете что-то в модулях разрабатываемого устройства, это отражается как во вкладке `Design Sources`, так и в `Simulation Sources`. Раскроем вкладку с модулем `tb`:
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_07.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_07.png)
_Рисунок 7. Пример иерархии с отсутствующим модулем._
Такая картина говорит нам о попытке подключить модуль, которого нет в проекте. Часто это связано с неправильным указанием подключаемого модуля. В данном случае мы хотим подключить модуль `half_adder` и Vivado не может его найти.
```SystemVerilog
module tb();
//...
half_adder DUT(
.A (a),
.B (b),
.P (p),
.S (s)
);
// ...
endmodule
```
Переименуем название подключаемого модуля на `fulladder4` и сохраним.
```SystemVerilog
module tb();
//...
fulladder4 DUT(
.A (a),
.B (b),
.P (p),
.S (s)
);
// ...
endmodule
```
После обновления в окне `Sources` модуль `fulladder4` "спрячется" под `tb`. Если раскрыть вкладку, будет видно, что `fulladder4` подключен к `tb`, а четыре модуля `fulladder` к `fulladder4`. Также отметим, что `tb` является модулем верхнего уровня, значит, если мы захотим запустить симуляцию, то Vivado выполнит симуляцию именно для модуля `tb`. Изменить модуль верхнего уровня можно так же, как было описано ранее.
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_08.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_08.png)
_Рисунок 8. Пример исправленной иерархии верификационного окружения._
После каждого сохранения файла проекта, иерархия проекта будет какое-то время обновляться. Это можно заметить по надписи `Updating` вверху окна (см. _рис 9_). Во время обновления иерархии не стоит выполнять операции синтеза или моделирования — это приведет к ошибке.
![../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_09.png](../.pic/Vivado%20Basics/How%20to%20use%20Source%20Window/fig_09.png)
_Рисунок 9. Окно `Sources` во время обновления иерархии проекта._
Одной из частой ошибок студентов бывает прикрепление файла не к той папке. Например, создание модуля проекта в папке `Simulation Sources` (из-за чего тот не появится в папке `Design Sources`), или создание модуля верификационного окружения в папке `Design Sources` (он же наоборот — окажется и в папке `Simulation Sources`, но при этом в папке Design Sources окажется несинтезируемый модуль, который может оказаться еще и модулем верхнего уровня, что приведет к ошибке).
В случае, если произошла такая ошибка, она может быть легко исправлена нажатием правой кнопкой мыши по неправильно расположеному модулю и выбору кнопки: "Move to Design[или Simulation] sources".
## Библиотеки проекта
В данной вкладке находятся файлы проекта, сгруппированные по библиотекам. Обычно данная вкладка практически не используется.
## Порядок компиляции сущностей проекта
Обычно Vivado сам определяет порядок компиляции по иерархии проекта. Однако, в некоторых ситуациях он может определить что-то неправильно. На данной вкладке вы можете исправить порядок компиляции (скорее всего, вам может потребоваться эта вкладка, для указания порядка компиляции пакетов SystemVerilog).
## Дополнительные материалы
Более подробную информацию по окну `Sources` вы можете найти в руководстве пользователя Vivado: ["Vivado Design Suite User Guide: Using the Vivado IDE (UG893)"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide) (раздел ["Using the Sources Window"](https://docs.xilinx.com/r/en-US/ug893-vivado-ide/Using-the-Sources-Window)).

View File

@@ -6,12 +6,13 @@
Дабы сократить порог вхождения в освоение этого инструмента, был написан ряд материалов по описанию базовых сценариев использования, который представлен в данной папке.
Здесь находятся инструкции о том как:
Здесь находятся следующие документы:
1. [создать демо-проект под отладочный стенд Nexys-7](Vivado%20trainer.md);
2. [прошить ПЛИС](How%20to%20program%20an%20fpga%20board.md);
3. [взаимодействовать с окном исходников проекта Vivado](How%20to%20use%20Source%20Window.md);
4. [открыть логическую схему написанного вами модуля](How%20to%20open%20a%20schematic.md);
5. [запустить симуляцию](Run%20Simulation.md);
6. [разобраться с ошибками, при попытке открыть схему / запустить симуляцию](Elaboration%20failed.md);
7. [находить и исправлять ошибки дизайна, найденные тестовым окружением](Debug%20manual.md).
1. [Создание нового проекта под отладочный стенд Nexys A7](./01.%20New%20project.md);
2. [Навигатор по маршруту проектирования](./02.%20Flow%20Navigator.md);
3. [Менеджер проекта](./03.%20Project%20manager.md);
4. [Как запустить симуляцию в Vivado](./04.%20Simulation.md);
5. [Руководство по поиску функциональных ошибок](./05.%20Bug%20hunting.md);
6. [Анализ RTL](./06.%20RTL%20Analysis.md);
7. [Как прошить ПЛИС](./07.%20Program%20and%20debug.md);
8. [Руководство по работе с ошибками обработки кода](08.%20Code%20processing%20errors.md)

View File

@@ -1,35 +0,0 @@
# Как запустить симуляцию в Vivado
Симуляция — это один из видов моделирования. Моделирование используется чтобы проверки поведения разработанного устройства. Для этого, на входные сигналы подаются тестовые воздействия, а с выходных считывается результат. Параллельно этому процессу, те же самые тестовые воздействия отправляются и в эталонную модель устройства. Результат модели сверяют с результатом проектируемого устройства и, в случае расхождения, сигнализируют об ошибке.
Генерация тестовых воздействий, подача их на верифицируемое устройство и модель, сверка результатов и логирование ошибок — все это выполняется средствами верификационного окружения, которое в рамках данных лабораторных работ будет именоваться как "тестбенч". Тестбенчи — это несинтезируемые модули, поэтому они не должны находиться в папке `Design Sources`, вместо этого для них есть папка `Simulation Sources` (см. ["Окно исходников проекта Vivado"](./How%20to%20use%20Source%20Window.md)).
Для каждого верифицируемого модуля в репозитории есть отдельный тестбенч. Перед запуском моделирования, необходимо убедиться, что в качестве модуля верхнего уровня в папке `Simulation Sources` выбран тестбенч того модуля, который вы собираетесь верифицировать.
Есть несколько способов запустить симуляцию, рассмотрим два из них:
1. На панели слева, в разделе `SIMULATION`, нажать `Run Simulation``Run Behavioral Simulation`.
![../.pic/Vivado%20Basics/Run%20Simulation/fig_1.png](../.pic/Vivado%20Basics/Run%20Simulation/fig_1.png)
_Рисунок 1. Запуск симуляции через вкладку `SIMULATION` окна `Flow Navigator`._
2. В иерархии проекта нажать по папке `sim_1` правой кнопкой мыши, далее выбрать `Run Simulation``Run Behavioral Simulation`.
![../.pic/Vivado%20Basics/Run%20Simulation/fig_2.png](../.pic/Vivado%20Basics/Run%20Simulation/fig_2.png)
_Рисунок 2. Запуск симуляции через контекстное меню папки `sim_1` в `Simulation Sources`._
После запуска симуляции будет отмоделировано определенное количество времени, задаваемое через настройки проекта, после чего моделирование приостанавливается. Если этого времени не хватает для прохождения всех этапов симуляции (если в `Tcl Console` вы не видите сообщение о завершении моделирования), необходимо нажать кнопку `▶` (`Run all`) на панели инструментов появившегося окна `SIMULATION` (либо нажать горячую клавишу `F3`).
В случае, если вы изменили исходный код какого-то из модулей, симуляцию можно перезапустить тем же способом, которым вы запустили её в первый раз, либо нажав кнопку `Relaunch Simulation`.
В случае, не меняли исходный код, но хотите промоделировать модуль заново, вы можете воспользоваться кнопкой `Restart` (`|◀`). В этом случае, вы избежите повторной компиляции модулей.
Для закрытия симуляции вы можете кликнуть на крестик окна `SIMULATION` (бирюзовое), либо нажать правой кнопкой мыши по `SIMULATION` и выбрать `Close Simulation`.
![../.pic/Vivado%20Basics/Run%20Simulation/fig_3.png](../.pic/Vivado%20Basics/Run%20Simulation/fig_3.png)
_Рисунок 3. Закрытие симуляции через окно `Flow Navigator`._
> Если вы изменили модуль верхнего уровня в `Simulation Sources`, вам необходимо закрыть текущую симуляцию. Без этого новая не сможет запуститься и будет выдавать ошибку "boost filesystem remove: Процесс не может получить доступ к файлу".

View File

@@ -1,99 +0,0 @@
# Создание базового проекта с прошивкой ПЛИС в Vivado
## Создание проекта в Системе Автоматизированного Проектирования (САПР)
1. Запустить Vivado
2. Нажать `Create Project`
3. В открывшемся окне нажать Next
4. Ввести название проекта (никаких пробелов и кириллических символов) → Выбрать папку для проектов (создать каталок на D:/) → Поставить галку `Create project subdirectory` → Нажать `Next`
5. Выбрать RTL Project → Поставить галку `Do not specify sources at this time` → Нажать Next
6. Выставить фильтры, для сужения списка ПЛИС:
* Family: `Artix 7`
* Package: `CSG324`,
* Speed: `-1`.
<details>
<summary> Скриншот окна с выставленными фильтрами</summary>
![../.pic/Vivado%20Basics/Vivado%20trainer/fig_01.png](../.pic/Vivado%20Basics/Vivado%20trainer/fig_01.png)
</details>
1. В списке выбрать ПЛИС `xc7a100tcsg324-1` → Нажать Next
2. Нажать Finish
3. Закрыть Vivado
4. Удалить папку
5. Повторить все действия самостоятельно
## Создание модуля на SystemVerilog
1. Создать новый SystemVerilog файл, для этого в окне `Sources` нажать на кнопку `+`
2. В открывшемся окне выбрать `Add or create design source` → Нажать `Next`
3. Нажать `Create File`В открывшемся окне ввести имя модуля `top` и выбрать тип файла SystemVerilog → Нажать `OK`В оставшемся окне нажать `Finish`
4. В открывшемся окне НЕ вводить названия портов и сразу нажать OK → После чего подтвердить выбор `Yes`
5. Двойным кликов в окне `Source` открыть файл `top.sv`
6. Написать следующий код:
```SystemVerilog
module top (
input logic clk,
input logic a,
input logic b,
output logic q
);
logic c;
assign c = a ^ b;
always_ff @(posedge clk) begin
q <= c;
end
endmodule
```
7. Сохранить изменения
8. Нажать `Open Elaborated Design`
9. Нажать `Schematic` в открывшемся списке
10. Проанализировать полученный результат (сопоставить с SystemVerilog-описанием)
11. Закрыть проект
## Реализация простого проекта на отладочном стенде
1. Создать новый проект
2. Создать новый SystemVerilog файл с названием `basic`
3. Написать следующий код:
```SystemVerilog
module basic (
input logic [15:0] SW,
output logic [15:0] LED
);
assign LED[0] = SW[0] & SW[1];
assign LED[2] = SW[2] | SW[3];
assign LED[4] = SW[4] ^ SW[5];
assign LED[10:6] = ~SW[10:6];
assign LED[13:11] = {SW[11], SW[12], SW[13]};
assign LED[15:14] = { 2{SW[14]} };
endmodule
```
4. Сохранить изменения
5. В окне Sources нажать на кнопку `+`
6. В открывшемся окне выбрать `Add or create constraints` → Нажать Next
7. Нажать `Create File`В открывшемся окне ввести название → Нажать `OK``Finish`
8. В окне `Source` в открывающемся списке `Constraints` найти только что созданный файл и открыть его для редактирования двойным щелчком
9. Скопировать содержимое файла констрейнов с [официального сайта](https://github.com/Digilent/digilent-xdc) и вставить в только что созданный → Найти строки посвященные SW и LED и раскомментировать их → Сохранить изменения
10. `Run Synthesis`
11. `Run Implementation`
12. После успешной имплементации нажимаем `Generate Bitstream` для генерации файла прошивки
13. Аккуратно достаем и подключаем стенд к компьютеру → Включаем питание на плате
14. Нажимаем `Open Hardware Manager` (под `Generate Bitstream`)
15. Вместо окна `Source` будет отображаться окно `Hardware`, в нем необходимо нажать кнопку `Auto Connect` (единственная активная кнопка) → В окне появится подключенное устройство
16. Нажать правой кнопкой на устройстве `xc7a100t_0` → Выбрать пункт меню `Program Device`
17. В открывшемся окне нажать `Program`
18. Сопоставить поведение отладочной платы с SystemVerilog-описанием

View 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`.

View File

@@ -0,0 +1,18 @@
/* -----------------------------------------------------------------------------
* Project Name : Architectures of Processor Systems (APS) lab work
* Organization : National Research University of Electronic Technology (MIET)
* Department : Institute of Microdevices and Control Systems
* Author(s) : Andrei Solodovnikov
* Email(s) : hepoh@org.miet.ru
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
* ------------------------------------------------------------------------------
*/
module half_divider(
input logic [31:0] numerator,
output logic [31:0] quotient
);
assign quotient = numerator << 1'b1;
endmodule

View File

@@ -0,0 +1,29 @@
/* -----------------------------------------------------------------------------
* Project Name : Architectures of Processor Systems (APS) lab work
* Organization : National Research University of Electronic Technology (MIET)
* Department : Institute of Microdevices and Control Systems
* Author(s) : Andrei Solodovnikov
* Email(s) : hepoh@org.miet.ru
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
* ------------------------------------------------------------------------------
*/
module max_min(
input logic [31:0] a,
input logic [31:0] b,
output logic [31:0] max,
output logic [ 3:0] min
);
always_comb begin
if(a > b) begin
max = a;
min = b;
end
else begin
max = b;
min = b;
end
end
endmodule

View File

@@ -0,0 +1,68 @@
/* -----------------------------------------------------------------------------
* Project Name : Architectures of Processor Systems (APS) lab work
* Organization : National Research University of Electronic Technology (MIET)
* Department : Institute of Microdevices and Control Systems
* Author(s) : Andrei Solodovnikov
* Email(s) : hepoh@org.miet.ru
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
* ------------------------------------------------------------------------------
*/
module tb_vector_abs();
logic [31:0] a;
logic [31:0] b;
logic [31:0] res;
vector_abs dut(
.x(a),
.y(b),
.abs(res)
);
integer err_count = 0;
task check_result(input logic [31:0]a, b, res);
begin : check_result
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;
check_result(a,b,res);
a = 1; b = 1;
#5;
check_result(a,b,res);
a = 3; b = 4;
#5;
check_result(a,b,res);
for(i = 0; i < 100; i=i+1) begin
a = $random()&32'hff; b = $random()&32'hff;
#5;
check_result(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

View File

@@ -0,0 +1,35 @@
/* -----------------------------------------------------------------------------
* Project Name : Architectures of Processor Systems (APS) lab work
* Organization : National Research University of Electronic Technology (MIET)
* Department : Institute of Microdevices and Control Systems
* Author(s) : Andrei Solodovnikov
* Email(s) : hepoh@org.miet.ru
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
* ------------------------------------------------------------------------------
*/
module vector_abs(
input logic [31:0] x,
input logic [31:0] y,
output logic [31:0] abs
);
logic [31:0] min;
logic [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