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

7.6 KiB
Raw Permalink Blame History

Список типичных ошибок в 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.

../.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-консоли появится сообщение об использовании необъявленного идентификатора:

INFO: [Synth 8-11241] undeclared symbol 'ab', assumed default net type 'wire'

Объявление выхода модуля его входом

Очень часто в попытке сэкономить себе немного времени студенты выполняют операцию копирования. В частности, копирования строк вида input logic [7:0] в процессе описания портов модуля. В случае, если по итогу подобного копирования, выход модуля будет объявлен как его вход (т.е. с помощью ключевого слова input вместо output).