In Verilog, block statements are used to group a set of instructions together. These grouped statements behave like a single statement in terms of syntax. There are two types of block statements in Verilog: sequential blocks and parallel blocks.

Sequential Block Statements

Sequential blocks in Verilog are executed one after the other. The statements inside the block are enclosed within begin and end keywords. Each statement waits for the previous one to finish before it begins. The delays between statements are calculated relative to the previous one.

Example of a Sequential Block

module design0;
    bit [31:0] data;

    // "initial" block starts at time 0
    initial begin
        // After 10 time units, data becomes 0xfe
        #10 data = 8'hfe;
        $display ("[Time=%0t] data=0x%0h", $time, data);

        // After 20 time units, data becomes 0x11
        #20 data = 8'h11;
        $display ("[Time=%0t] data=0x%0h", $time, data);
    end
endmodule

Explanation:

  • In the code above, the initial block runs at time 0.
  • The first statement assigns the value 8'hfe to data after 10 time units.
  • The second statement assigns the value 8'h11 to data 20 time units later.
  • Notice that the second statement executes after the first one, so the total delay from the start is 30 time units.

Simulation Log Output

[Time=10] data=0xfe
[Time=30] data=0x11

As shown in the log, the first value of data is displayed at time 10, and the second at time 30, based on the delay times.

Parallel Block Statements

Parallel blocks allow multiple statements to execute simultaneously. These blocks are enclosed within the fork and join keywords. This is useful when you want to run several tasks at the same time, such as updating multiple variables concurrently.

Example of a Parallel Block

initial begin
    #10 data = 8'hfe;
    fork
        #20 data = 8'h11;
        #10 data = 8'h00;
    join
end

Explanation:

  • The first statement assigns 8'hfe to data after 10 time units.
  • The fork begins after that, and two parallel operations occur:
    • The first parallel operation assigns 8'h11 to data after 20 time units.
    • The second parallel operation assigns 8'h00 to data after 10 time units (because it starts at the same time).
  • The join keyword ensures that the block waits for all the parallel statements to finish before moving on.

Key Behavior:

  • The first statement (data = 8'h00) will execute first since it has a shorter delay (10 time units).
  • The second statement (data = 8'h11) executes 20 time units later, after the fork block has started.

Nested Parallel Blocks

You can also use begin and end inside a forkjoin block to organize more complex parallel executions.

Example of a Nested Parallel Block

initial begin
    #10 data = 8'hfe;
    fork
        #10 data = 8'h11;
        begin
            #20 data = 8'h00;
            #30 data = 8'haa;
        end
    join
end

Explanation:

  • The first parallel operation (data = 8'h11) happens 10 time units after the initial assignment.
  • The second parallel operation (data = 8'h00) occurs 20 time units after the initial assignment, followed by data = 8'haa 30 time units later.

Order of Execution:

  • data will first be assigned 8'h11 at 20 time units.
  • data will be assigned 8'h00 at 30 time units.
  • Finally, data will be assigned 8'haa at 60 time units.

Naming Blocks for Better Control

Both sequential and parallel blocks can be named for easier management. Naming blocks helps in referencing them in a disable statement, allowing control over specific blocks.

Syntax for Named Blocks:

begin : name_seq
    [statements]
end

fork : name_fork
    [statements]
join

Example:

initial begin
    fork : fork_block
        #10 data = 8'h11;
        #20 data = 8'h00;
    join
end

In this example, the fork block is named fork_block. This name can be used later to disable or control the execution of the block.

Summary of Block Types

Type of BlockKeywordsExecution OrderDelay HandlingUse Case
Sequential Blockbegin and endExecutes one after anotherDelays are relative to previous statementUse when operations need to happen in a specific order
Parallel Blockfork and joinExecutes in parallelDelays are set independentlyUse when operations can run concurrently

Conclusion

Verilog provides two types of block statements: sequential and parallel. Sequential blocks execute statements one by one, while parallel blocks allow multiple statements to execute at the same time. Using these blocks effectively can help you create complex and efficient hardware designs. Don’t forget to name your blocks for better organization and control, especially when debugging or using disable statements.


Scroll to Top