mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 17:20:10 +00:00
* СП. Обновление предисловия * СП. Обновление введения * СП. Обновление лаб * СП. Обновление доп материалов * СП. Введение * СП. Введение * СП. ЛР№4, 15 * СП. Базовые конструкции Verilog * Update Implementation steps.md * СП. ЛР 4,5,7,8,14 * СП. ЛР№8 * Синхронизация правок * СП. Финал * Исправление ссылки на рисунок * Обновление схемы * Синхронизация правок * Добавление белого фона .drawio-изображениям * ЛР2. Исправление нумерации рисунка
104 lines
7.6 KiB
Markdown
104 lines
7.6 KiB
Markdown
# Список типичных ошибок в 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`, мы увидим, что он почему-то 1-битный. Более того, если раскомментировать строчку с объявлением сигнала `ab`, результат никак не изменится.
|
||
|
||
Подобное поведение в точности воспроизводит требование стандарта SystemVerilog [1, стр. 108]:
|
||
|
||
> - Если идентификатор использовался списке сигналов, подключаемых к модулю, и этот идентификатор не был объявлен в области видимости, которая доступна при этом подключении, то неявно подразумевается 1-битный провод.
|
||
> - Если идентификатор встречается по левую сторону от оператора непрерывного присваивания, и этот идентификатор не был объявлен в той области видимости, которая доступна оператору, то неявно подразумевается 1-битный провод.
|
||
|
||
Иными словами, если вы присваиваете значение необъявленному сигналу, или пытаетесь подключить необъявленный сигнал к модулю, неявно создается 1-битный сигнал с тем же именем (попробуйте удалить объявление сигналов `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`).
|
||
|
||
## |