Почему блокирующие и неблокирующие задания не ведут себя одинаково в среде тестирования?

#verilog #test-bench

Вопрос:

Я пишу модуль D-триггера, как показано ниже:

 module mod1(
    input clk,
    input d,
    output reg q
);

    always @(posedge clk)begin
        q <= d;
    end

endmodule
 

Это два фрагмента кода, которые я использовал для тестирования своего модуля mod1

 // code 1
module mod1_tb;
    reg clk;
    reg d;
    wire q;
    
    mod1 dut(
        .clk(clk),
        .d(d),
        .q(q)
    );
    
    always #10 clk = ~clk;
    
    initial begin
        clk = 0;

        @(posedge clk)
            d <= 0;
        @(posedge clk)
            d <= 1;
        @(posedge clk)
            d <= 0;
        @(posedge clk)
            d <= 1;
    
    end

endmodule

 

Форму волны можно увидеть следующим образом:
форма волны 1

 // code 2
module mod1_tb;
    reg clk;
    reg d;
    wire q;
    
    mod1 dut(
        .clk(clk),
        .d(d),
        .q(q)
    );
    
    always #10 clk = ~clk;
    
    initial begin
        clk = 0;
        
        @(posedge clk);
        d = 0;
        @(posedge clk);
        d = 1;
        @(posedge clk);
        d = 0;
        @(posedge clk);
        d = 1;
    
    end

endmodule
 

Форму волны можно увидеть следующим образом:
испытательный стенд2

На мой взгляд, все они должны хорошо работать, но результат показывает, что работает только первый способ. Я немного смущен тем, почему второй вариант не работает.

Ответ №1:

Предполагается, что ваш входной сигнал ( d ) синхронен с часами. Вы должны управлять этим сигналом в своем тестовом стенде аналогично тому, как он управляется в дизайне. Используйте @(posedge clk) , как вы уже делаете, и используйте неблокирующие назначения ( <= ) вместо блокировки ( = ).

Ваш code 1 компьютер правильно использует неблокирующуюся среду в тестовом стенде, поэтому он имитирует так, как вы ожидаете.

Вы code 2 используете блокировку в тестовой среде, поэтому она не имитируется должным образом.

Неблокирующее назначение гарантирует, что симулятор выполнит выборку синхронного ввода в то время, когда вы этого ожидаете.

Рекомендуемая надлежащая практика кодирования заключается в использовании неблокирующего для последовательной логики, такой как триггеры.


Существует множество литературы, в которой обсуждаются детали планирования событий Verilog. Вот одна статья.