How to understand the blocking and non blocking statements in verilog? - verilog

I understood the basic difference between blocking and non-blocking statements in Verilog. But still it is not possible for me to understand what's happening & when and where to use blocking and non-blocking statements. For example, consider simple d ff code:
module dff (clk, reset,d, q, qb);
input clk;
input reset;
input d;
output q;
output qb;
reg q;
assign qb = ~q;
always #(posedge clk or posedge reset)
begin
if (reset) begin
// Asynchronous reset when reset goes high
q <= 1'b0;
end else begin
// Assign D to Q on positive clock edge
q <= d;
end
end
endmodule
But if I write the very same logic using two-segment coding technique:
module dff(input wire d,
clk,
reset,
en,
output wire q);
reg q;
reg r_reg, r_next;
always #(posedge clk, posedge reset)
if(reset)
r_reg<=1'b0;
else
r_reg<=r_next;
always #*
if(en)
r_reg=d;
else
r_reg=r_next;
assign q<=r_reg;
endmodule
Now, in this code, I just didn't understand why are using <= in the first always block and why they are using = in 2nd always block. I also know that in combinational logic circuit = is advised to use & in sequential <= this is advised to use. But still, I couldn't be able to find out the answer to the usage of blocking and non-blocking statements. Can you please help me!?

Blocking/non-blocking assignments is a simulation artifact only. Contrary to the believe, verilog does not describe hardware. Verilog describes desired behavior of the hardware trying to fit it into an event-driven simulation scheme.
Here is a simple example of a shift register which employs 2 flops:
always #(posedge clk)
out1 = in;
always #(posedge clk)
out2 = out1;
Now, what would the output of the out2 be? Since we are dealing with simulation, then it depends on the order in which these 2 statements are executed. Either it will be the old value of out1, or the new one (actually the value of in);.
In hardware there is no such mess. It will flop the value which existed at the posedge time, the old value of out1 (well, unless there are unusual delays in clocks).
In order to match this behavior, the non-blocking assignment was introduced. Verilog simulation is done in simulation ticks. Every tick is as long as there are events which could cause re-evaluation of other blocks. The non-blocking assignments are scheduled to be executed at the end of such a tick with current rhs values ( in reality there are several scheduling zones). So, consider the following:
always #(posedge clk)
out1 <= in;
always #(posedge clk)
out2 <= out1;
In the above example the all assignments will happen at the end of the tick. 'out2` will be assigned a value which existed at the time of the <=, so, it will be the old value of out1. Now, it does not matter in which order they are executed.
So, the top-level recommendation is to use blocking assignments (=) for combinational logic and use non-blocking assignments (<=) for all outputs of state devices, flops and latches. Note that some temporary variables inside state devices, which are only used there internally should also be assigned with blocking. Also, never use non-blocking assignments in clock trees.

Related

two clock ring counter with verilog

I'm trying to write a roll shift/ ring counter that takes two switches as the clocks in verilog.
My code is as follows:
module roll(CLK1, CLK2, LEDS);
input CLK1;
input CLK2;
output [3:0] LEDS;
reg [3:0] LEDS;
initial
begin
LEDS = 4'b0001;
end
always#(posedge CLK1 or posedge CLK2)
begin
if(CLK1)
begin
LEDS[3]<=LEDS[2];
LEDS[2]<=LEDS[1];
LEDS[1]<=LEDS[0];
LEDS[0]<=LEDS[3];
end
// Roll Right
if(CLK2)
begin
LEDS[3]<=LEDS[0];
LEDS[2]<=LEDS[3];
LEDS[1]<=LEDS[2];
LEDS[0]<=LEDS[1];
end
end
endmodule
I tried using two always blocks, but then figured out that I cannot do that. and when I have the posedge CLK2 in the always statement, the leds on my FPGA all stay on.
Remember Verilog is not a programming language it is a hardware description language.
And when coding for synthesis, you will only be successful if you write code that can be instantiated with actual gates. So writing an always block with sensitivity to edges of two different signals can't be synthesized unless the response to one of the two signals has the effect of a RESET or PRESET operation.
Your code also logically doesn't do what it seems you want to. Consider what your code says will happen if there is a rising edge on CLK2 when CLK1 is already high (or vice versa). Your lights will roll left and then immediately roll right gain, resulting in no change.
A more usual approach would be to have a clock running much faster than the UP and DOWN inputs are expected to change, and use that to drive the logic. For example
module roller(input clk, input rst, input UP, input DOWN, output reg LEDS[3:0]);
reg UP1, DOWN1;
always #(posedge clk or posedge rst)
if (rst) begin
LEDS[3:0] <= 4'b0001;
end
else
begin
UP1 <= UP;
DOWN1 <= DOWN;
if (UP & ~UP1) begin
LEDS[3:0] <= {LEDS[2:0], LEDS[3]};
end
else if (DOWN & ~DOWN1) begin
LEDS[3:0] <= {LEDS[0], LEDS[3:1]};
end
end
endmodule;
Notice that this gives priority to UP. If both UP and DOWN are asserted, the pattern will roll "up" rather than down. If you want a different behavior, you'd have to modify the code to achieve it.

