Forum Discussion

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

Basic Verilog questions: sequential execution within a procedural block

Code1:always @ (*) begin

<delay1> out1 =/<= a && b;

end

always @ (*) begin

<delay2> out2 =/<= c || d;

end

always @(*) begin

<delay3> final_out =/<= out1 || out2;

end

Code 2:always @ (*) begin

<delay1> out1 =/<= a && b;

<delay2> out2 =/<= c || d;

<delay3> final_out =/<= out1 || out2;

end

Observations:

1. When delay = 0; code 2 behaves the same way as code 1.

2. When you put a delay value, Code 2 != Code 1, this is because within a process between begin and end, all statements are sequential. That means final_out does not get evaluated after <delay3> but instead it takes <delay1> + <delay2> + <delay3>. This does not happen in real hardware.

My question:

1. I have never come across any verilog material that mentions this point why is that?

2. What is the right structure ?

1 Reply

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

    First of all, combinatorial processes should always use simple procedural assignments '=', never non-blocking assignments (NBA) '<='. NBAs in Code 2 will cause that process to execute multiple times unnecessarily because the values of out1 and out2 are not visible the first time through.

    You normally do not see any delays in RTL code unless that RTL code needs to interface with gate-level code in the same simulation. Those delays are only needed on the boundaries of the RTL code and usually specified with continuous assignments or buffers with delays added.

    If your RTL code is made of simple Boolean equations, then the structure does not matter. But as soon as you start adding more procedural statements like if/else and case, etc., then you want to group things together in a single block so you don't have to repeat those statements.