Sequential designs
Consider a simple 4-bit shift register. The Verilog code for it would look like:
always@(posedge clk)
begin
if(! rst_n)
{r1, r2, r3, r4} <= 4'd0 ;
else
{r1, r2, r3, r4} <= {in1, r1, r2, r3} ;
1. Blocking assignment
« Previous Next »
always@(posedge clk)
begin
if(! rst_n)
{r1, r2, r3, r4} <= 4'd0 ;
else
{r1, r2, r3, r4} <= {in1, r1, r2, r3} ;
end
To understand the assignments above of RHS to LHS, we need to understand following terminologies:
1. Blocking assignment
In a single always block, when a blocking assignment is encountered, RHS is evaluated and directly assigned to LHS, and the control moves to evaluate next assignment for all the always blocks.
It is used in combinatorial always block.
2. Non-blocking assignment
In a single always block, when a non-blocking assignment is encountered, RHS is evaluated and stored in a temporary variable, and the control moves to evaluate next assignment similarly for all the always blocks. At last, all the evaluated RHS are assigned to their LHS counterparts respectively.
It is used in sequential always block.
Race around condition in sequential always block:
Let us see, consequences of using blocking assignments in sequential always block:
always@(posedge clk) //1
out1 = r1 ;
always @(posedge clk) // 2
out2 = out1 ;
Lets say, initial value of r1 = 23, initial value of out1 = 45
If #2 always block is executed before #1 always block:
posedge clk -> initial value of out1 assigned to out2 -> value of out1 gets updated to r1.
At the end of first posedge of clk, out2 = 45 and out1 = 23
If #1 always block is executed before #2 always block:
posedge clk -> value of out1 gets updated to r1 -> initial value of out1 assigned to out2
At the end of first posedge of clk, out2 = 45 and out1 = 45.
The point here is that there is no consistency.
Hence, to avoid race around problems, use non-blocking statements in sequential always blocks throughout.
If non-blocking assignments were used in above example, the sequence of events would be:
posedge clk -> r1 is evaluated -> out1 is evaluated -> updated value of r1 and out1 are assigned to their respective RHS.
If you visualize, that is also the working of a flip-flop. Thus every sequential always block results in a flip-flop
Guidelines in sequential always blocks:
1. Do not used edge and level triggering in same sensitivity list. Keep either only edge triggering or only level triggering. Do not mix them in same sensitivity list.
2. Use only non-blocking assignments in a sequential always block. Do not mix them with blocking assignments.
3. Assign a variable in only single always block.
« Previous Next »
Comments
Post a Comment