Specifics about Calculating Delays in Verilog and Timing - delay

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.

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:
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.
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.
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.

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

Related

Verilog delayed signal not toggling

I have the following Code:
`timescale 1ps / 1ps
module tb;
localparam t_CLOCK_PERIOD = 1000;
bit clk;
bit clk_del;
always #(t_CLOCK_PERIOD/2) clk = ~clk;
assign #490 clk_del = clk;// clk_del toggling normally
//assign #510 clk_del = clk;// clk_del not toggling
initial begin
clk =1'b1;
$display("waiting for Clock delayed");
#(posedge clk_del);
$display("Clock delayed");
$finish;
end
endmodule
I am trying to delay a clock signal, but when I do that by more of half a period, the signal stays unassigned (it does not toggle).
What am I doing wrong? How can I delay this signal more that the half period?
Your clk_del assign statement does not work with the 510 delay because the RHS (clk) changes more quickly than the delay. It is like you are always sampling clk when it is 0. The assign statement is confusing, and it is not the proper way to generate two related clock signals.
You can control the phase relationship between the 2 clocks by using an initial delay for the delayed clock. This approach is more conventional and is easier to understand:
always #(t_CLOCK_PERIOD/2) clk = ~clk;
initial begin
clk_del = 1;
#10;
forever #(t_CLOCK_PERIOD/2) clk_del = ~clk_del;
end
By varying the initial value of clk_del and the initial delay value, you can achieve any phase relationship you want.
The issue is related to clk changing before the assignment delay as toolic points out.
This problem is independent of clock signal and can be faced on data signals too. A detailed explanation of the delays usage in verilog can be found here.
The proper solution to my problem was to change
assign #510 clk_del = clk;
to
always #(clk) clk_del <= #510 clk;

I need to generate waveform as shown. in verilog code

I need to generate a waveform, as shown in the image. But with my code, I did not get expected waveform
In the design, part got the last and valid values in a random period from test-bench.
my problem is why the I value incremented at valid not equal to one
Design code:
module design_d(clk,valid,last,data);
input clk,valid,last;
output reg [7:0] data;
reg [7:0] i;
initial
begin
data=0;
i=0;
end
always #(posedge clk,valid)
begin
if (valid)
begin
data<=i;
i=i+1;
$display("i=%d data=%d ",i,data);
end
else
begin
data <=8'bz;
end
end
endmodule
Test bench code:
module test;
reg clk,valid,last;
wire [7:0] data;
parameter clk_period=2;
design_d dut(clk,valid,last,data);
initial
begin
clk=1;
valid=1;
last=0;
end
always #(clk_period/2) clk=~clk;
always #(posedge clk)
begin
last=0;
#4 last=1;
#clk_period last=0;
#8 last=1;
#clk_period last=0;
#10 last=1;
#clk_period last=0;
#16last=1;
#clk_period last=0;
#20 last=1;
#clk_period last=0;
end
always #(posedge clk or last)
begin
valid<=1;
wait(last==1)
#clk_period;
valid<=0;
#clk_period;
valid<=1;
end
initial
begin
$dumpfile("dump.vcd");
$dumpvars(1);
#24 $finish;
end
endmodule
It seems you have difficulties with the English language, which is not your fault but because of that, I may interpret your question wrongly.
You have a waveform of what you need to achieve. This to me suggest that this is a school assignment and therefore I will treat it that way. This means I will **not* give you a complete answer but give you pointers about where you are going wrong. (This should all be in a comment but there is now way it would fit).
...got the last and valid values in a random period from test-bench.
First thing to realize is writing a test-bench is just as difficult, if not more difficult then writing the RTL code itself.
In your test-bench You are using always #(posedge clk) but inside that section you use #... statements. That by itself is not wrong. Dangerous, yes, but not necessary wrong.
But
Your clock has a time period of 2 (parameter clk_period=2;) and inside your posedge clock you use delays which are equal or bigger then the clock period. That often leads to a disaster, as you have found out.
Read up on how Verilog works, especially when the sensitivity list always #... is used: It is not triggered until all statement in the section have been dealt with. In your case it means the that it will takes several clock edges until the always block is started again.
Test Bench
I don't know what the assignment was so I'll use the waveform you have given.
As last and valid are inputs to you module I will give you pointers how to make those.
valid is high for 4 clock cycles, it is then low for one clock cycle, after which it repeats itself. This means you need a pattern which repeats itself every 5 clock cycles and thus you need to make a counter which counts 0,1,2,3,4,0,1,2,3,4,...
You should not make that using #..... statements. You should use the test bench clock and make a counter which counts!
Making a counter which counts as described above is the first thing you need to learn in HDL! You will find that you have to do that over and over and over and over .. In every piece of RTL code and every test bench.
Modulo 5 counter.
I prefer for all my modules and my test benches to have a reset.
If only that it allows me to start a new test from a known state.
reg [2:0] counter;
always #(posedge clk or negedge reset_n)
begin
if (reset_n)
counter <= ...
else // clocked section
begin
if (..)
counter <= ...
else
counter <= ...
end
end
Start fresh and get the above code running first. Observe that the counter is indeed running 0,1 2, 3, 4, 0, .. before you continue.
Derived signals .
Next learn to derive signals from that.
Basic rule: in a clocked section, if you need a signal at counter value X you have to generate that at cycle X-1.
Thus to make last high when the counter is 3 you have to set that up when the counter is 2:
always #(posedge clk...
...
if (counter==3'h2)
last <= 1'b1;
else
last <= 1'b0;
I leave making the valid to you.
Once you got your test bench running start working on your design_d module.
Some tips:
Use always non-blocking assignments <= in your clocked section. **
Do NOT use a clock period of 2, use 100 or 1000. You will find out in due time why that is better.
Do not use always #(posedge clk or [one or more signals] ) unless as per my example. **
Take care of your indenting. I had to do some mayor editing on your code.
**Sorry I can't go into details why that is good practice most of the time as that would triple the size of this answer. For now please follow the tips.
I could have written the actual code in a tenth of the time it took me to write all that so I hope you will not delete the question as others may profit from it.

code for clock generation in structural verilog

I was trying to teach myself verilog programming from "The Verilog HDL" book by Thomas Moorby. In one of the exercises, they asked to generate a clock using structural verilog only (except for the $monitor part of course).
I tried the following:
module clock();
wor clk;
assign clk=0;
initial begin
$monitor($time,,"clk=%b", clk);
#100 $finish;
end
assign #5 clk = ~clk;
endmodule
Problem is, it works in iVerilog 0.9.7, but for version 10.0 and above, it does not work.. I simply get undefined value for clk!
Does not seem like a bug in iVerilog, otherwise it would probably have been fixed in one of the 10.x releases. Is there any other way to get this working? Also, what is wrong with the current code (if any) ?
this is a messy code you have. usually clock generation done with regs as one of the following
reg clk;
initial begin
clk = 0;
forever
#5 clk = ~clk;
end
or
always
#5 clk = ~clk;
initial
clk = 0;
Strange code, you are resolving clk drives using an or-gate behaviour. First assign is constantly driving 0. Second assign is inverting the resolved value. But what is the initial value of the second wor input? Wouldn't that second assign produce X in the first place (X ored with 0 would give you X)? Have your tried running it in the simulator or at least drawing somewhere what hardware do you want to get? It's like you're feeding and inverter with 0 or'ed with X which will produce X.
If you want to model a clock you can:
1) convert first assign into initial begin clk = 0; end
2) second assign to always
3) make clk reg type
If you want a synthesizable clock generator you would require a source of oscillations, PLL, etc.

How to compare integer values with binary in for loop for Delay Generation in Verilog Synthesis?

Hello Friends I still not know how to Generate Delay in Verilog For synthesis and call it any line in Verilog for synthesis...for finding this I write a code but it not works please help me if you know how to Generate Delay and call in any line like a C's Function*......Actually Friends if you tell me why I use for Loop here then my answer is - I want to move pointer inside for loop until and unless they completes its calculation that I made for Delay Generation..
module state_delay;
reg Clk=1'b0;
reg [3:0]stmp=4'b0000;
integer i,a;
always
begin
#50 Clk=~Clk;
end
always #(posedge Clk)
begin
a=1'b1;
delay();
a=1'b0;
delay();
a=1'b1;
end
task delay();
begin
for(i=0;i==(stmp==4'b1111);i=i+1)
begin
#(posedge Clk)
begin
stmp=stmp+1;
end
end
if(stmp==4'b1111)
begin
stmp=4'b0000;
end
end
endtask
endmodule
Actually friends I want this a=1'b0; delay(); a=1'b1; please help I already tried delay Generation Using Counter previously but it not works for me.....If you know same using Counter then please tell me......Thanks
// will generate a delay of pow(2,WIDTH) clock cycles
// between each change in the value of "a"
`define WIDTH 20
reg [`WIDTH:0] counter;
wire a = counter[`WIDTH];
always #(posedge Clk)
counter <= counter + 1;
You have to choose a suitable value for WIDTH according to how much delay you want between changes in a and the rate of your Clk signal
This question is a more succinct version of How to generate delay in verilog using Counter for Synthesis and call inside Always block?.
There is one section of code that I find troublesome:
always #(posedge Clk) begin
a = 1'b1;
delay() ;
a = 1'b0;
end
NB: A good rule to stick to is to always use <= in edge triggered processes.
for now lets think of the delay(); task as #10ns; What we get with the current code would be:
time 0ns a = x;
time 1ns a = 1; //Posedge of clk
time 6ns a = 1; //Waiting on delay
time 11ns a = 0; //Delay completed
Using <= and I think you should see a similar behaviour. However when it comes to synthesis delays like #1ns can not be created and the whole thing will collapse back down to :
always #(posedge Clk) begin
a <= 1'b0;
end
With a hardware description language a good approach is to consider what hardware we want to imply and describe it in the language. The construct always #(posedge Clk) is used to imply flip-flops, that is the output changes once per clock cycle. In the question we have a changing value 3 times, from 1 clock edge I do not know what hardware you are trying to imply.
You can not provide an inline synthesizable delay. For always #(posedge clk) blocks to be synthesizable they should be able to execute in zero time. You need to introduce a state machine to keep state between clock edges. I think I have already provided a good example on how to do this in my previous answer. If the delay is to be programmable then see mcleod_ideafix's answer.

