SystemVerilog introduced the program block to address the needs of testbench development. It provides a dedicated context for writing verification code that interacts with the design under test (DUT). While similar in structure to the traditional module, the program block serves a specific purpose and has distinct characteristics.
This article explores the program block, its features, and how it differs from the module block, with examples to illustrate its usage.
What is a Program Block?
A program block in SystemVerilog is a construct designed specifically for testbenches. It encapsulates verification logic, ensuring a clear separation between testbench code and the DUT. The program block introduces synchronization semantics to avoid race conditions between the testbench and the design.
Key Features of the Program Block
- Verification Context: Dedicated for writing testbenches and verifying DUT behavior.
- It can’t contain always block, modules, interfaces or other programs.
- Non-blocking assignments are not allowed inside program block.
- Automatic Scheduling: Provides a built-in mechanism to avoid race conditions by scheduling procedural statements in the Reactive region of the SystemVerilog event queue.
- One-Time Execution: Designed to execute procedural code only once, making it ideal for stimulus generation.
Syntax
program program_name;
// Declarations
// Procedural code
endprogram
Example: Comparing Program and Module
Design (DUT):
In this example we create a design module where we initialize the value of y. We will write the testbench first with program block and then with module block. After then, we will compare the output of both.
module design_ex(output logic [3:0] y);
initial begin
y <= 4'h2;
end
endmodule
Testbench with Program Block:
program design_tb(input logic[3:0] y);
initial begin
$display("y = %0h", y);
end
endprogram
module top();
logic [3:0] y;
//instantiate design
design_ex dut(.y(y));
//instatntiate testbench
design_tb test_bench(.y(y));
endmodule
Output:
y = 2
When we are using testbench with program block, we are getting output as 2.
Testbench with module Block:
Now let’s try the testbench with module block.
module design_tb(input logic[3:0] y);
initial begin
$display("y = %0h", y);
end
endmodule
module top();
logic [3:0] y;
//instantiate design
design_ex dut(.y(y));
//instatntiate testbench
design_tb test_bench(.y(y));
endmodule
Output:
y = x
Here we are getting value of y is x because of race condition.
So, The program block in System Verilog offers a structured and race-free environment for writing verification logic, making it a powerful tool for modern testbenches. While similar in structure to a module, the program block is tailored for verification tasks, offering synchronization and preventing race conditions with the DUT.