Пример моделирования схемы
Verilog позволяет создать модель схемы (design) и тестовое окружение (testbench), в котором можно проверить корректность работы разработанной схемы.
Рассмотрим пример схемы, приведённой на рисунке ниже.

Синим подписаны элементы схемы, черным – провода. Вместо выходного контакта, на котором можно наблюдать итоговое значение, в Verilog используется системная функция $display
, которая выводит результат в консоль.
Приведённую схему можно описать на языке Verilog как:
module mux(output logic out, input logic a, s, b);
or #2 or_res(out, w_and_a, w_and_b);
and #2 and_a(w_and_a, a, n_s),
and_b(w_and_b, b, s);
not ns(n_s, s);
endmodule
В этом примере были инстанцированы логические элементы and
и or
, которые соединили между собой проводами. #
означает временную задержку исполнения.
Порядок описания компонентов модуля не важен, поэтому следующие объявления модуля эквивалентны предыдущему:
module mux_v1(output logic out, input logic a, s, b);
not ns(n_s, s);
and #2 and_a(w_and_a, a, n_s),
and_b(w_and_b, b, s);
or #2 or_res(out, w_and_a, w_and_b);
endmodule
module mux_v2(output logic out, input logic a, s, b);
and #2 and_a(w_and_a, a, n_s),
and_b(w_and_b, b, s);
not ns(n_s, s);
or #2 or_res(out, w_and_a, w_and_b);
endmodule
Важно отметить, что в модели схемы не описывается, какие значения будут на входах. Это делается в модели тестового окружения или в других модулях, которые будут инстанцировать этот.
Схемы можно описывать на основе структурного или поведенческого подходов:
module mux_v3(output logic out, input logic a, s, b);
assign #4 out = s ? b : a;
endmodule
module mux_v4(output logic out, input logic a, s, b);
or #4 or_res(out, (a & !s) | (b & s));
endmodule
module mux_v5(output logic out, input logic a, s, b);
always @(*) begin
case(s)
0 : out = #4 a;
1 : out = #4 b;
default : out = #4 a;
endcase
end
endmodule
Пример тестового окружения для проверки работоспособности и корректности модуля:
Пример
module mux_tb;
string display_format = "[%2t] %d %d %d %d";
event display_states;
logic a, sel, b, y;
mux _mux(y, a, sel, b);
initial begin
$display("time a sel b y");
a = 0; b = 0; sel = 0;
#10; a = 1; b = 0; sel = 1;
#10; a = 1; b = 1; sel = 1;
#10; a = 0; b = 1; sel = 1;
#10; a = 0; b = 1; sel = 0;
#10; a = 0; b = 0; sel = 0;
#10; $finish;
end
always @(display_states) $display(display_format, $time, a, sel, b, y);
initial begin
#3; ->display_states;
#1; ->display_states;
#1; ->display_states;
#10; ->display_states;
#10; ->display_states;
#10; ->display_states;
#10; ->display_states;
#10; ->display_states;
#10;
end
endmodule
Результат исполнения
time a sel b y
[ 3] 0 0 0 x
[ 4] 0 0 0 0
[ 5] 0 0 0 0
[15] 1 1 0 0
[25] 1 1 1 1
[35] 0 1 1 1
[45] 0 0 1 0
[55] 0 0 0 0
Можно заметить, что в первой строке y имеет неопределённое состояние, т.к. присвоение значения в результате исполнения мультиплексора, которое занимает 4 такта, ещё не произошло. Начиная со следующей строки, сигнал успел распространиться до выхода подсхемы и при выводе на экран выводится корректное значение.
Last updated