【问题标题】:How to understand the blocking and non blocking statements in verilog?如何理解verilog中的阻塞和非阻塞语句?
【发布时间】:2020-05-18 01:07:47
【问题描述】:

我了解 Verilog 中阻塞和非阻塞语句的基本区别。但是我仍然无法理解 & 何时何地使用阻塞和非阻塞语句发生了什么。例如,考虑简单的 d ff 代码:

module dff (clk, reset,d, q, qb);
input      clk;
input      reset;
input      d;
output     q;
output     qb;

reg        q;

assign qb = ~q;

always @(posedge clk or posedge reset)
begin
  if (reset) begin
    // Asynchronous reset when reset goes high
    q <= 1'b0;
  end else begin
    // Assign D to Q on positive clock edge
    q <= d;
  end
end
endmodule

但如果我使用两段编码技术编写完全相同的逻辑:

module dff(input wire d,
           clk,
           reset,
           en,
           output wire q);

reg q;
reg r_reg, r_next;

always @(posedge clk, posedge reset)
if(reset) 
  r_reg<=1'b0;
else
  r_reg<=r_next;

always @*
  if(en)
    r_reg=d;
  else
    r_reg=r_next;

assign q<=r_reg;
endmodule

现在,在这段代码中,我只是不明白为什么在第一个 always 块中使用 &lt;= 以及为什么在第二个 always 块中使用 =。我也知道在组合逻辑电路中= 建议使用&amp; 顺序&lt;= 建议使用。但是,我仍然无法找到使用阻塞和非阻塞语句的答案。你能帮帮我吗!?

【问题讨论】:

  • 您的第二个示例不代表相同的逻辑 - 它具有第一个示例没有的 en 输入。它在语法上也不正确。请解决这个问题,您可能会更清楚,或者如果没有,有人可以回答这个问题。

标签: verilog system-verilog hdl vlsi


【解决方案1】:

阻塞/非阻塞分配只是一个模拟工件。与相信相反,verilog 没有描述硬件。 Verilog 描述了硬件的期望行为,试图将其融入事件驱动的模拟方案。

这是一个使用 2 个触发器的移位寄存器的简单示例:

    always @(posedge clk)
        out1 = in;
    always @(posedge clk)
        out2 = out1;

现在,out2 的输出是什么?由于我们正在处理模拟,因此它取决于执行这两个语句的顺序。要么是 out1 的旧值,要么是新值(实际上是 in 的值);

在硬件方面没有这样的混乱。它将翻转在 posedge 时间存在的值,即 out1 的 old 值(好吧,除非时钟出现异常延迟)。

为了匹配这种行为,引入了非阻塞赋值。 Verilog 模拟是在模拟滴答中完成的。只要有可能导致重新评估其他块的事件,每个滴答声都是如此。非阻塞分配被调度为在当前 rhs 值的这种滴答结束时执行(实际上有几个调度区域)。因此,请考虑以下事项:

    always @(posedge clk)
        out1 <= in;
    always @(posedge clk)
        out2 <= out1;

在上面的示例中,所有分配都将发生在滴答声的末尾。 'out2' 将被分配一个在

因此,顶级建议是对组合逻辑使用阻塞分配 (=),对状态设备、触发器和锁存器的所有输出使用非阻塞分配 (

【讨论】:

    猜你喜欢
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多