Files
APS/Basic Verilog structures/Common mistakes.md
Andrei Solodovnikov 9739429d6e Синхронизация с правками публикуемого издания (#101)
* СП. Обновление предисловия

* СП. Обновление введения

* СП. Обновление лаб

* СП. Обновление доп материалов

* СП. Введение

* СП. Введение

* СП. ЛР№4, 15

* СП. Базовые конструкции Verilog

* Update Implementation steps.md

* СП. ЛР 4,5,7,8,14

* СП. ЛР№8

* Синхронизация правок

* СП. Финал

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

* Обновление схемы

* Синхронизация правок

* Добавление белого фона .drawio-изображениям

* ЛР2. Исправление нумерации рисунка
2025-02-12 17:53:52 +03:00

104 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Список типичных ошибок в 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_.
![../.pic/Basic%20Verilog%20structures/common%20mistakes/figure_01.png](../.pic/Basic%20Verilog%20structures/common%20mistakes/figure_01.png)
Как вы можете увидеть, код был успешно собрался и был промоделирован, но значения в выделенных синим прямоугольниках не те, что должны были быть. Можно заметить также и то, что значение выхода `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`).
##