1
\$\begingroup\$

I'm learning Verilog with some background in VHDL and C. I would like to know if Verilog if blocks are executed concurrently or not, and if this is IDE- or vendor-dependent.

For example, are the following always equivalent or never equivalent, or sometimes equivalent, depending on something I'm not aware of?

always @ (posedge clk)
begin
    if (x == 1'b1) begin
        // do something
    end

    // possibly other code

    if (y == 1'b1) begin
        // do something else
    end

    // possibly other code
end

versus

always @ (posedge clk)
begin
    if (y == 1'b1) begin
        // do something else
    end

    // possibly other code

    if (x == 1'b1) begin
        // do something
    end

    // possibly other code
end

The if blocks and the "// possibly other code" chunks of code always execute sequentially, correct? My understanding is that the two blocks above should never be the same in Verilog because the line-by-line sequence is different.

I've read that "statements in procedural blocks are executed sequentially", implying that the code should be synthesized to execute in hardware line-by-line. However it is unclear to me if the blocks themselves are processed sequentially, and simulating with just one behavioral simulator doesn't address the question of how universal Verilog synthesis is supposed to be.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ You are using words interchangeably when they have very different meanings: "executed", "synthesized", "processed", "simulated". A synthesis tool will process the statements sequentially but (if you use non-blocking assignments) will synthesize concurrent logic. A simulator tool will also process the statements sequentially but (again assuming non-blocking assignments) the output signals are updated simultaneously. You can only talk about executing an HDL if you are running a testbench, and then it doesn't make sense to talk about synthesis. \$\endgroup\$ Commented Jul 5, 2019 at 20:01

2 Answers 2

6
\$\begingroup\$

Sequentially. Statements within an always block are evaluated sequentially, doesn't matter if blocking or non blocking assignments are used - nonblocking assignments are simply deferred assignments, a subsequent nonblocking assignment to the same reg in the same always block will override the first. Same goes for if statements, you can define a "default" value with a blocking or nonblocking statement, then override it later in the same always block. Last assignment in the block wins.

Note that when I say "evaluated sequentially", this does not mean the lines are evaluated in hardware one at a time. If there are no data dependencies, they will effectively be evaluated in parallel, and then the ordering will determine the precedence. Each if statement condition gets converted to an enable signal, and this signal can then drive mux selects, enables, etc. The ordering simply determines which enable signal takes precedence.

The code examples that you have are perfectly valid synthesizable code. They may or may not be equivalent depending on how x and y are assigned (for example, if the values are changed with blocking statements in the same always block) or if the same regs are assigned in different sections of the code (the last assignment wins, no matter if blocking or nonblocking assignments are used).

Recently, I have taken to putting my reset code in an if statement at the bottom of sequential always blocks so I can preferentially reset what needs to be reset without extra dependencies on the reset signal (gating) that occur when you put the whole block in an if (rst) else block.

\$\endgroup\$
4
\$\begingroup\$

In Verilog the statements inside the if... begin end are treated as concurrent if the code in them uses non-blocking assignments. They’re sequential if blocking assignments are used. So if the individual statements are non-blocking, the order of the surrounding ‘if’ blocks doesn’t matter. If there are blocking statements, and there are dependencies in the variables, then the order of the ‘if’ statements will matter.

More about blocking vs. non-blocking here: http://www.asic-world.com/tidbits/blocking.html

More: @alex.forencich makes a very good point about how the Verilog compiler interprets multiple assignments to the same variable. The last statement in order ends up being dominant over the previous statements.

That is,

if (a)  begin
    x <= y;
end

if (b) begin
    x <= z;
end

Gets interpreted the same as:

if (b) begin
    x <= z;
end else if (a) begin
    x <= y;
end

So in this case, again, the influence of ordering of the ‘if’ blocks depends on what’s in the ‘if’ statements.

In summary, if there dependencies (blocking statements with common variables) or common left-hand side assignments, then the if-block order matters. If there aren’t, it doesn’t.

My opinion is, depending on the if-block order to express the priority of your logic is a bit sketchy. Yes, having an if (reset) ... at the end in your always @ block works, but it’s not as clear to the reader as the more typical if (reset) .... else ... structure.

\$\endgroup\$
7
  • \$\begingroup\$ What I'm not clear on is if an IF block is always considered non-blocking or blocking, since this could potentially affect the ways they're executed after synthesis. \$\endgroup\$
    – Bort
    Commented Jul 5, 2019 at 19:19
  • \$\begingroup\$ The if statement is rolled up as part of the assignments that it contains. It is elaborated as qualifier on each line within its begin... end block.So the blocking statements will be inferred as sequential, and the non blocking ones parallel. \$\endgroup\$ Commented Jul 5, 2019 at 19:21
  • \$\begingroup\$ So you're saying all the blocking statements in an if block are executed sequentially and all the non-blocking are executed concurrently, once the if block evaluates true. Are you also saying that the if block's conditional is evaluated as a concurrent statement, and so all the if blocks at the same "indent" level can execute in any order? \$\endgroup\$
    – Bort
    Commented Jul 5, 2019 at 19:31
  • 2
    \$\begingroup\$ Think of it this way: you could rewrite the entire if statement block as a sequence of conditional assignments ( y = (a) ? b : c). That’s basically what synthesis does when it elaborates an IF block. \$\endgroup\$ Commented Jul 5, 2019 at 19:43
  • 1
    \$\begingroup\$ They are not concurrent, they are always sequential. Last assignment to the same reg in the same always block wins, same for both blocking and nonblocking assignments. Nonblocking assignments simply defer the actual assignment. \$\endgroup\$ Commented Jul 7, 2019 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.