verilog 什么时候使用当前时隙的值,什么时候使用前一个时隙的值?

When does verilog use values from the current and when from the previous timeslot?

这是一个简短的示例代码,让我感到困惑。在 verilog 过程中使用当前或上一个模拟时隙的值的规则是什么?

module test();

    reg clk, rst, r1, r2, r3;

    initial begin
        clk = 0;
        rst = 0;
        r1 = 0;
        r2 = 0;
        r3 = 0;

        @(posedge clk)
        rst = 1;
    end // initial

    always #5 begin : clkgen
        clk = ~clk;
    end


    /** TESTS **/

    // PREVIOUS
    always @(posedge clk) begin : proc_non_block
        r1 = rst;
    end

    // CURRENT
    always @(posedge clk or posedge rst) begin : proc_async
        r2 <= rst;
    end

    // PREVIOUS
    always @(posedge clk or negedge rst) begin : proc_async_neg
        r3 <= rst;
    end

endmodule // test

这是模拟的结果。 (Questasim 10.4C)

上面的实验告诉我,只有当给定信号在当前模拟时隙有活动事件时,才会使用给定信号的当前值。我对吗?有详细信息吗?

Verilog 总是 使用变量的当前值。此问题是在进行分配时更新当前值。由于您在 clkposedge 上解除阻塞的进程中使用阻塞赋值写入 rst,因此存在与其他也在 posedge 上解除阻塞的块的竞争条件时钟。没有定义每个 always 进程解除阻塞相对于 Initial 进程解除阻塞的顺序,因为分配尚未发生。

一般规则是:每当一个进程写入时,对变量使用非阻塞赋值,而另一个进程读取同一个变量,并且所有进程都同步到同一个时钟事件。