• Home   /  
  • Archive by category "1"

Verilog Multiple Non-Blocking Assignments To Same Variable On Both Sides

Assignment Statements¶

Blocking Assignment¶

A blocking assignment evaluates the expression on its right hand side and then immediately assigns the value to the variable on its left hand side:

It is also possible to add delay to a blocking assignment. For example:

In this case, the expression on the right hand side is evaluated and the value is held for 10 units of time. During this time, the execution of the code is blocked in the middle of the assignment statement. After the 10 units of time, the value is stored in the variable on the left

Nonblocking Assignment¶

A nonblocking assignment evaluates the expression on its right hand side without immediately assigning the value to the variable on the left. Instead the value is cached and execution is allowed to continue onto the next statement without performing the assignment. The assignment is deferred until the next blocking statement is encountered. In the example below, on the positive edge of clk the right-hand side of the first nonblocking assignment is evaluated and the value cached without changing a. Then the right-hand side of the second nonblocking assignment statement is evaluated is also cached without changing b. Execution continues until it returns to the event statement, once there the execution of the process blocks until the next positive edge of the clk. Just before the process blocks, the cached values finally assigned to the target variables. In this way, the following code swaps the values in a and b on every positive edge of clk:

Adding delay to nonblocking assignments is done as follows:

Using nonblocking assignment with delay in this manner is a way of implementing transport delay, as shown below:

always @(posedge clk) begin a <= b; b <= a; end
always @(*) a <= #10 b + c;

Blocking versus Nonblocking Assignment¶

Nonblocking statements allow you to schedule assignments without blocking the procedural flow. You can use the nonblocking procedural statement whenever you want to make several register assignments within the same time step without regard to order or dependence upon each other. It means that nonblocking statements resemble actual hardware more than blocking assignments.

Generally you would use nonblocking assignment whenever assigning to variables that are shared between multiple initial or always processes if the statements that access the variable could execute at the same time. Doing so resolves race conditions.

Blocking assignment is used to assign to temporary variables when breaking up large calculations into multiple assignment statements. For example:

always @(posedge clk) begin t1 = b + c; t2 = d + e; a <= t1*t2; end

Procedural Continuous Assignment¶

Two types of continuous assignment are available in initial and always processes: assign and force.

The target of an assign statement must be a register or a concatenation of registers. The value is continuously driven onto its target and that value takes priority over values assigned in procedural assignments. Once a value is assigned with an assign statement, it can only be changed with another assign statement or with a force statement. Execution of deassign releases the continuous assignment, meaning that the value of the register can once again be changed with procedural assignments. For example, the following implements a D-type flip-flop with set and reset:

Assign statements are used to implement set and reset because they dominate over the non-blocking assignment used to update q upon positive edges of the clock c. If instead a simple procedural assignment were used instead, then a positive edge on the clock could change q even if r or s were high.

A force statement is similar to assign, except that it can be applied to both registers and nets. It overrides all other assignments until the release statement is executed. Force is often used in testbenches to eliminate initial x-values in the DUT or to place it in a particular state. For example:

module dff(q, qb, c, d, r, s); output q, qb; input c, d, r, s; reg q; assign qb = ~q; always @(posedge c) q <= d; always @(r or s) begin if (r) assign q=0; else if (s) assign q=1; else deassign q; end endmodule
module dff_tb; reg c = 0, d = 1, r = 0, s = 0; wire q, qb; dff FF1 (q, qb, c, d, r, s); initial begin #1 force FF1.q = 0; #1 release FF1.q; #1 c = 1; #1 $strobe(q ? "pass" : "FAIL"); $finish; end endmodule

I have been having a really hard time understanding the difference between blocking and non-blocking assignments in Verilog. I mean, I understand the conceptual difference between the two, but I am really lost when it comes to implementation.

I referred to a number of sources, including this question, but all the explanations seem to explain the difference in terms of code (what happens to the sequence of execution of lines when using blocking vs non-blocking). My question is a little different.

While writing verilog code (since I am writing it to be synthesized on an FPGA), I always try to visualize what the synthesized circuit is going to look like, and that is where the problem begins :

1) I am not able to understand how the changing from blocking to non-blocking assignments would alter my synthesized circuit. For example :

In the above code, how would the synthesized circuit change if I replaced all the blocking assignments by non-blocking

2) Understanding the difference between blocking and non-blocking statements when written sequentially is a bit simpler (and most answers to this question focus on this part), but how do blocking assignments affect behaviours when they are declared in separate conditional behaviours. For example :

Would it make a difference if I wrote this:

or if I wrote this :

I know that conditional statements synthesize to become multiplexers or priority structures, and so I feel that using either blocking or non-blocking statements should not make a difference, but I am not sure.

3) When writing testbenches, I the result of the simulation is very different when using blocking v/s non-blocking statements. The behaviour is very different if I write :

versus when I write this :

This is very confusing. In my practice, the rx_done_tick signal is going to be generated by a Flip Flop. So, I think that non-blocking statements should be used to represent this behaviour. Am I right ?

4) Finally, when to use blocking assignments and when not to use non-blocking statements ? I.e is it true that blocking statements should be used only in combinational behaviours , and non-blocking statements in sequential behaviours only? If yes or No, why ?

fpgaverilogsynthesissystem-verilog

One thought on “Verilog Multiple Non-Blocking Assignments To Same Variable On Both Sides

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *