# 2. SystemVerilog Testbench
## What is the purpose of the Testbench?
* A testbench is used to verify a design’s functionality via simulation.
* It acts as a container for:
* Generating different input stimuli
* Driving inputs to the design
* Allowing the design to process inputs and generate outputs
* Checking outputs against expected values to identify bugs
* Modifying the design to fix any bugs found
* Repeating until no functional defects remain
## Component of Testbench
* The earlier example was not modular or reusable due to tight coupling between testbench and DUT.
* A proper testbench should include multiple components to separate concerns and make the system scalable and reusable.
* Below are the key components of a structured testbench:
| Component | Description |
|-------------|-----------------------------------------------------|
| Generator | Produces various input stimulus to send to the DUT |
| Interface | Holds design signals that can be driven or monitored |
| Driver | Sends the generated stimulus into the DUT |
| Monitor | Observes and captures DUT's input/output activities |
| Scoreboard | Compares DUT outputs against expected behavior |
| Environment | A wrapper that contains all components listed above |
| Test | Top-level container with configurable environment settings |
## What is DUT ?
* DUT stands for Design Under Test, the actual hardware design written in Verilog or VHDL that we want to verify.
* In pre-silicon verification, it is sometimes referred to as DUV (Design Under Verification).
* After the chip is fabricated (post-silicon validation), the term DUT is more commonly used.
* In a testbench, DUT is:
* Instantiated within the testbench module.
* Connected to testbench signals such as clk, en, wr, etc.
* Driven with stimuli and monitored for output correctness.
```
module tb_top;
reg clk;
wire en;
wire wr;
wire data;
design myDsn (
.clk (clk),
.en (en),
.wr (wr),
// ...
.rdata
);
endmodule
```
## What is Interface?
* If a design has hundreds of ports, directly connecting them becomes cumbersome and error-prone.
* SystemVerilog's interface allows grouping all input-output signals into a single container.
* This interface can be used to connect and drive signals to the DUT, making the testbench:
* More organized
* Easier to maintain
* Reusable and scalable
## What is Driver?
* The Driver is a verification component responsible for "pin-wiggling"—driving values onto DUT input signals.
* It does this via a task defined inside an interface.
* The Driver:
* Calls the task in the interface to apply input stimuli
* Doesn’t need to know the timing logic, which is encapsulated in the interface
* This abstraction allows:
* Better flexibility and scalability
* Ease of modification—if the interface changes, the same task can be re-implemented without changing the Driver logic
## How does the Driver know what to drive?
* The Generator is a verification component that creates valid data transactions.
* These transactions are sent to the Driver, which then drives the data to the DUT via the interface.
* Transactions are implemented as class objects (visualized as blue boxes).
* The Driver’s job is to:
* Receive the transaction object
* Translate it into pin-level signals the DUT can understand
## Why is a Monitor required?
* So far we’ve focused on how data is driven into the DUT, but verification also requires observing outputs.
* The DUT processes input data and produces outputs on its pins.
* The Monitor is responsible for:
* Capturing the output signals
* Converting them into a data object (transaction)
* Sending the object to the Scoreboard for checking against expected results
## What is the purpose of a Scoreboard?
* The Scoreboard often contains a Reference Model, which mimics the expected behavior of the DUT.
* The same input is sent to both:
* The DUT
* The Reference Model
* The Scoreboard compares:
* DUT output
* Reference Model output
* If there is a mismatch, it indicates a functional bug in the DUT.
* This comparison and checking logic is implemented inside the Scoreboard.
## Why is an Environment required?
* The Environment acts as a container for all verification components (like Generator, Driver, Monitor, Scoreboard, etc.).
* It makes the testbench more:
* Flexible – easy to reconfigure or extend
* Scalable – new components can be added as needed
* Using an Environment allows reuse of the verification infrastructure in future projects without starting from scratch.
## What does the Test do?
* The Test is the top-level module in the verification hierarchy.
* It:
* Instantiates the Environment
* Configures the Environment using parameters or settings specific to that test case
* We might have thousands of tests, so it’s not feasible to change the Environment logic every time.
* Instead, we introduce knobs or parameters in the Environment to make it configurable per test.
* This makes each test:
* Easier to control
* More reusable and maintainable
* The described testbench structure is good for simple designs (e.g. a 50-line counter).
* For complex projects, we need more abstraction and better modularity.
## What are Abstraction Levels?
* In the preface, signals were directly toggled using delays:
```
#5 resetn <= 0;
#20 resetn <= 1;
```
* Instead, we can encapsulate these signal manipulations into a task, such as apply_reset():
```
task apply_reset ();
#5 resetn <= 0;
#20 resetn <= 1;
endtask
```
* This introduces abstraction:
* Hides implementation details (timing, signal names)
* Makes the code more modular, reusable, and easier to read
* The test writer only needs to care about when and why to call the task, not how it works.
* Higher abstraction allows:
* Clean separation between what the test does and how it's implemented
* Simplified test development