Tutorials
Learn More
Program Block
In Verilog, a module is a basic building block that contains wires, tasks, function declaration, continuous and procedural statements, and hierarchies of other modules. The module construct behaves perfectly w.r.t. design implementation, while developing a testbench an engineer has to take care to avoid a race condition between design and testbench. The program block is sensitive to the design signals changes that are declared in the module block are scheduled in the reactive region of the time slot.
Syntax:
program <program_name> <port_list>;
...
endprogram
Program block purpose
- All elements within the program block are scheduled to execute in the reactive region. This helps to avoid race-around conditions between design and testbench.
- It provides an execution entry point for the testbench.
- It encapsulates testbench data in a single container.
Similarities between program and module block
- A program block can instantiate another program block in the way how the module is instantiated another module block.
- Both can have no or more inputs, inout, and output ports.
- Both can have tasks, functions, variable declaration.
- Both can have continuous assignments, initial blocks, concurrent assertions, generate blocks, etc.
Difference between program and module block
- A program block can not instantiate a module block. On the opposite side, a module block can instantiate another module or program block.
- A program block can not have an interface, user-defined primitives (UDP), always block or nested program.
- The initial block inside the program block is scheduled in the reactive region whereas the initial blocks inside the module lock are scheduled in the active region.
How program block avoid race around condition?
To understand it clearly, below two points need to be cleared.
- As per System Verilog scheduling semantic, System Verilog events are scheduled in the following order.
Active region → Non-blocking region → Reactive region. - The non-blocking assignments (RHS) are evaluated in the active region and updates their LHS in the NBA region (Non-blocking region).
When the design module assigns some value to a variable in the initial block and the testbench module tries to access the same variable (in the initial block) and perform some action, race around condition is expected to occur.
Race around situation example
Let’s understand with the below example, the design module has assigned out <= 2 and the testbench module wants to do some action based on design update (here, value is printed for simplicity).
Design Code:
module dut_example (output bit [3:0] out);
initial begin
out <= 2;
end
endmodule
In the active region of a time slot, the RHS value of non-blocking assignment out (<= 2;) is evaluated, LHS value is not yet updated. At the same time, testbench tries to access the variable that has an older value (default value in this case). Thus, the testbench operation will be affected.
Race around solution example using program block
To resolve this race around the condition, a program block is used that executes in the reactive region. By the time the reactive region is scheduled, the out variable value would have updated to 2 in the NBA region.
System Verilog Tutorials