Question

I am currently teaching myself Verilog and going through a few tutorials that I found and two things that kind of confuse me are how to specifically calculate how much time you need to delay after changing the inputs to a combinatorial circuit, and in what order items get executed in your code. I understand generally that real circuits have rise/fall delay times and that you want to delay your outputs so that your inputs generate a value before you calculate your outputs, but I want to know specifics.

So, here's an example:

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

Some of my questions are embedded in comments in the code. However, my other confusion is with timing. In the beginning of the main module, I instantiate a dflipflop module called dff with my parameters that I defined in main above. Where in my code does it say: rebuild the module/recalculate the Q when I change the inputs in main? I don't see the link.

Was it helpful?

Solution

On your specific questions:

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

You don't. Adding a transport delay to the clock branch and not the reset branch makes little or no sense.

//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?

You don't; the model is flawed. Remove the first clk=0, or move it above the forever.

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

No idea - it's just an arbitrary delay in your stimulus generation. It doesn't matter, as long as it's 'long enough'.

General points:

  1. You don't care about specifying delays when writing HDL code; this is almost always a job for the tools. Your tools will work out real silicon delays and back-annotate them into your code using sdf, specify blocks, and so on. If you want details, look at the simulation model output by your synth or place-and-route tools.
  2. As long as you're careful about your use of blocking and non-blocking assignments then your code will 'work', even though you haven't explicitly put delays into it. 'Working' means that the outputs change in the correct order to preserve your required functionality.
  3. I think you may be confused in your understanding of 'rise/fall delays' and 'delaying outputs'. In general, at the HDL level, you're never concerned with signal rise or fall times; everything happens at a threshold voltage. An input changes at time x, and dependent outputs change at some later time. This is a propagation delay. For clocked circuits, the prop delay will depend on whether the output goes to 0 or goes to 1, which leads to unfortunate terminology involving 'rise delay' or 'fall delay' (actually propagation delay to 1, or to 0). You don't "delay your outputs so that your inputs generate a value before you calculate your outputs". Except in exceptional circumstances, you calculate your outputs immediately, and then specify how long it takes the outputs to actually propagate to the pins of your model.

OTHER TIPS

If your dflipflop module will be synthesized, there should not be a #2 delay. Sometimes people add these delays because they are simulating with a mix of different coding styles: behavioral and structural. Sometimes the structural code has delays which make your behavioral code behave incorrectly.

Perhaps this is what was intended:

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

Perhaps the #4 was used to release the rst just before the 1st clk edge at time=5.

q <= #2 d; This is the clock-to-q delay. The number is most likely arbitrary, but it could be coming from characterization of a specif flip-flop design. Many designers put a small delay on the clock-to-q to make the looking a waveforms easier. Normally you want this number very small and almost always less then the clock period.

for your clock generator, the extra clock = 0 doesn't matter as long as there is a semicolon. Most likely this is the coding style designer liked to use. Both of the following are equivalent to your clock, just written differently:

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

The #4 is because the designer wanted the test to end the reset on the design before the first clock (@ #5). This also gives all the following delays (which are multiples of the clock period of #10) and #1 setup time.

your dflipflip will only react if there is a posedge clk or posedge reset. if reset is high, then q will be assigned to 0. If reset and the positive edge of clk is detected, then d will be sampled and #2 latter assign the sampled value to q.

Here is a step buy step on what is happening:

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  
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top