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
104
Basic Verilog structures/Common mistakes.md
Normal file
104
Basic Verilog structures/Common mistakes.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Список типичных ошибок в SystemVerilog
|
||||
|
||||
- [Список типичных ошибок в SystemVerilog](#список-типичных-ошибок-в-systemverilog)
|
||||
- [имя сигнала is not a type](#имя-сигнала-is-not-a-type)
|
||||
- [cannot find port on this module](#cannot-find-port-on-this-module)
|
||||
- [Использование сигнала без его объявления (или до его объявления)](#использование-сигнала-без-его-объявления-или-до-его-объявления)
|
||||
- [Объявление выхода модуля его входом](#объявление-выхода-модуля-его-входом)
|
||||
- [](#)
|
||||
|
||||
## имя сигнала is not a type
|
||||
|
||||
Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков `always` и `initial` можно выполнять только непрерывное присваивание (через `assign`).
|
||||
|
||||
```Verilog
|
||||
module half_adder(input logic a, input logic b, output logic c);
|
||||
c = a ^ b; // ошибка, для непрерывного присваивания
|
||||
// необходимо ключевое слово assign
|
||||
endmodule
|
||||
```
|
||||
|
||||
_Листинг 1. Пример ошибочного присваивания._
|
||||
|
||||
## cannot find port on this module
|
||||
|
||||
Имя порта, указанного при подключении модуля (после точки) не соответствует ни одному имени сигналов подключаемого модуля
|
||||
|
||||
```Verilog
|
||||
module half_adder(input logic a, input logic b, output logic c);
|
||||
assign c = a ^ b;
|
||||
endmodule
|
||||
|
||||
module testbench();
|
||||
logic A, B, C;
|
||||
|
||||
adder DUT(
|
||||
.A(A), // <- здесь будет ошибка,
|
||||
// т.к. в модуле half_adder нет порта 'A'
|
||||
.b(B),
|
||||
.c(C)
|
||||
);
|
||||
endmodule
|
||||
```
|
||||
|
||||
_Листинг 2. Пример создание экземпляра модуля с ошибкой в описании его входных портов._
|
||||
|
||||
## Использование сигнала без его объявления (или до его объявления)
|
||||
|
||||
Достаточно частая ошибка, когда сигнал забывают объявить, либо объявляют, но потом добавляют код с использованием этого сигнала выше его объявления. Не смотря на то, что в SystemVerilog не важно, в каком порядке были описаны блоки кода, это не касается объявления сигналов — они должны выполняться до их использования. Рассмотрим следующий пример, приведенный в _листинге 3_.
|
||||
|
||||
```Verilog
|
||||
module example(
|
||||
input logic [1:0] a,
|
||||
input logic [1:0] b,
|
||||
output logic [1:0] c
|
||||
);
|
||||
|
||||
assign ab = a | b;
|
||||
// logic [1:0] ab;
|
||||
assign c = ab;
|
||||
endmodule
|
||||
|
||||
module tb_example();
|
||||
logic [1:0] a, b, c;
|
||||
logic [3:0] i = 0;
|
||||
example DUT(.a(a),.b(b),.c(c));
|
||||
assign {a, b} = i;
|
||||
|
||||
initial repeat(15) begin
|
||||
#5;
|
||||
i++;
|
||||
end
|
||||
endmodule
|
||||
```
|
||||
|
||||
_Литсинг 3. Пример присваивания значения сигналу без его объявления._
|
||||
|
||||
Результат моделирования _листинга 3_ приведён на _рисунке 1_.
|
||||
|
||||

|
||||
|
||||
Как вы можете увидеть, код был успешно собрался и был промоделирован, но значения в выделенных синим прямоугольниках не те, что должны были быть. Можно заметить также и то, что значение выхода `c` никогда не превышает единицу.
|
||||
|
||||
Если мы начнем разбираться, и решим вытащить на временную диаграмму внутренний сигнал модуля `ab`, мы увидим, что он почему-то однобитный. Более того, если раскомментировать строчку с объявлением сигнала `ab`, результат никак не изменится.
|
||||
|
||||
Подобное поведение в точности воспроизводит требование стандарта SystemVerilog [1, стр. 108]:
|
||||
|
||||
> - Если идентификатор использовался списке сигналов, подключаемых к модулю, и этот идентификатор не был объявлен в области видимости, которая доступна при этом подключении, то неявно подразумевается однобитный провод.
|
||||
> - Если идентификатор встречается по левую сторону от оператора непрерывного присваивания, и этот идентификатор не был объявлен в той области видимости, которая доступна оператору, то неявно подразумевается однобитный провод.
|
||||
|
||||
Иными словами, если вы присваиваете значение необъявленному сигналу, или пытаетесь подключить необъявленный сигнал к модулю, неявно создается однобитный сигнал с тем же именем (попробуйте удалить объявление сигналов `a`, `b`, `c` в тестбенче _листинга 3_ и посмотрите, как изменится разрядность сигналов тестбенча на временной диаграмме).
|
||||
|
||||
Даже если объявите сигнал с правильной разрядностью после его использования — это уже ничему не поможет, поскольку повторные объявления уже объявленных проводов и регистров стандартом запрещены [1, стр. 91] и в зависимости от САПР будут либо проигнорированы, либо вызовут ошибку.
|
||||
|
||||
Подобная ошибка легко обнаруживается линтером (появился в Vivado начиная с версии 2023.1). Кроме того, при попытке открыть схематик описанной схемы, в TCL-консоли появится сообщение об использовании необъявленного идентификатора:
|
||||
|
||||
```text
|
||||
INFO: [Synth 8-11241] undeclared symbol 'ab', assumed default net type 'wire'
|
||||
```
|
||||
|
||||
## Объявление выхода модуля его входом
|
||||
|
||||
Очень часто в попытке сэкономить себе немного времени студенты выполняют операцию копирования. В частности, копирования строк вида `input logic [7:0]` в процессе описания портов модуля. В случае, если по итогу подобного копирования, выход модуля будет объявлен как его вход (т.е. с помощью ключевого слова `input` вместо `output`).
|
||||
|
||||
##
|
Reference in New Issue
Block a user