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
todata
after 10 time units. - The second statement assigns the value
8'h11
todata
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
todata
after 10 time units. - The
fork
begins after that, and two parallel operations occur:- The first parallel operation assigns
8'h11
todata
after 20 time units. - The second parallel operation assigns
8'h00
todata
after 10 time units (because it starts at the same time).
- The first parallel operation assigns
- 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 thefork
block has started.
Nested Parallel Blocks
You can also use begin
and end
inside a fork
–join
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 bydata = 8'haa
30 time units later.
Order of Execution:
data
will first be assigned8'h11
at 20 time units.data
will be assigned8'h00
at 30 time units.- Finally,
data
will be assigned8'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 Block | Keywords | Execution Order | Delay Handling | Use Case |
---|---|---|---|---|
Sequential Block | begin and end | Executes one after another | Delays are relative to previous statement | Use when operations need to happen in a specific order |
Parallel Block | fork and join | Executes in parallel | Delays are set independently | Use 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.