循环中非阻塞语句之前和之后的延迟有什么不同?

时间:2011-09-06 03:35:39

标签: verilog

这两段代码片段有什么区别?

    always @(posedge clk) begin
            r3 <= @(posedge clk) 1;
            r2 <= @(posedge clk) 1;
            ready = 0;
            while (r2 <= n) begin
                r2 <= @(posedge clk) r2 + 1;     <--- never stops executing
            end
    end


    always @(posedge clk) begin
            r3 <= @(posedge clk) 1;
            r2 <= @(posedge clk) 1;
            ready = 0;
            while (r2 <= n) begin
                @(posedge clk) r2 <= r2 + 1;     <--- normally executes
            end
    end

1 个答案:

答案 0 :(得分:3)

当模拟器执行r2 <= @(posedge clk) r2 + 1时,它执行以下步骤:

  • 评估r2 + 1
  • 安排在下一个posedge clk
  • 执行的非阻塞作业(NBA)更新事件

当模拟器执行@(posedge clk) r2 <= r2 + 1时,它执行以下步骤:

  • 暂停always进程并安排在下一个posedge clk恢复
  • 当该过程恢复时,执行r2 <= r2 + 1 NBA,执行以下操作:
    • 评估r2 + 1
    • 安排当前的NBA更新活动

第一个表单解析为非阻塞赋值,并在零时间内执行。延迟仅适用于NBA执行时生成的更新事件。第二种形式解析为延迟控制,然后是NBA。它不会在零时间内执行,因为延迟适用于语句的执行而不仅仅是更新事件。

第一种形式是无限循环,因为while循环的主体在零时间内执行,而将增加r2的事件将在未来安排。

使用第二种形式时,您仍然需要在循环终止时注意边界条件。在安排将r2设置为n + 1的更新后,该条件将在应用更新之前再次评估为true。