关于计算Verilog和时序延迟的细节

时间:2013-05-23 20:14:40

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

我目前正在教自己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

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

3 个答案:

答案 0 :(得分:4)

关于您的具体问题:

//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处改变,并且从属输出在稍后的某个时间改变。这是传播延迟。对于时钟电路,支路延迟将取决于输出是变为0还是变为1,这导致涉及“上升延迟”或“下降延迟”(实际传播延迟为1或0)的不幸术语。您没有“延迟输出,以便输入在计算输出之前生成一个值”。除非在特殊情况下,您立即计算输出,然后指定输出实际传播到模型引脚所需的时间。

答案 1 :(得分:1)

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

也许这就是预期的目的:

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

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

答案 2 :(得分:1)

q <= #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设置时间的倍数。

只有dflipflipposedge clk时,posedge reset才会做出反应。如果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