Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Verilog: Concept on Blocking assignment and always

i read an article about blocking assignment.

module fbosc1 (y1, y2, clk, rst);

output y1, y2;

input clk, rst;

reg y1, y2;

always @(posedge clk or posedge rst)

if (rst) y1 = 0; // reset

else y1 = y2;

always @(posedge clk or posedge rst)

if (rst) y2 = 1; // preset

else y2 = y1;

endmodule

Case1

If the first always block executes first after a reset, both y1 and y2

will take on the value of 1.

Case2

If the second always block executes first after a reset, both y1 and y2

will take on the value 0.

Question:

1. How is the flow for above case in terms of always block and blocking

assignment?

2. if reset = 1, y1=0 and y2=1, isn't it? i don understand the

explaination above. So, Try to explain in details.

Thanks a lot

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Question:

    1. How is the flow for above case in terms of always block and blocking

    assignment?

    2. if reset = 1, y1=0 and y2=1, isn't it? i don understand the

    explaination above. So, Try to explain in details.

    --- Quote End ---

    Dear jasonkee111,

    when you are talking about the simulation semantics of verilog, your remark is correct. For synthesis however the signal assignments within an

    always @(posedge clk or posedge rst)
    construct will be synthesized as D type flip-flops. The

    if (rst) ...   ; 
    construct within the always will be synthesized as sets or presets of the flipflops. The rest of the code will determine the combinatorial logic at the input of the flip-flops.

    As a result of this. The two flip flops will be reset in the beginning at the correct level: y1 = 0 and y2 = 1. After that the two flip-flops will toggle at each positive edge of the clock signal.

    When writing this code with blocking or non-blocking statements the two descriptions will have the same behavior.

    If you want to have your simulation correspond to the synthesized circuit you could use the non-blocking construct in this case.

    Within an always construct blocking and non-blocking constructs could of course have different semantics in the determination of what circuit is being synthesized.

    Hope this helps...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi jasonkee111,

    sanmao is right about synthesis - these constructs will be recognized as D-flops

    However, to directly answer your question, how could the simulation behavior differ depending on which always block executes first after reset:

    Your circuit will typically have many always blocks that update on the rising edge of clock. The way event-driven simulators calculate the results for all of these processes, is (with non-blocking assignments) to determine the new values but don't let the new values take effect until a short time in the future.

    No matter what order these two block are evaluated, the current instantaneous values of y1 and y2 will be used to determine the future values, and the future values will take effect a short time later.

    always @(posedge clk) y1 <= y2;

    always @(posedge clk) y2 <= y1;

    However if you do this:

    always @(posedge clk) y1 = y2;

    always @(posedge clk) y2 = y1;

    You are immediately, instantaneously updating the variables y1 and y2, you are not waiting for "some time in the future" for the updates to take effect. If the simulator evaluates the first block first, y1 will get y2, and then y2 will get the new value of y1 which is y2 also ! If the simulator evaluates the second block first, y2 will get y1, and then y1 will get the new value of y2 (which is y1).

    The whole point of <= is to allow simulators to model many things that "happen at once" and then let the updates take place afterwards, so that order doesn't matter. After all, digital logic is all operating in parallel.

    The whole point of = is to allow the user to calculate a value with programming language constructs, in zero time.

    Hope this helps too...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The previous posts have basically answered the question but I'll throw in my 2 cents if it helps.

    1 - The first thing I always tell beginners is never use a blocking assignment '=' inside a clocked always block. If you know what you are doing it's fine and can be useful but in general just don't do it and it's certainly not necessary. Use non-blocking assignments '<=' for all clocked processes. Use blocking assignments '=' in combinatorial always blocks. This one rule will save you many headaches. Once you're experienced and truly understand the language, you can violate this rule. Mixing blocking and non-blocking assignments inside an always block can confuse people so I've seen many company's prohibit it in their coding standards.

    2 - The problem has to do with the simulator. The simulator processes the code and detects these two always blocks. Because they are separate from each other, the simulator is free to schedule them however it wants. So you have no idea which always block the simulator will choose to execute first and it can and will very between simulators. Because the statements within the always block are blocking, they are executed immediately.

    So if we follow the simulator's execution with the blocking assignment:

    1 - reset is applied. y1 = 0; y2 = 1;

    2 - reset is removed.

    3 - posedge clk occurs.

    4 - Simulator evaluates 2nd always block first.

    . 4a - y2 = y1 (which is 0) so y2 = 0;

    5 - Simulator evaluates 1st always block next.

    . 5a - y1 = y2(which has been set to 0) so y1 = 0;

    Now let's follow the simulators execution with non-blocking assignments:

    1 - reset is applied. y1 = 0; y2 = 1;

    2 - reset is removed.

    3 - posedge clk occurs.

    4 - Simulator evaluates 2nd always block first.

    . 4a - y2 is scheduled to be set to the current value of y1. so y2_next = 0; (current value of y2 is still 1).

    5 - Simulator evaluates 1st always block next.

    . 5a - y1 is scheduled to be set to the current value of y2. so y1_next = 1; (current value of y1 is still 0).

    6 - All always blocks have been evaluated. Simulator executes scheduled assignments.

    . 6a y2 = y2_next = 0;

    . 6b y1 = y1_next = 1;

    Jake
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The same example is used in Cliff Cummings' Verilog courses (Sunburst Design). It's possible the poster grabbed the example from one of those courses.

    For example, page 9-4 of the Expert Verilog-2001 course Rev. 200701 uses it.

    Jake
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It is correct that the article i read is Cumming's SNUG-2000 paper nonblocking assignments in verilog synthesis, coding styles that kill!

    Jakobjones, ur explaination helps me a lot,

    thanks