Difference in Clock Generation

What is the difference between the following codes ?
initial begin
clk = 0 ;
forever begin
#5 clk = ~clk;
end
end
initial begin
clk = 0 ;
forever begin
clk = #5 ~clk;
end
end
I do know the difference between Inertial and Transport Delays and I know that clock is generated in both the cases(with some Phase difference between the two ), but I want to know how the simulator reacts to the following codes.Is it the same or different ? Like how many events are taken into consideration while calculating the value ?
The difference between the two from a usage point:
#5 clk = ~clk; means wait 5 time steps then execute clk = ~clk;
For Wires B = #5 A; means B is assigned to A from 5 timestep ago. A leads B by 5 timesteps. If B is changed to A A = #5 A;
wire B;
assign B= #5 A;
Usage for a wire is covered by the IEEE 1800-2012 section 6.7 Net declarations
From #new2androids update syntax A = #5 B;, for a registers is different from that of a wire. B is checked every 5 time units and A is assigned the value immediately. Which is why it works for testbench clock generation.
As to how the simulator reacts, there may be some standard scheduling practises that others can comment on but to a degree it may depend on the simulator you are using.
#new2android Provided the follwoing info read from 1996 : Understanding Verilog Blocking
and Non--blocking Assignments
#5 A = B; Pulses with width less than 5 are ignored by the Simulator
A = #5 B; Input is checked every 5 time units and assigned the value immediately
Notes
All uses of delays are for simulation only and are not synthesizable.
The question & answer does not cover the differences when using non-blocking variants of the delays (B <= #5 A;, #5 B <= A;).

Resources