On increasing digital design complexity, the designer has to find out the optimum algorithm and architecture to implement in hardware. Hence, the designer needs a way that can describe the design as per algorithm behavior. The Verilog provides the facility to represent the behavior of design at a high-level abstraction similar to C language programming.
Structured Procedure blocks
Verilog provides two structured procedural blocks.
- initial block
- always block
initial block in Verilog
The initial block executes only once and starts its execution at the beginning of a simulation.
- It is a non-synthesizable block and it can not contribute to building design schematic development.
- Multiple statements are enclosed within ‘begin’ and ‘end’ keywords and statements are executed sequentially.
- Multiple initial blocks are valid in a module and each block executes at zero simulation time. An individual block may finish their execution independently.
- Nested initial blocks are not valid.
- It can execute in zero time or take some time depending on the delay involved.
initial <single statement> initial begin <statement 1> <statement 2> <statement 3> ... ... end
Use of initial block:
The initial block is used for
- Initialize variables
- Implementing a testbench code
- Monitoring waveforms and other processes that are executed only once during the entire simulation.
- Drive ports with specific values.
Basic initial block that executes in zero simulation time.
module tb; reg i1; reg [3:0] i2; initial begin i1 = 0; i2 = 4'h5; $display("i1 = %0h, i2 = %0h", i1, i2); end endmodule
i1 = 0, i2 = 5
Multiple initial blocks
module tb; reg i1; reg [3:0] i2; initial i1 = 0; initial begin i2 = 4'h5; $display("i1 = %0h, i2 = %0h", i1, i2); end initial begin #5; i1 = 1; i2 = 4'h8; $display("i1 = %0h, i2 = %0h", i1, i2); end endmodule
i1 = 0, i2 = 5 i1 = 1, i2 = 8
Terminate simulation using $finish system task
module tb; reg i1; reg [3:0] i2; initial begin #5; i1 = 1; i2 = 4'h8; $display("i1 = %0h, i2 = %0h", i1, i2); #5 i1 = 0; i2 = 4'h2; $display("i1 = %0h, i2 = %0h", i1, i2); end initial #6 $finish; endmodule
i1 = 1, i2 = 8 $finish called from file "testbench.sv", line 18. $finish at simulation time 6
always block in Verilog
The always block starts its execution at the beginning of the simulation and continues to execute in a loop.
- Similar to the initial block, the always block is executed sequentially.
- Based on changes in single or multiple signals in the sensitivity list, always block is executed.
- If no sensitivity list is specified, always block executes repeatedly throughout the simulation.
- Multiple always blocks are valid in a module and each block executes independently.
- Nested always blocks are not valid.
always <single statement> always @(<sensitivity_list>) <single statement> always @(<sensitivity_list>) begin <statement 1> <statement 2> <statement 3> ... ... end
Use of always block
- To model repetitive activity in a digital design. Ex. clock generation.
- To implement combinational and sequential elements in digital circuits.
The sensitivity list can be a single or multiple signals placed within parentheses () after @ operator. Based on the change in any signal value, it allows executing the always block.
If the sensitivity list includes all inputs, then only ‘*’ is used to represent all inputs instead of writing all inputs.
always @(i1 or i2 or i3) begin <statements> end
Based on the change in signal value in anyone of the i1, i2, or i3 signals, the always block will be executed.
In the below example, the signal clk value changes after every 5 time-units.
The time period of the clock = 10 time-units.
module tb; reg clk; initial clk = 0; always #5 clk = ~clk; initial begin $monitor("At t = %0d, clk = %0b", $time, clk); #50 $finish; end endmodule
At t = 0, clk = 0 At t = 5, clk = 1 At t = 10, clk = 0 At t = 15, clk = 1 At t = 20, clk = 0 At t = 25, clk = 1 At t = 30, clk = 0 At t = 35, clk = 1 At t = 40, clk = 0 At t = 45, clk = 1
It is mandatory to put a delay in always block while generating the clock otherwise, simulation hangs due to zero-delay infinite loop.
always clk = ~clk; // causes simulation hang
Always block with a sensitivity list
module and_gate(input i1, i2, i3, output reg out); always@(i1 or i2 or i3) begin out = i1 & i2 & i3; end // or //always @(*) out = i1 & i2 & i3; endmodule
At T = 0: i1 = 0, i2 = 0, i3 = 0, out = 0 At T = 5: i1 = 0, i2 = 1, i3 = 0, out = 0 At T = 13: i1 = 1, i2 = 1, i3 = 0, out = 0 At T = 16: i1 = 1, i2 = 1, i3 = 1, out = 1