<= Assignment Operator in Verilog - verilog

What does the <= do in Verilog?
For example:
always #(posedge Clock) begin
if (Clear) begin
BCD1 <= 0;
BCD0 <= 0;
end
end

"<=" in Verilog is called non-blocking assignment which brings a whole lot of difference than "=" which is called as blocking assignment because of scheduling events in any vendor based simulators.
It is Recommended to use non-blocking assignment for sequential logic and blocking assignment for combinational logic, only then it infers correct hardware logic during synthesis.
Non-blocking statements in sequential block will infer flip flop in actual hardware.
Always remember do not mix blocking and non-blocking in any sequential or combinational block.
During scheduling process of simulator:
There are four regions and order of execution of commands as follows
1) Active region
--Blocking assignments
--Evaluation of RHS of non-blocking assignments(NBA)
--Continuous assignment
--$display command
--Evaluate input and output of primitives
2) Inactive region
--#0 blocking assignments
3) NBA(non-blocking assignment update)
--update LHS of non-blocking assignments (NBA)
4) Postponed
--$monitor command
--$strobe command
Using of blocking assignment "=" for two variable at the same time slot causes race condition
eg: Verilog code with race condition,
always #(posedge Clock)
BCD0 = 0; // Usage of blocking statements should be avoided
always #(posedge Clock)
BCD1 = BCD0;
In order to avoid race condition use non-blocking statement "<="
eg:
always #(posedge Clock)
BCD0 <= 0; // Recommended to use NBA
always #(posedge Clock)
BCD1 <= BCD0;
When this block is executed, there will be two events added to the non blocking assign update queue.
Hence, it does the updation of BCD1 from BCD0 at the end of the time step.
Using Non-blocking "<=" assignment in continuous assignment statement is not allowed according to verilog LRM and will result in compilation error.
eg:
assign BCD0 <= BCD1; //Results in compilation error
Only use NBA in procedural assignment statements,
- initial and
- always blocks

This is called a 'non-blocking' assignment. The non-blocking assignment allows designers to describe a state-machine update without needing to declare and use temporary storage variables.
For example, in this code, when you're using a non-blocking assignment, its action won't be registered until the next clock cycle. This means that the order of the assignments is irrelevant and will produce the same result.
The other assignment operator, '=', is referred to as a blocking assignment. When '=' assignment is used, for the purposes of logic, the target variable is updated immediately.
The understand this more deeply, please look at this example (from Wikipedia):
module toplevel(clock,reset);
input clock;
input reset;
reg flop1;
reg flop2;
always # (posedge reset or posedge clock)
if (reset)
begin
flop1 <= 0;
flop2 <= 1;
end
else
begin
flop1 <= flop2;
flop2 <= flop1;
end
endmodule
In this example, flop1 <= flop2 and flop2 <= flop1 would swap the values of these two regs. But if we used blocking assignment, =, this wouldn't happen and the behavior would be wrong.

Since people have already explained the blocking/non blocking situation, I'll just add this here to help with understanding.
" <= " replaces the word "gets" as you read code
For example :
.... //Verilog code here
A<=B //read it as A gets B
When does A get B? In the given time slot, think of everything in hardware happening in time slots, like a specific sampled event, driven by clock. If the "<=" operator is used in a module with a clock that operates every 5ns, imagine A getting B at the end of that time slot, after every other "blocking" assignments have resolved and at the same time as other non blocking assignments.
I know its confusing, it gets better as you use and mess up bunch of designs and learn how it works that way.

"<=" is a non-blocking assignment operator in verilog."=" is a blocking assignment operator.
Consider the following code..
always#(clk)
begin
a=b;
end
always#(clk)
begin
b=a;
end
The values of a and b are being exchanged using two different always blocks.. Using "=" here caused a race-around condition. ie. both the variables a and b are being changes at the same time..
Using "<=" will avoid the race-around.
always#(clk)
begin
a<=b;
end
always#(clk)
begin
b<=a;
end
Hope i helped too..

<= is a non blocking assignment. The <= statements execute parallely. Think of a pipelined architecture, where we come across using such assignments.
A small exammple:
// initialise a, b, c with 1, 2 and 3 respectively.
initial begin
a <= 1
b <= 2
c <= 3
end
always#(clock.posedge)
begin
a <= b
b <= c
c <= a
end
After the first posedge clock:
a = 2, b = 3, c = 1
After the second posedge clock:
a = 3, b = 1, c = 2
After third posedge clock:
a = 1, b = 2, c = 3

