Search code examples
verilogfpgahdlsequential

Verilog execution parallel or sequential if block along with another statement


The following is a verilog code
I'm trying to understand the working of statements inside an always block. I know the rule that blocking statements are written using = and non blocking use <= in verilog.I know the working of these.

What will happen if an if statement(with blocking statements) come in between blocking statements?

always(@posedge clk)
begin
  if(en1)
  begin
      out1=c;   //statement 1
      out2=c+1; //statement 2
      if(out2>5)
      begin
      out3=out1+out2;//statement 3
      end
      else
      out3=0;
      out4=out1-out2;
  end
end

The 'if statement' was synthesized into a multiplexer. Will it use the values updated in the previous statement1 ???Requirement is -The output should be such that the three statements were executed sequentially.

But when this is implemented in hardware the mux for ' if ' will be separate from the other adders.So I thought the if statement3 in between will work in parallel with statement 1 and 3.

I checked in simulation and the value taken is the latest value-ie as if it works sequentially.

My questions are
1.Is it correct to use 'if statements' in between other assignments. or should I use another method of programming.Will it run sequentially when blocking statements are used?
2.Will this work in all conditions as if sequentially?


Solution

  • The story here is very simple. In simulation all statements inside an always block are always executed sequentially, as in any programming language. The if statement will be executed after the assignment, as in the order given below.

      1> out1=c;   //statement 1
      2> out2=c+1; //statement 2
      3> if(out2>5)
           begin
      3a>      out3=out1+out2;//statement 3
         end
         else
      3b>     out3=0;
      4> out4=out1-out2;
    

    The above will work as in any generic programming language. The if will be taken if out1 > 5.

    The confusion is in in the blocking/non-blocking assignments. Verilog has a very special semantic for the <=, non-blocking assignment. Actually it is just a simulation artifact. It means that the rhs value will not be assigned to the lhs inside this particular always block. It will be done later, after all always blocks are evaluated.

    So, consider the following:

      out1=c;   //statement 1
      out2 <= c+1; //<<<< non blocking, assignment here, statement 2
      if(out2>5)
           begin
    

    Now, if c is 4 and the result of the rhs c+1 is 5, the if statement will still be taken, because out2 is not yet updated in this block. It will still have the previous value of 4. But the value of 5 will be assigned to it at the very end, after all the statements are evaluated. It will not be seen by the if statement till the next posedge of your clock.

    1.Is it correct to use 'if statements' in between other assignments. or should I use another method of programming.Will it run sequentially when blocking statements are used?

    it depend on what you are trying to achieve here. Could be correct or not

    1. Will this work in all conditions as if sequentially?

    As i explained above. You have to understand one thing though. Verilog is not a hardware description language. It is a language for describing desired behavior of hardware and gets interpreted by synthesis tools. Therefore you can run into a situation when your simulation results will not match behavior of the synthesized schematic. To minimize this possibility you should use verilog programming practices accepted in the industry. One of them: use non-blocking assignments for the real outputs of the edge-controlled blocks. There are compelling reasons for doing so. From this perspective your example is completely wrong.