【问题标题】:Specifics about Calculating Delays in Verilog and Timing关于计算 Verilog 和 Timing 延迟的细节
【发布时间】:2013-05-19 08:28:15
【问题描述】:

我目前正在自学 Verilog,并浏览了一些我发现的教程,有两件事让我感到困惑,即如何具体计算在将输入更改为组合电路后需要延迟多少时间,以及在什么情况下订单项在您的代码中执行。我通常了解实际电路具有上升/下降延迟时间,并且您希望延迟输出,以便您的输入在计算输出之前生成一个值,但我想知道具体情况。

所以,这里有一个例子:

module dflipflop (d,clk,reset,q);
input d, clk, reset;
output q;
reg q;

always @ (posedge clk or posedge reset) begin
  if (reset) begin
    q <= 0;
  else begin
    q <= #2 d; //why did I need to delay this 2 time units?
  end
 end
end module

module main;
reg d, clk, rst;
wire q;
dflipflop dff(d,clk,rst,q);

inital begin
  forever begin
    clk = 0;
    #5
    clk = 1;
    #5
    clk = 0; //why do I need to reset the clk to 0 if this is a forever block and my first assignment is clk = 0 in the beginning? 
  end
end

 initial begin
  d=0; rst=1; 
  #4  //why #4? How did they calculate that?
  d=1; rst=0; 
  #50
  d=1; rst=1;
  #20
  d=0; rst=0; 
 end  
end module

我的一些问题嵌入在代码中的 cmets 中。然而,我的另一个困惑是时间问题。在主模块的开头,我用上面 main 中定义的参数实例化了一个名为 dff 的 dflipflop 模块。我的代码在哪里说:当我更改 main 中的输入时重建模块/重新计算 Q?我没有看到链接。

【问题讨论】:

    标签: delay verilog timing timedelay order-of-execution


    【解决方案1】:

    如果您的dflipflop 模块将被合成,则不应有#2 延迟。有时人们会添加这些延迟,因为他们正在使用不同编码风格的混合进行模拟:行为和结构。有时结构代码有延迟,这会使您的行为代码行为不正确。

    也许这就是我们想要的:

    inital begin
      clk = 0;
      forever begin
        #5
        clk = 1;
        #5
        clk = 0;
      end
    end
    

    也许#4 用于在时间=5 的第一个clk 边缘之前释放rst

    【讨论】:

      【解决方案2】:

      q &lt;= #2 d; 这是时钟到 q 的延迟。该数字很可能是任意的,但它可能来自特定触发器设计的特征。许多设计人员在时钟到 q 上设置了一个小的延迟,以使查看波形更容易。通常,您希望这个数字非常小,并且几乎总是小于时钟周期。

      对于您的时钟发生器,只要有分号,额外的clock = 0 就无关紧要。这很可能是设计师喜欢使用的编码风格。以下两个都相当于你的时钟,只是写法不同:

      always begin
        clk = 0;
        #5;
        clk = 1;
        #5;
      end
      // or
      initial begin
        clk = 0;
        forever #5 clk = !clk;
      end
      

      #4 是因为设计人员希望测试在第一个时钟 (@#5) 之前结束设计的复位。这也给出了以下所有延迟(它们是#10 时钟周期的倍数)和#1 设置时间。

      只有在存在posedge clkposedge reset 时,您的dflipflip 才会做出反应。如果reset 很高,那么q 将分配给0。如果resetclk的上升沿被检测到,那么d将被采样,#2后者将采样值赋给q

      这是关于正在发生的事情的一步购买步骤:

      initial begin
        d=0; rst=1;  /* simulation time #0, rst goes 1'bx->1'b1 (posedge) therefore q goes 1'bx->1'b0 */
        #4  
        d=1; rst=0; /* 
             simulation time #4, rst goes low, sill no posedge clk therefore dflipflop does nothing 
             simulation time #5 first posedge clk therefore sample d (1)
             simulation time #7 q is assigned to 1 (sampled d)
             simulation time #15 posedge clk therefore  sample d (1) again
             simulation time #17 q is assigned to 1 (sampled d) again
             ... repeat pattern ...
             simulation time #45 posedge clk therefore sample d (1) again
             simulation time #47 q is assigned to 1 (sampled d) again */
        #50
        d=1; rst=1; /* 
             simulation time #54, rst goes high therefore assign q to 0 
             simulation time #55 posedge clk, rst==1 therefore assign q to 0
             simulation time #65 posedge clk, rst==1 therefore assign q to 0 */
        #20
        d=0; rst=0; /* 
           simulation time #74, rst goes low therefore no change
           simulation time #74, initial block ends */
      end  
      

      【讨论】:

        【解决方案3】:

        关于您的具体问题:

        //why did I need to delay this 2 time units?

        你没有。向时钟分支而不是重置分支添加传输延迟几乎没有意义。

        //why do I need to reset the clk to 0 if this is a forever block and my first assignment is clk = 0 in the beginning?

        你没有;模型有缺陷。删除第一个 clk=0,或将其移至 forever 上方。

        //why #4? How did they calculate that?

        不知道 - 这只是刺激生成的任意延迟。没关系,只要“足够长”。

        一般要点:

        1. 在编写 HDL 代码时,您不关心指定延迟;这 几乎总是工具的工作。您的工具将真正发挥作用 硅延迟并使用 sdf 将它们反注释到您的代码中, specify blocks,等等。如果你想了解详细信息,请查看 合成器或布局布线工具输出的仿真模型。
        2. 只要您小心使用阻塞和非阻塞赋值,那么您的代码就会“工作”,即使您没有明确地将延迟放入其中。 “工作”意味着输出以正确的顺序更改以保留您所需的功能。
        3. 我认为您可能对“上升/下降延迟”和“延迟输出”的理解感到困惑。一般来说,在 HDL 级别,您从不关心信号上升或下降时间;一切都发生在阈值电压下。输入在时间 x 发生变化,相关输出在稍后的某个时间发生变化。这是传播延迟。对于时钟电路,prop 延迟将取决于输出是变为 0 还是变为 1,这导致不幸的术语涉及“上升延迟”或“下降延迟”(实际上传播延迟为 1 或 0)。您不会“延迟输出,以便您的输入在计算输出之前生成一个值”。除非在特殊情况下,您会立即计算输出,然后指定输出实际传播到模型引脚所需的时间。

        【讨论】:

        • 好的,很高兴知道有些延迟有些随意。我确实知道在哪里使用非阻塞和阻塞分配非常重要,但是特定延迟的结合让我感到困惑。感谢您清除传播延迟 vs.上升/下降时间延迟混淆。
        猜你喜欢
        • 1970-01-01
        • 2012-07-04
        • 1970-01-01
        • 1970-01-01
        • 2013-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多