As most told, it is a "Non Blocking <=" assignment widely used for Sequential logic design because it can emulate it best.
Here is why :
Mostly involving a delay(here posedge clock) it is something like it schedules the evaluation of the RHS to LHS after the mentioned delay and moves on to the next statement(emulating sequential) in flow unlike "Blocking = " which will actually delay the execution of the next statement in line with the mentioned delay (emulating combinational)

Related

Blocked and non-blocking assignment error in verilator

I'm testing SystemVerilog code using verilator, and it looks like below.
output [31:0] data_out1;
reg [31:0] data_out1;
always #(rst_b or addr1 or data_in1 or write_mask1)
begin
if((write_mask1 != 32'b0) && (rst_b == 1'b1))
begin
data_out1 <= 32'hxxxxxxxx;
... do something ....
end
always #(posedge clk)
begin
if((write_mask1 != 32'b0) && (rst_b == 1'b1))
begin
data_out1 <= 32'hxxxxxxxx;
... do something ..
end
It has two always blocks, and in each block, data_out1 is assigned in non-blocking. But, it shows a "Blocked and non-blocking assignments to same variable" error.
I do not use blocking assignment, and I can't understand why such an error occurs. I would appreciate if anyone can help.
When I run verilator on your code snippet, I get messages like the following:
%Warning-COMBDLY: Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).
%Warning-COMBDLY: *** See the manual before disabling this,
%Warning-COMBDLY: else you may end up with different sim results.
%Error-BLKANDNBLK: Unsupported: Blocked and non-blocking assignments to same variable: data_out1
The 1st warning message indicates that verilator interprets your 1st always block as combinational logic, not sequential logic, and it treats the nonblocking assignment operator (=>) as a blocking assignment.
Since your 1st block does not use #(posedge clk), it is treated as combinational logic.
Also, you should not make assignments to the same signal from multiple blocks.
Lastly, you should not use nonblocking assignment to infer combinational logic.
There are two issues:
The code in the post is assigning the same signal from two always blocks. This can't be done, data_out1 must be driven from a single always block.
The always block without the clock infers combinational logic. The correct way to model combinational logic is by using blocking assignments (=).
The 2nd always block is ok (but not clean, because the rst_b is not at the first condition alone, it might cause problem for some simulator), working as a FF with sync low-active reset. The problem is the 1st always block.
Based on your modeling with <= in the 1st block, if write_mask1 changes to trigger the sensitivity list, you want to assign data_out1 depending on the old value of write_mask1 at the time point that write_mask1 has been updated with the new value. This behavior is inferred latch, because it needs the memory to hold the old value before the event, but it is also not a valid behavior of a FF. It seems that Verilator interprets this inferred latch still as "blocking assignment". (By the way, latch itself won't cause error, because it is indeed a right way to model if you have latches for purposes like clock gating)
If it is SystemVerilog (instead of Verilog), i would try to use always_comb for combinational logic, and always_ff for sequential. (and always_latch for latch). In your case, the simplest clean way to model is to be aware of which part is combitional and which sequential. I'd model it as:
always_ff #(posedge clk) // to add "or negedge rst_b" if you want async reset
begin
if(!rst_b)
begin
data_out1 <= 32'hxxxxxxxx; // some reset value
end
else if(write_mask1 != 32'b0)
begin
data_out1 <= 32'hxxxxxxxx; // the value you want to update
end
end
// if there is no other condition, it will keep the old value based on the FF behavior
... do something ..
end
If you really mean to have 2 blocks, one doing combinational, one sequential, here we are:
always_comb begin
if(write_mask1 != 32'b0) begin
data_out1_next = 32'hxxxxxxxx;
end
else begin
// now it's necessary to write else-clause because it's not a FF -- it has no memory
data_out1_next = data_out1;
end
end
always_ff #(posedge clk) // to add "or negedge rst_b" if you want async reset
begin
if(!rst_b) begin
data_out1 <= 32'hxxxxxxxx; // some reset value
end
else begin
data_out1 <= data_out1_next;
end
end

Blocking assignments in always block verilog?

now I know in Verilog, to make a sequential logic you would almost always have use the non-blocking assignment (<=) in an always block. But does this rule also apply to internal variables? If blocking assignments were to be used for internal variables in an always block would it make it comb or seq logic?
So, for example, I'm trying to code a sequential prescaler module. It's output will only be a positive pulse of one clk period duration. It'll have a parameter value that will be the prescaler (how many clock cycles to divide the clk) and a counter variable to keep track of it.
I have count's assignments to be blocking assignments but the output, q to be non-blocking. For simulation purposes, the code works; the output of q is just the way I want it to be. If I change the assignments to be non-blocking, the output of q only works correctly for the 1st cycle of the parameter length, and then stays 0 forever for some reason (this might be because of the way its coded but, I can't seem to think of another way to code it). So is the way the code is right now behaving as a combinational or sequential logic? And, is this an acceptable thing to do in the industry? And is this synthesizable?
```
module scan_rate2(q, clk, reset_bar);
//I/O's
input clk;
input reset_bar;
output reg q;
//internal constants/variables
parameter prescaler = 8;
integer count = prescaler;
always #(posedge clk) begin
if(reset_bar == 0)
q <= 1'b0;
else begin
if (count == 0) begin
q <= 1'b1;
count = prescaler;
end
else
q <= 1'b0;
end
count = count - 1;
end
endmodule
```
You should follow the industry practice which tells you to use non-blocking assignments for all outputs of the sequential logic. The only exclusion are temporary vars which are used to help in evaluation of complex expressions in sequential logic, provided that they are used only in a single block.
In you case using 'blocking' for the 'counter' will cause mismatch in synthesis behavior. Synthesis will create flops for both q and count. However, in your case with blocking assignment the count will be decremented immediately after it is being assigned the prescaled value, whether after synthesis, it will happen next cycle only.
So, you need a non-blocking. BTW initializing 'count' within declaration might work in fpga synthesis, but does not work in schematic synthesis, so it is better to initialize it differently. Unless I misinterpreted your intent, it should look like the following.
integer count;
always #(posedge clk) begin
if(reset_bar == 0) begin
q <= 1'b0;
counter <= prescaler - 1;
end
else begin
if (count == 0) begin
q <= 1'b1;
count <= prescaler -1;
end
else begin
q <= 1'b0;
count <= count - 1;
end
end
end
You do not need temp vars there, but you for the illustration it can be done as the following:
...
integer tmp;
always ...
else begin
q <= 1'b0;
tmp = count - 1; // you should use blocking here
count <= tmp; // but here you should still use NBA
end

generate inside generate verilog + error near generate(veri - 1137)

Writing verilog code from quite a few days and one question I have is 'Can we write generate block inside generate block'? I am writing an RTL something like this:
Where 'n' is a parameter.
reg [DATA_WIDTH:0] flops [n-1:0];
generate
if (n > 0) begin
always #(posedge clk) begin
if (en) begin
flops[0] <= mem[addr];
end
end
generate
genvar i;
for (i = 1; i <= n ; i = i + 1) begin
always #(posedge clk) begin
flops[i] <= flops[i-1];
end
end
endgenerate
always #(flops[n - 1])
douta = flops[n - 1];
else
always #(posedge clk) begin
if (en) begin
primary_output = mem[addr];
end
end
end
endgenerate
While compiling the above code, I am getting :
ERROR: syntax error near generate (VERI-1137)
Not sure why. Purpose of this RTL is to create an pipeline of 'n' flops at the output side of the design.
Lets say n is 2, then circuit should become :
flop1-> flop2-> primary output of design
flop1 and flop2 are newly created flops.
You are a long long way from where you should be.
Verilog is not a programming language; it is a hardware description language. You model hardware as a network of concurrent processes. Each process models a small bit of hardware such as a counter, a state machine, a shift-register, some combinational logic... In Verilog, each process is coded as an always block. So, one always statement never ever can appear inside another; that makes no sense.
Secondly, generate is quite a specialised statement. You use it when you want either a large number or a variable number of concurrent processes. That is not a common thing to need, so generate is not common, but is useful when required. You don't need a generate statement to implement a parameterisable shift-register. And, because an always block is a concurrent statement it sits inside a generate statement, not the other way round.
I don't know what your design intent is exactly, to I suspect this code does not do exactly what you want. However, it does implement a parameterisable shift-register of length n and width DATA_WIDTH+1 (did you really mean that?), enabled by the en input:
module N_FLOPS #(n = 2, DATA_WIDTH = 8) (input [DATA_WIDTH:0] dina, input clk, en, output [DATA_WIDTH:0] douta);
reg [DATA_WIDTH:0] flops [n-1:0];
always #(posedge clk)
if (en)
begin : SR
integer i;
flops[0] <= dina;
for (i = 1; i <= n ; i = i + 1)
flops[i] <= flops[i-1];
end
assign douta = flops[n-1];
endmodule
http://www.edaplayground.com/x/3kuY
You can see - no generate statements required. This code conforms to this template, which suffices for any sequential logic without an asynchronous reset:
always #(posedge CLOCK) // or negedge
begin
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
end

What does <= operator do in this code?

module counter (clk,rst,enable,count);
input clk, rst, enable;
output [3:0] count;
reg [3:0] count;
always # (posedge clk or posedge rst)
if (rst) begin
count <= 0;
end else begin : COUNT
while (enable) begin
count <= count + 1;
disable COUNT;
end
end
endmodule
(Source: http://www.asic-world.com/verilog/verilog_one_day2.html#While)
From what I have learnt, <= is a relational operator and it will return 1 if true and 0 if false, but where does it return in this code?
In the context of your code, <= is not a relational operator, it is an assignment operator. There are two types of assignment in Verilog:
blocking : =
non-blocking : <=
In a Verilog design, you
always use blocking assignments for combinational logic
always use non_blocking assignments for sequential logic
If you do not, you simulation will be indeterminate - it will not necessarily behave the same way every time you run it. Which, of course, is not good.
So, why is that? Well, to start you must learn that Verilog has 4 scheduling regions:
from prev time step
|
ACTIVE
|
INACTIVE
|
NBA
|
POSTPONED
|
V
to next time step
Blocking assignments are executed in the ACTIVE region. However, while the right-hand side of a non-blocking assignment is evaluated in the ACTIVE region, the assignment does not occur until the NBA region. This is key to why you need to use them for sequential logic.
So, why do you need to use non-blocking assignments for sequential logic? The reason is because the delay between evaluation of the right-hand side and assignment of the left hand side enables a Verilog simulation to be determinate, ie to behave the same way every time you run it. This delay means that the behaviour of the simulation does not depend on the order in which the always blocks are executed, which it would if only blocking assignments were used.
A simple analogy to the delay between evaluating the right-hand side of a non-blocking assignment and assigning the left-hand side is the clock-to-Q delay of a real flip-flop. In a real flip-flop, there is always a small delay (clock-to-Q delay) between the D input being sampled (by the clock) and the Q output being driven. This is vital to the correct operation of real sequential logic. For example, if there were no clock-to-Q delay in a real flip-flop instead of it taking exactly 4 clocks for the D input of the first flip-flop in a 4-stage shift register to get to the Q output of the fourth flip-flop, it could take any number of clocks between 1 and 4: its behaviour would also be indeterminate.

Verilog Blocking Assignment

I am somewhat new to Verilog. I know that in a Clock Process we should use non blocking assignments, and in a Non Clock processes, we use blocking assignments.
I have came across this code, when I was reading someone else's code.
reg iowrb_int,iowrb_met;
reg iordb_int,iordb_met;
always#(*)
begin
iowrb_int <= iowrb_met;
iordb_int <= iordb_met;
iowrb_met <= iowr_bar;
iordb_met <= iord_bar;
end
I am really not sure about the above code ! I don't think it is doing any registering, correct? Would it mean anything to have a non-blocking in a always#(*) statement ?
Is there any difference in using blocking vs non-blocking in a always#(*) statement ?
The main difference is:
a blocking assignment is executed before the next assignment i.e. it blocks the execution of the next statement.
non-blocking assignments execute in parallel i.e. they don't block the execution of the statement following them.
Suppose a = 2 and b = 3 then non-blocking assignments:
a <= 4;
b <= a;
results in a = 4 and b = 2 - value of a before assignment
But
a = 4;
b = a;
Will result in a=4 and b=4 - value of a after the blocking assignment completes.
A variable getting synthesized to a register (latch or flip-flop) vs. combinatorial logic depends on the sensitivity list of the always block. It does not depend on use of blocking or non-blocking assignment.
For example:
always #(*) begin
if (enable)
q = d;
end
This will result in a D-latch since assignment to q is not specified for when enable==0 so it needs to remember is last assignment.
While
always #(*) begin
if (enable)
q = d;
else
q = f;
end
This will result in a mux (combinatorial logic) since assignment to q is specified for both cases of enable and so q need not remember anything.
The blocking vs non-blocking is so that your gate level (synthesis) matches your RTL simulation. Using a different one to alter the behaviour of the simulation as far as I know will not effect synthesis and therefore the behaviour of gate-level.
<= non-blocking effectively take a temporary copy of the copy right-hand side, and make the = blocking assignment at the end of the timestep.
a <= b;
b <= a;
is equivalent to:
a_temp = b;
b_temp = a;
//
a = a_temp;
b = b_temp;
The example uses combinatorial logic, that is it contains no state, so all inputs must be defined by all outputs.
always#* begin
iowrb_int <= iowrb_met;
iordb_int <= iordb_met;
iowrb_met <= iowr_bar;
iordb_met <= iord_bar;
end
When the right hand side updates the block should be retriggered. Since iowrb_met is on both sides I am not sure what this implies interms of electrical connectivity.
while <= implies copying to a temp location, combinatorial logic does not have this capability, it is always and continuously driven by the assignment.
I think in simulation you effectively have this:
always#* begin
iowrb_int_temp = iowrb_met;
iordb_int_temp = iordb_met;
iowrb_met = iowr_bar;
iordb_met = iord_bar;
iowrb_int = iowrb_int_temp;
iordb_int = iordb_int_temp;
end
In hardware you would have:
always#* begin
iowrb_int = iowrb_met; //= iowr_bar;
iordb_int = iordb_met; //= iord_bar;
iowrb_met = iowr_bar;
iordb_met = iord_bar;
end
Where iowrb_int is effectively the same as iowrb_met
Flip-flops are implied using always #(posedge clk
Combinatorial logic is implied using always #* but latches can be implied when the output is not fully defined from inputs.
By only changing to code to blocking assignments it may synthesize to latches and/or create logical equivalency check mismatches depending on the tools handle.
This is how it looks through the scheduler:
With blocking:
The *_int signals are assigned
The *_met signals are assigned
Move on to the next time step.
*_int keeps the non-updated values of *_met
With non-blocking:
The *_int signals are assigned
The *_met signals are assigned
A change to *_met is detected causes a loop back the the Active region of the scheduler
Re-assign the *_int signals
Re-assign the *_int signals
Move on to the next time step.
*_int has the same values as *_met
Waste CPU time to reprocessing. This is not important on a small project, but can add noticeable overhead used throughout a large project.
The correct, logical equivalent, and CPU friendly way would be to revers the assignment order (assign *_met before *_int):
always#(*)
begin
iowrb_met = iowr_bar;
iordb_met = iord_bar;
iowrb_int = iowrb_met;
iordb_int = iordb_met;
end
The *_int signals are assigned
The *_met signals are assigned
Move on to the next time step.
*_int has the same values as *_met
OR use *_bar as the assigning value (i.e. if a==b and b==c, then a==b and a==c):
always#(*)
begin
iowrb_int = iowr_bar;
iordb_int = iord_bar;
iowrb_met = iowr_bar;
iordb_met = iord_bar;
end
The *_int and *_met signals are assigned
Move on to the next time step.
*_int has the same values as *_met
As others have said, changing to blocking assignments here will actually not work. Using blocking assignments in combinational always blocks (which is the recommendation) require you to put assignments in the right order.
Using non-blocking assignments in combinational always blocks may seem attractive, because you can then have assignments in any order, like in VHDL. Besides performance, one good reason to avoid this is that it doesn't work with always_comb. This code does not work:
always_comb begin
tmp <= in;
out <= tmp;
end
The reason is that tmp will not be part of the sensitivity list. It will work as expected if you use always #(*), always #(tmp, in) or replace with blocking assignments.

Resources