# Список типичных ошибок в 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`, мы увидим, что он почему-то однобитный. Более того, если раскомментировать строчку с объявлением сигнала `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`). ##