Пример моделирования схемы

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