始终按顺序分配 Verilog

Verilog assignments in a sequential always

我知道我应该在顺序总是分配中使用非阻塞分配。但是,我不小心在我的部分代码中使用了阻塞赋值,这里是:

reg tb_strobe = 0;
reg [9:0] tb_strobe_cnt = 0;
reg tb_sync = 0;

always@(posedge tb_clkh)
begin
    if (~tb_resetl) begin
        tb_strobe     <= 0;
        tb_strobe_cnt <= 0;
        tb_sync     <= 0;
    end
    else begin

        if (tb_strobe_cnt == 1022) begin
            tb_strobe <= 1;
            tb_strobe_cnt <= tb_strobe_cnt + 1;
        end else if (tb_strobe_cnt == 1023) begin
            tb_strobe <= 0;
            tb_strobe_cnt <= 0;
        end else begin
            tb_strobe <= 0;
            tb_strobe_cnt <= tb_strobe_cnt + 1;
        end

        if (tb_strobe == 1) begin
            tb_sync = 1;             //  <-- this is the mistakenly used blocking assignment
        end else begin
        end

    end
end

然后我的模拟器出现了不可预测的行为,一旦我将该分配修复为非阻塞分配,它就开始正常工作了!!!!

我很好奇上面(在我的特定代码中)有什么问题? 在我使用它的方式中,因为我只在我的代码中调用 tb_sync 一次,所以我没有预料到任何不可预测的行为...... 并且 tb_sync 没有在代码中的其他任何地方分配。知道哪里出了问题吗?

非阻塞赋值用于防止在同一时钟沿写入和读取同一变量的多个进程之间的竞争条件。只需一个进程写入,另一个进程在同一时钟边沿读取同一变量即可创建该竞争。您的示例没有显示读取 tb_sync 的过程,但我假设这就是比赛所在。