mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 17:20:10 +00:00
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:
committed by
GitHub
parent
78bb01ef95
commit
a28002e681
351
Vivado Basics/03. Project manager.md
Normal file
351
Vivado Basics/03. Project manager.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# Менеджер проекта (Project Manager)
|
||||
|
||||
Окно Project Manager позволяет управлять проектом: добавлять и редактировать исходные коды проекта, изучить краткое ревью по утилизации ресурсов ПЛИС, используемых для реализации проекта, просматривать логи и сообщения о результатах сборки проекта и многое другое.
|
||||
|
||||
В первую очередь нас интересует окно исходных кодов проекта, которое называется `Design Sources` и представлено на _рис. 1_.
|
||||
|
||||
## Окно Design Sources
|
||||
|
||||
Данное окно находится по умолчанию в верхнем левом углу окна Project Manager (в случае, если вы случайно закрыли это окно, вы можете вернуть его обратно через меню `Windows->Sources`).
|
||||
|
||||

|
||||
|
||||
_Рисунок 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`).
|
||||
|
||||

|
||||
|
||||
_Рисунок 2. Первая страница окна добавления исходников._
|
||||
|
||||
В первую очередь мы хотим описать какую-нибудь простую схему, поэтому необходимо убедиться, что активным выбран пункт `Design Sources`. Выбрав, нажимаем `Next`.
|
||||
|
||||
Появится страница, представленная на _рис. 3_, которая предлагает три варианта добавления исходников.
|
||||
|
||||
1. добавить существующий файл;
|
||||
2. добавить все имеющиеся файлы в заданной директории;
|
||||
3. создать новый файл.
|
||||
|
||||

|
||||
|
||||
_Рисунок 3. Вторая страница окна добавления исходников._
|
||||
|
||||
Создадим новый файл, нажав на соответствующую кнопку окна. Появится всплывающее окно, предлагающее выбрать тип файла и его имя (см. _рис. 4_). В поле `File Type` выберите `SystemVerilog` (этот тип будет использоваться в качестве основного на протяжении всего курса кроме случаев, когда будет сказано иное). В поле `File Name` задайте имя новому файлу (в рамках примера, имя файла будет `max_min`). Указывать расширение файла не нужно — САПР автоматически его добавит в зависимости от выбранного типа файла. Когда всё будет готово, нажмите на `OK`. После того, как были добавлены (или созданы) все необходимые источники, можно нажать кнопку `Finish` в окне `Add Sources`.
|
||||
|
||||

|
||||
|
||||
_Рисунок 4. Окно создания нового файла._
|
||||
|
||||
В случае, если создавался новый файл, после нажатия на кнопку `Finish` появится окно, предлагающее автоматически создать прототип модуля, указав в графическом интерфейсе направление и разрядность его портов (см. _рис. 5_). В рамках данного примера, откажемся от данного предложения, нажав кнопки `Cancel->Yes`.
|
||||
|
||||

|
||||
|
||||
_Рисунок 5. Окно описания входов и выходов модуля._
|
||||
|
||||
После добавления файлов с исходными кодами, Vivado автоматически начнет обновлять иерархию проекта. Вы можете заметить это по появившейся надписи `Updating` с анимацией крутящейся стрелки, показанной на _рис. 6_.
|
||||
|
||||

|
||||
|
||||
_Рисунок 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_.
|
||||
|
||||

|
||||
|
||||
_Рисунок 7. Иерархия проекта, представленная в свёрнутом виде._
|
||||
|
||||
Нажав на стрелку слева от модуля `vector_abs`, иерархия развернётся (_рис. 8_).
|
||||
|
||||

|
||||
|
||||
_Рисунок 8. Иерархия проекта, представленная в развёрнутом виде._
|
||||
|
||||
Обратите внимание на то, что модуль `vector_abs` выделен жирным относительно других модулей. Такое выделение означает, что данный модуль выбран в качестве **модуля верхнего уровня** (**top-level module**). Это означает, это данный модуль и представляет итоговую схему, которую мы проектируем, и что другие подпрограммы во `Flow Navigator`, такие как `RTL ANALYSIS`, `SYNTHESIS`, `IMPLEMENTATION` и `PROGRAM AND DEBUG` будут обрабатывать именно этот модуль. Если вдруг вы захотите работать с другим модулем (например, с модулем, `half_divider`) — его необходимо пометить вручную в качестве модуля верхнего уровня. Для этого необходимо нажать по нему правой кнопкой мыши, и в выпадающем меню выбрать `Set as Top` (см. _рис. 9_).
|
||||
|
||||

|
||||
|
||||
_Рисунок 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_).
|
||||
|
||||

|
||||
|
||||
_Рисунок 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_.
|
||||
|
||||

|
||||
|
||||
_Рисунок 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)).
|
Reference in New Issue
Block a user