all about vlsi DV
System Verilog Program Structure — module, program, initial
1. Introduction
Once you move beyond basic syntax in System Verilog, the first real confusion beginners face is:
-
Why does my simulation sometimes behave differently?
-
Why does SystemVerilog have both module and program?
-
What exactly does initial control?
This topic appears very frequently in interviews, but more importantly, it directly affects whether your simulation code is safe or unsafe.
A key point to understand early is this:
Code can compile, simulate, and still be logically unsafe.
This article explains why that happens and how SystemVerilog prevents it.
2. Before Anything Else: Design vs Testbench (No Assumptions)
Before discussing keywords, we must clearly separate two ideas.
What is Design (DUT)?
Design (DUT – Design Under Test):
-
Represents real hardware
-
Meant to be synthesized
-
Describes how a circuit behaves
In System Verilog, design is written using module.
Example designs:
-
Flip-flop
-
Counter
ALU
What is a Testbench?
A testbench:
-
Is not hardware
-
Exists only in simulation
-
Drives inputs to the design
-
Observes outputs from the design
You can think of a testbench as a test program for hardware.
Even in simple testbenches, two roles exist:
-
Driver → applies inputs
-
Checker → checks outputs
System Verilog introduces the program block specifically for testbench code.
3. What Is the Difference Between module and program? (Snippet Target)
In System Verilog, a module models hardware and executes in the active simulation region, while a program models testbench behavior and executes after all modules to prevent race conditions.
In short:
-
module → hardware
-
program → testbench
Quick Comparison
Feature Module Program
Purpose Hardware modeling Testbench modeling
Synthesizable Yes No
Simulation Region Active Reactive
Can Race with DUT Yes No
Intended Use Design Verification
4. Why This Distinction Matters (The Core Problem)
In simulation:
-
The design samples inputs on clock edges
-
The testbench drives those inputs
If both execute at the same simulation time, then:
-
Sometimes the design sees the old value
-
Sometimes the new value
-
The language gives no guarantee
This situation is called a race condition.
A race condition means behavior depends on execution order, not logic.
5. Where initial Fits (Important Clarification)
initial:
-
Runs once when simulation starts
-
Does not control priority
-
Executes according to where it is declared
Key rule:
initial defines what runs,
module vs program defines when it runs.
6. Unsafe Code Example — Works but Is NOT Safe
This code may appear to work, but it is not guaranteed by the language.
❌ NOT SAFE — Testbench as module
module dut(input logic clk, input logic a, output logic y);
always_ff @(posedge clk)
y <= a;
endmodule
module testbench;
logic clk, a, y;
dut d1(.clk(clk), .a(a), .y(y));
initial clk = 0;
always #5 clk = ~clk;
initial begin
a = 0;
#10 a = 1; // changes exactly at posedge
#1 if (y !== 0) $error("RACE: y sampled new value");
#10 $finish;
end
endmodule
Why This Is Unsafe
-
DUT and testbench are both module
-
Both execute in the same simulation region
-
Order is not guaranteed
-
Behavior depends on simulator scheduling
No syntax error.
No compile error.
But language-level unsafe.
7. Safe Code Example — Deterministic and Correct
Now we fix only one thing:
Move the testbench into a program.
✅ SAFE — Testbench as program
module dut(input logic clk, input logic a, output logic y);
always_ff @(posedge clk)
y <= a;
endmodule
program testbench;
logic clk, a, y;
dut d1(.clk(clk), .a(a), .y(y));
initial clk = 0;
always #5 clk = ~clk;
initial begin
a = 0;
#10 a = 1; // same timing as before
#1 if (y !== 0) $error("THIS SHOULD NEVER HAPPEN");
#10 $finish;
end
endprogram
Why This Is Safe
-
DUT (module) executes first
-
Testbench (program) executes after
-
Sampling happens before driving
-
Execution order is guaranteed by SystemVerilog
Same logic.
Different scheduling.
Only one is correct.
8. Key Takeaway (This Is the Core Insight)
-
Code can work and still be unsafe
-
Race conditions do not always show visible errors
-
System Verilog program exists to remove undefined behavior
This is why verification engineers care about this distinction.
9. Common Beginner Mistakes
-
Writing entire testbench using module
-
Assuming delays (#) fix race conditions
-
Believing initial controls execution order
Mixing synthesizable logic inside program
10. Interview Perspective
Interviewers are not asking:
“Does the code run?”
They are asking:
“Is the behavior guaranteed by the language?”
Strong one-line answer:
Program prevents race conditions between testbench and RTL.
11. Knowledge Check
-
Why can two modules race in simulation?
-
What guarantee does program provide?
-
Does initial decide execution order?
If you can answer these clearly, you understand the topic.
12. What’s Next
Now that execution order and structure are clear, the next confusion beginners face is:
“Which data types should I use, and why?”
👉 Next Article:
System Verilog Data Types — logic, bit, reg, wire
This topic is both:
-
Highly interview-relevant
Critical for writing correct code