4.1 Verilog Procedural Blocks
Category Verilog Tutorial
Keywords: initial, always
There are two types of procedural block statements: initial and always. They are the two fundamental statements for behavioral modeling.
A module can contain multiple initial and always statements, but these two types of statements cannot be nested.
These statements are executed in parallel across modules and are not related to their order within the module.
However, within an initial or always statement, it can be understood as sequential execution (except for non-blocking assignments).
Each initial or always statement generates an independent control flow, and the execution time starts from time 0.
Initial Statement
The initial statement starts executing at time 0 and is executed only once. Multiple initial blocks are independent of each other.
If an initial block contains multiple statements, the keywords begin and end must be used to form a block statement.
If an initial block contains only one statement, the keywords begin and end can be used or omitted.
In theory, the initial is not synthesizable and is often used for initialization, signal detection, etc.
Modify the code from the previous section slightly for simulation, and the code is as follows.
Example
`timescale 1ns/1ns
module test;
reg ai, bi;
initial begin
ai = 0;
#25; ai = 1;
#35; ai = 0; //absolute 60ns
#40; ai = 1; //absolute 100ns
#10; ai = 0; //absolute 110ns
end
initial begin
bi = 1;
#70; bi = 0; //absolute 70ns
#20; bi = 1; //absolute 90ns
end
//at proper time stop the simulation
initial begin
forever begin
#100;
//$display("---gyc---%d", $time);
if ($time >= 1000) begin
$finish;
end
end
end
endmodule
The simulation results are as follows:
It can be seen that the two initial process statements assign values to the signals ai and bi without affecting each other.
The values of signals ai and bi change in the order of assignment, so the statements inside the initial can also be considered as sequential execution.
Always Statement
In contrast to the initial statement, the always statement is executed repeatedly. The always statement block starts executing the behavioral statements from time 0; after executing the last statement, it starts executing the first statement of the block again, and so on.
Due to the characteristic of repeated execution, the always statement is often used for generating simulation clocks, detecting signal behavior, etc.
The following code uses always to generate a 100MHz clock source and stops the simulation at 1010ns.
The code is as follows:
Example
`timescale 1ns/1ns
module test;
parameter CLK_FREQ = 100; //100MHz
parameter CLK_CYCLE = 1e9 / (CLK_FREQ * 1e6); //switch to ns
reg clk;
initial clk = 1'b0; //clk is initialized to "0"
always #(CLK_CYCLE/2) clk = ~clk; //generating a real clock by reversing
always begin
#10;
if ($time >= 1000) begin
$finish;
end
end
endmodule
The simulation results are as follows:
It can be seen that the clock cycle is the desired 100MHz. And the simulation stops at 1010ns.
Source Code Download
-1.3 Setting up the Verilog Environment
-2.2 Numeric Representation in Verilog
-2.5 Verilog Compilation Instructions
-3.1 Continuous Assignment in Verilog
-[3.2 Time Delay in