* СП. Обновление предисловия * СП. Обновление введения * СП. Обновление лаб * СП. Обновление доп материалов * СП. Введение * СП. Введение * СП. ЛР№4, 15 * СП. Базовые конструкции Verilog * Update Implementation steps.md * СП. ЛР 4,5,7,8,14 * СП. ЛР№8 * Синхронизация правок * СП. Финал * Исправление ссылки на рисунок * Обновление схемы * Синхронизация правок * Добавление белого фона .drawio-изображениям * ЛР2. Исправление нумерации рисунка
7.6 KiB
Список типичных ошибок в SystemVerilog
имя сигнала is not a type
Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков always
и initial
можно выполнять только непрерывное присваивание (через assign
).
module half_adder(input logic a, input logic b, output logic c);
c = a ^ b; // ошибка, для непрерывного присваивания
// необходимо ключевое слово assign
endmodule
Листинг 1. Пример ошибочного присваивания.
cannot find port on this module
Имя порта, указанного при подключении модуля (после точки) не соответствует ни одному имени сигналов подключаемого модуля
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.
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-консоли появится сообщение об использовании необъявленного идентификатора:
INFO: [Synth 8-11241] undeclared symbol 'ab', assumed default net type 'wire'
Объявление выхода модуля его входом
Очень часто в попытке сэкономить себе немного времени студенты выполняют операцию копирования. В частности, копирования строк вида input logic [7:0]
в процессе описания портов модуля. В случае, если по итогу подобного копирования, выход модуля будет объявлен как его вход (т.е. с помощью ключевого слова input
вместо output
).