I'm learning verilog, I have read some tutorials but i'm a bit confused about this:
When and why to use the "assign" keyword and when and why use the "<=" operators. In what context? It is clear for me the difference between "<=" and "=", being nonblocking and blocking, but beside that, some literature start by working with "assign" and others don't even use this keyword.
Example:
assign var_z = x|~y
var_z <= a + b
Thank you.
assign
is used for driving wire/net type declarations. Since wires change values according to the value driving them, whenever the operands on the RHS changes,the value is evaluated and assigned to LHS( thereby simulating a wire).
Continuous assignments drive values into the nets whenever the right-hand side value changes, hence continuous assignments are always active and assignments occur whenever the right-hand side operands changes.
Continuous assignments provide a models combinational logic at a higher level of abstraction than Gate-Level logic.
always
is a procedural block is used for modelling registers and combinational logic. always
block contains sensitivity list, that is, the event list, upon which the logic inside the block must be evaluated.
always(@ posedge clk)
triggers the the logic inside the block at every positive edge. Thereby modelling a flop kind of behavior.
always @ (*)
is sensitive to all the RHS statements. If anything in the RHS of the always block changes,that particular expression is evaluated and assigned. This is similar to assign
statement, but this type of block is used to drive a reg
datatype.
// var_z needs to be driven continuously
// Evaluated when any of x or y changes
assign var_z = x|~y
Refer to assign statement and Continuous assignments for more information.
Coming to blocking and non-blocking statements:
A blocking statement must be executed before the execution of the statements that follow it in a sequential block.
Non blocking statements allow you to schedule assignments without blocking the procedural flow.
Blocking and non-blocking assignments are better understood by following example:
x = #10 5; // x = 5 at time 10ns
y = #5 6; // y = 6 at time 15ns
x <= #10 5; // y = 6 at time 10ns
y <= #5 6; // y = 6 at time 5ns
Here, in blocking assignment, y
is evaluated after x
is assigned a value. While using non-blocking assignment, x
and y
are evaluated and pushed into simulators internal queue and assigned at 10ns
and 5ns
respectively.
A blocking assignment effects immediately. A nonblocking assignment takes place at the end of processing the current "time delta".
So, intuitively, we can say that since combinational blocks needs continuous driving, use of blocking statements must be done. While, to model sequential hardware, that holds or retains a value, non-blocking assignments must be used.
// model a flop var_z
var_z <= a+b;
Pipeline modelling cal effectively be done by non-blocking assignments. Consider a shift register example:
// Improper hardware, q3 is directly assigned the value of d
always @(posedge clk) begin
q1 = d;
q2 = q1;
q3 = q2; end
// Proper hardware, q3=q2, q2=q1 and q1=d
always @(posedge clk) begin
q1 <= d;
q2 <= q1;
q3 <= q2; end
The above example models proper hardware while using nonblocking assignments. Refer to CummingsSNUG2000SJ_NBA paper, this link for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With