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;).
Related
I have designed a serial in parallel out shift register as input register for an encoder
module ShiftRegister_SIPO(clk, in, out);
input clk,in;
output [3:0] out;
reg [3:0] tmp;
always #(posedge clk)
begin
tmp = {tmp[2:0], in};
end
assign PO = tmp;
endmodule
how do I retain the value once the desired parallel out data is got , even with clk=1? Because even after the output data is got the value keeps shifting. For example ,if i give
Part of testbench
in=1;
#10
in=0;
#10
in=1;
#10
in=1;
#5 clk=~clk;
I get 1011 at the 4th clock cycle , but the value then keeps shifting. Can i retain it as 1011 for the remaining period also, still keeping the clk=1.
Thanks in advance
In you example the value will be shifting every positive edge of the clock. In order to prevent it from shifting under some circumstances you need a way to enable or disable shifting. For example:
always #(posedge clk)
begin
if (enable)
tmp <= {tmp[2:0], in};
end
So, controlling the enable signal you can control shifting. If its value is low, then no shifting will happen and the value of 'tmp' will remain unchanged till you enable it again.
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.
This question already has answers here:
What does #`DEL mean in Verilog?
(2 answers)
Closed 7 years ago.
I understand that always #(posedge clk) in verilog is a flip flop.
input ld;
reg ld_r;
always #(posedge clk) ld_r <= #1 ld;
What does #1 do in above code? I found it in verilog code for AES. I include a snippet of it below:
always #(posedge clk)
if(!rst) dcnt <= #1 4'h0;
else
if(ld) dcnt <= #1 4'hb;
else
if(|dcnt) dcnt <= #1 dcnt - 4'h1;
always #(posedge clk) done <= #1 !(|dcnt[3:1]) & dcnt[0] & !ld;
always #(posedge clk) if(ld) text_in_r <= #1 text_in;
always #(posedge clk) ld_r <= #1 ld;
Since you mention that always #(posedge clk) infers a flip-flop I assume you are interested in knowing what #1 is synthesized as in hardware. The answer is: nothing.
These delays will get ignored in synthesis, so if you use them in design code you run the risk of your simulation not matching your hardware.
Here is a paper that describes why you would want to add delays: http://sunburst-design.com/papers/CummingsSNUG2002Boston_NBAwithDelays.pdf
#1 Delays by 1 timestep. To find what time step your using you can use:
$printtimescale;
> Time scale of (test) is 1ns / 1ns
Just using #1 can be risky because it is based on the last instance of `timescale 10ns/1fs.
Therefore as files are added or load order changes the definition of #1 can change. Newer versions of Verilog support the use of units ie #1ns. the 1ns part is a realtime and you may perform operations on them as you would any realtime variable.
//Delay 1001ns
#(1us + 1ns);
Intra-assignment
ld_r <= #1 ld;
Equates to :
temp = ld;
#1 ld_r <= temp; // Delay execution of ld_r <= temp by 1 timestep
That is take a copy ld now and assign its value back to ld_r in #1.
The usage of this is explained in 9.4.5 Intra-assignment timing controls of SystemVerilog IEEE 1800-2012 Standard:
I have a test bench that monitors a bus. Some of the signals (bits) within the bus can be 1'bx. For a variety of reasons, I need to know if any of the signals within the bus are 1'bx. What's the best way to test (not for synthesis -- only for simulation purposes) if a bus contains any x's? I had hoped that I could use a reduction OR and then use ===, but this doesn't seem to work.
(^bus === 1'bX)
Bit-wise xor the bus then check if the result is X. If any bit is X or Z then the result will be X.
To know which bit in the bus has the error:
always #* begin
for(integer i=0; i<$size(bus); i++) begin
if(bus[i]===1'bX) $display("bus[%0d] is X",bus[i]);
if(bus[i]===1'bZ) $display("bus[%0d] is Z",bus[i]);
end
end
You can use $isunknown (refer to the IEEE Std 1800-2017, section 20.9 Bit vector system functions):
module tb;
reg [3:0] data;
initial begin
#5 data = 4'b0101;
#5 data = 4'b000x;
#5 data = 4'b1111;
#5 data = 4'b0x0x;
#5 data = 4'b0x1x;
#5 data = 4'bzzzz;
#5 $finish;
end
always #(data) begin
if ($isunknown(data)) $display($time, " data=%b has x's", data);
end
endmodule
Outputs:
10 data=000x has x's
20 data=0x0x has x's
25 data=0x1x has x's
30 data=zzzz has x's
Note that this also treats z as x.
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