How to split the sequential and the combinational in verilog

I am trying to make a counter in verilog and I want to know how to split the sequential part from the combinational one.
I have this module, it works fine, but I don't know how to split it?
module counter4bits(
input clk_i,
input rst_n_i,
input enable_i,
input up_down_i,
output reg[3:0] val_o);
always#(posedge clk_i) begin
if (rst_n_i == 1)
val_o <= 0;
else if(enable_i == 1)
val_o <= val_o + 1;
end
endmodule
One way is to make always #(*) blocks for the combinational parts using blocking assignments (=), and make always #(posedge clk_i) blocks for the sequential parts using non-blocking assignments (<=) to simple reg.
The blocking assignment (=) in combinational gives faster simulation and predictable behavior even if explicit sensitivity lists line #(rst_n_i or enable_i or ...) are used instead of #(*). The non-blocking assignment (<=) in sequential logic gives the expected flip-flop behavior where the next value depends on the previous value.
The code will then look like:
module counter4bits(
... input/output with no change
reg [3:0] val_nxt; // Not flip-flop but used in always #(*) thus reg
always #(*) begin
if (rst_n_i == 1)
val_nxt = 0;
else if(enable_i == 1)
val_nxt = val_o + 1;
end
always #(posedge clk_i)
val_o <= val_nxt;
endmodule
Why do you want to split the combinational and sequential logic.
The code you have written is good style for the power optimization.
With your style of code the tool can understand the flip flop value will change on enable_i hence the tools are intelligent enough to put a clock gate for flop using enable_i which will reduce the power.

How to handle data going from a clock domain to another clock domain whose clock is divide by 2 version of the first clock?

I have the following code.
module tb;
reg clk;
reg clk_2;
reg [15:0] from_flop;
reg [15:0] to_flop;
initial begin
clk = 0;
clk_2 = 0;
from_flop = 1;
end
always #10 clk = ~clk;
always #(posedge clk) begin
clk_2 <= ~clk_2;
end
always #(posedge clk) begin
from_flop <= from_flop + 1;
end
always #(posedge clk_2) begin
to_flop <= from_flop;
end
endmodule
However, at time instant 10ns, from_flop and to_flop both get value = 2. This is contrary to what I was expecting. I was expecting from_flop to change from 1 to 2 at 10ns, and to_flop to change from x to 1 at 10ns.
Why is this happening and how to code such that this doesn't happen?
Usually assignments in a sequential block are use non-blocking (<=) assignments. The one notable except is for generating derived clocks, which should use blocking (=) assignments. Blocking assignments in sequential blocks are legal; but you need to know what you are doing or you will get a functional mismatch between RTL simulation and circuit. That said, you still needed to error on the side of caution when using this approach.
A flip-flop has has a clock to Q delay, there for any derived clocks will have a phase offset from its parent clock. Some synthesizing tools may compensate the offset for you, however you will need to specify all cases where this should happen to the synthesizer; it will not figure it out for you. This means you should not create derived clocks sporadically across the design. All derived clocking signals need to be generated from one dedicated module; this keeps it manageable.
In most cases you should not create any derived clock. Instead, sample every other clock by adding an extra flip-flop.
always #(posedge clk) begin
from_flop <= from_flop + 1;
if (transfer_n==1'b0) begin
to_flop <= from_flop;
end
transfer_n <= ~transfer_n;
end
This strategy keeps the design in one clock domain which usually makes synthesis easier with better timing. The area impact from the extra flop in minimal can easily be less then the area penalty from the added buffers needed to keep the derived clocks aligned.
The problem is this line:
clk_2 <= ~clk_2;
You are using a non-blocking assignment, when perhaps you wanted a blocking assignment:
clk_2 = ~clk_2;
Non-blocking assignments are scheduled after blocking assignments, so the always #(posedge clk) begin will always be clocked before always #(posedge clk_2) begin.
Obviously, this isn't synthesisable code. So, this is a simulation (scheduling) issue. If you are going to synthesise something with this functionality, consider very carefully how you generate the divided clock.
http://www.edaplayground.com/x/AyQ

Assignment under multiple single edges is not supported for synthesis

I have written this code:
module Key_Schedule(
subkey_tupple1,
subkey_tupple2,
generate_key_final_step,
rst,clk
);
reg [0:31] a1,b1,a2,b2;
input [0:31] subkey_tupple1;
input [0:31] subkey_tupple2;
//input [31:0] subkey_A_swap;
//input [31:0] subkey_B_swap;
input clk,rst;
output reg [0:63] generate_key_final_step;
reg [0:63] temp;
reg [0:63] round_sub_key_left;
always #(posedge clk or negedge rst)
begin
if (!rst)
begin
temp<={64{1'b0}};
round_sub_key_left<={64{1'b0}};
end
else
temp<={subkey_tupple1[0:31],subkey_tupple2[0:31]};
//The error is below... line 49
round_sub_key_left<={temp[8:15],temp[16:23],temp[24:31],temp[0:7],temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a1={temp[8:15],temp[16:23],temp[24:31],temp[0:7]};
b1={temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a2=b1;
b2=a1^b1;
generate_key_final_step={a2,b2};
end
endmodule
When I click Synthesize -XST I get this error:
ERROR:HDLCompiler:1128 - "D:\Embedded_Project\Key_Schedule.v" Line 49: Assignment under multiple single edges is not supported for synthesis
There is a missing begin-end around the else condition. Therefore the assignment to temp is the only assignment in the else condition. When in active reset round_sub_key_left is still derived from temp. There error is likey do to the fact that during asynchronous reset round_sub_key_left is not being assigned to a constant.
Also, at toolic mentioned: It is generally a bad practice to put your combinational logic and synchronous logic in the same always block (ie mix blocking and non-blocking assignments). The best practice is to put combinational logic in an always #* block with blocking assignments (=). Synchronous logic (ie flip-flop) should go in an always #(posedge clk /*+ async-set/set*/) and only use non-blocking assignment (<=).
always #(posedge clk or negedge rst) begin
if (!rst) begin
temp<={64{1'b0}};
round_sub_key_left<={64{1'b0}};
end
else begin
temp <= {subkey_tupple1[0:31],subkey_tupple2[0:31]};
round_sub_key_left <= temp[8:31],temp[0:7],temp[40:63],temp[32:39]};
end
end
always #* begin : output_comb_logic
a1={temp[8:15],temp[16:23],temp[24:31],temp[0:7]};
b1={temp[40:47],temp[48:55],temp[56:63],temp[32:39]};
a2=b1;
b2=a1^b1;
generate_key_final_step={a2,b2};
end
else at line 47 affects only one line, and it is not right.
Under reset condition round_sub_key_left has two conflicting drivers.
Place code after else in begin-end parentheses.

Shift Registers Verilog

I am very new to HDL language. I have a question about how to program a shift register. (i know i shift to the other direction). Why does the book use wire[N-1:0] r_next? what's drawback of my implementation?
thanks
my first try is as following
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg[0]=data;
r_reg = r_reg<<1;
end
assign out =r_reg[N-1];
endmodule
but the book gives:
module lesson04#(parameter N=8)(
input wire clk, reset,
input wire data,
output wire out
);
reg [N-1: 0] r_reg;
wire[N-1:0] r_next;
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg =0;
else
r_reg <= r_next;
end
assign r_next= {data, r_reg[N-1:1]};
assign out =r_reg[N-1];
endmodule
First of all, don't forget your begin-ends around sections of code:
else begin
r_reg[0]=data;
r_reg = r_reg<<1;
end
Without this, only r_reg[0]=data will be in the else clause of the if statement. This will work, but is considered bad style due to the blocking statements in a sequential logic description...
Second, for modeling sequential blocks, use nonblocking assignments (<=) or your calculations may 'fall through' (google nonblocking vs blocking for more info). Your example may very well work (did you try it in a simulator?) but if things get more complicated and more variables are added things can break.
always #(posedge clk or negedge reset)
begin
if(!reset)
r_reg <= 0;
else begin // This is horrible! Don't write code like this!
r_reg[0] = data; // blocking
r_reg <= r_reg<<1; // non-blocking
end
end
For the above reason, it is sometimes recommended that combo logic is separated from sequential logic so that you can write nonblocking assignments to registers in sequential blocks, and blocking in combo blocks and never have to worry about the scheduling.
To code in this way, you need to calculate what the next output should be using the current state, hence the r_next bus in the answer. I think it tends to help the synthesis tool out too if all the flip-flops are separated from surrounding combo logic in this way.
Also, if your reset is active low (ie LOW resets ) it should be named as such, eg resetb or reset_n.
Your implementation produces quite a different output from the book's. You should prove this to yourself by constructing a simple testbench to drive your inputs and run a simulation. You will see that the book's output shifts the input data by a single clock cycle, whereas your output shifts the input data by eight clock cycles.
By the way you have indented your always block, I am led to believe that it is not what you wanted. This is how your block really behaves:
always #(posedge clk or negedge reset)
begin
if(!reset) begin
r_reg =0;
end else begin
r_reg[0]=data;
end
r_reg = r_reg<<1;
end
I always explicitly use the begin/end keywords in if/else statements to avoid this confusion.
The way it simulates, r_reg is always 0 because you clobber the 1st assignment (r_reg[0]=data;) with the 2nd (r_reg = r_reg<<1;). Another difference is that the book assigns data to the MSB of the shift register, but you assign it to the LSB.
If you are using decent linting and synthesis tools, you would probably get a bunch of warnings for your code. This would alert you to make some changes.

Resources