3 / 37 · Теория
Модули, порты и экземпляры: соединения как контракты
Соединяйте комбинационные модули по именам портов и проверяйте единственный источник и границы иерархии.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
Граница модуля не является границей такта
Модуль объединяет порты и логику. Экземпляр не создаёт автоматически регистр или цикл. Последовательное соединение комбинационных модулей остаётся комбинационным путём с суммарной физической задержкой. Явный регистр создаёт границу хранения. Документируйте направление, разрядность, знак, источник и достоверность; именованные соединения не зависят от порядка портов.
module select_word #(parameter integer W = 8) (
input logic [W-1:0] a, b,
input logic select_b,
output logic [W-1:0] y
);
assign y = select_b ? b : a;
endmodule
module choose_and_increment (
input logic [7:0] a, b,
input logic select_b,
output logic [8:0] result
);
logic [7:0] chosen;
select_word #(.W(8)) select_u (
.a(a), .b(b), .select_b(select_b), .y(chosen)
);
assign result = {1'b0, chosen} + 9'd1;
endmoduleselect_word — тип модуля, select_u — имя экземпляра. .a(a) соединяет порт a дочернего модуля с сигналом a родительского. .W(8) задаётся при elaboration, а не является динамическим входом.
Проверяйте оба конца
chosen имеет единственный источник y дочернего модуля и читается родителем. Не присваивайте ему значение ещё в другом процессе; logic не разрешает конфликт источников. result содержит девять бит для 255+1=256: chosen расширяется до сложения. a=255, b=9, select_b=0 даёт 256; select_b=1 даёт 10. Восемь бит потеряли бы перенос в первом случае.
Иерархия, файлы и верхний модуль
Определения могут быть вместе или раздельно, но компилятору нужны оба. Верхний модуль — choose_and_increment; выбор select_word изменяет проверяемую границу. Отсутствие файла дочернего модуля относится к списку исходников, а не доказывает ошибку логики. Позиционные связи могут измениться при редактировании портов. Неподключённый вход не является намеренным нулём: подключите константы либо опишите неиспользуемые выходы и рассмотрите диагностику. Отслеживайте зависимости против комбинационной обратной связи без памяти; модуль её не разрывает.
Практика: проверяйте композицию независимо
Для (a, b, select_b)=(0,255,0),(0,255,1),(255,0,0),(255,0,1) ожидайте 1,256,256,1. Переберите 256 выбранных значений для обоих select, задав другой вход отличающимся для выявления инверсии выбора. Эталон выбирает целое a или b и добавляет 1; сравнивайте после установления. Чтение внутреннего chosen могло бы разделять ошибку выбора. Затем добавьте выходной регистр и задайте сброс, достоверность и соответствующий входной фронт: временной контракт меняется даже при той же арифметике.