A Verification Plan defines what needs to be verified, how it will be verified, and how we will determine whether the design is sufficiently tested.
๐น Directed Testing Specific test scenarios are created to verify known and important behaviors.
๐น Random Testing Inputs are generated randomly to explore a wider range of possible scenarios and uncover unexpected bugs.
๐น Assertions Assertions continuously check whether specific design properties or rules are satisfied during simulation.
Example 1 โ Directed Test: For a FIFO, explicitly write data until it becomes FULL, then verify that another write is rejected.
Example 2 โ Random Test: Generate random read/write operations and compare the DUT output against a reference model.
๐ฏ A good verification plan combines multiple techniques rather than relying on only one.
The Verification Methodology Manual (VMM) introduced a structured approach to developing reusable and scalable verification environments.
๐น VMM techniques were originally developed for use with the OpenVera language.
๐น In 2005, these techniques were extended for SystemVerilog.
๐น VMM was preceded by the Reference Verification Methodology (RVM) for Vera.
VMM helped establish systematic verification practices such as:
- ๐งฉ Reusable verification components
- ๐งช Constrained-random testing
- ๐ Functional coverage
- ๐ Structured test environments
- ๐ฏ Scalable verification methodologies
Without a methodology, a large verification environment can become difficult to maintain and reuse.
Example 1: A reusable bus verification component can be used across multiple projects.
Example 2: A standardized test structure makes it easier for multiple verification engineers to work on the same project.
๐ Next: Understanding how verification methodologies evolved toward modern SystemVerilog/UVM-based verification.
The primary purpose of a testbench is to determine the correctness of the Design Under Test (DUT).
A testbench accomplishes this through the following steps:
1๏ธโฃ Generate Stimulus Create input transactions that exercise the DUT.
2๏ธโฃ Apply Stimulus to the DUT Drive the generated inputs into the DUT.
3๏ธโฃ Capture the Response Observe and collect the DUT's outputs.
4๏ธโฃ Check for Correctness Compare the actual response with the expected response and identify errors.
5๏ธโฃ Measure Progress Against Verification Goals Determine how much of the design functionality has been exercised and whether the verification objectives are being achieved.
Not every verification activity is performed automatically.
๐น Some steps can be automated by the testbench, such as stimulus generation, monitoring, and checking.
๐น Other decisions are manually determined by the verification engineer, such as defining scenarios, expected behavior, and verification goals.
๐ The verification methodology you choose determines how these activities are structured and carried out.
Generate โ Apply โ Capture โ Check
For an ALU, the testbench may:
- ๐ฏ Generate random operands and operations
- ๐ฅ Apply them to the ALU
- ๐ค Capture the result
- ๐ Compare it with a reference model
- ๐ Track which operations have been verified
For a FIFO, the testbench may:
- ๐ Generate read/write transactions
- ๐ฅ Apply them to the FIFO
- ๐ Monitor output data and status flags
- ๐ Compare read data against expected data
- ๐ Track coverage of FULL, EMPTY, READ, and WRITE scenarios
Generate โ Apply โ Capture โ Check โ Measure
๐ 1.4 Directed Testing
Directed testing is a verification approach where you study the hardware specification and create a verification plan containing a list of specific tests.
Each test focuses on a particular set of related features of the DUT.

๐ฏ Basic Approach
Specification โ Verification Plan โ Test Cases โ DUT โ Check Results
๐น Identify the features from the specification. ๐น Create specific test cases for those features. ๐น Apply the required stimulus. ๐น Check whether the DUT behaves correctly.
๐ก Example 1 โ UART
Suppose the UART specification has:
Start-bit detection 8-bit data transmission Parity Stop-bit detection
You could create separate directed tests:
๐งช Test 1 โ Verify start-bit detection ๐งช Test 2 โ Verify different data patterns ๐งช Test 3 โ Verify parity ๐งช Test 4 โ Verify stop-bit detection ๐ก Example 2 โ FIFO
For a FIFO, directed tests could target:
๐งช Write until FULL ๐งช Read until EMPTY ๐งช Attempt write when FULL ๐งช Attempt read when EMPTY ๐ Directed vs Random Testing
In the first image, the dashed line represents random testing and the solid line represents directed testing.
The important idea is that random testing can reach different coverage points quickly, while directed testing progresses through explicitly planned scenarios.
๐ Key Point: Directed testing is predictable and targeted, but writing enough directed tests for a complex design can become time-consuming.
1.4.1 Constrained-Random Stimulus: Although you want the simulator to generate the stimulus, you donโt want totally random values. You use the SystemVerilog language to describe the format of the stimulus (โaddress is 32-bits; opcode is ADD, SUB or STORE; length < 32 bytesโ), and the simulator picks values that meet the constraints.
๐ 1.5 Methodology Basics
๐น 1. Constrained-Random Stimulus ๐ฒ
๐น 2. Functional Coverage ๐
๐น 3. Layered Testbench Using Transactors ๐งฉ
๐น 4. Common Testbench for All Tests โป๏ธ
๐น 5. Keep Test-Specific Code Separate ๐งฉ
๐ Key Takeaway:
A good verification methodology is not just about finding bugs. It is about creating a reusable and measurable process for demonstrating that the DUT meets its specification.
๐ 1.6 What Should You Randomize?
๐น 1. Device Configuration โ๏ธ
๐น 2. Environment Configuration ๐
๐น 3. Input Data ๐ฅ
๐น 4. Protocol Exceptions
๐น 5. Errors and Violations ๐จ
๐น 6. Delays โฑ๏ธ
๐ Key Takeaway
Don't simply randomize everything.
The useful strategy is:
๐ฒ Randomize โ ๐ Constrain โ ๐งช Stimulate โ ๐ Check โ ๐ Measure Coverage
๐ฌ 1.7 The Testbench โ Design Environment
The testbench wraps around the Design Under Test (DUT), similar to how a hardware tester connects to a physical chip. ๐งช TESTBENCH
๐ฏ Basic Testbench Function
The testbench performs two main activities:
๐ฅ Provide Stimulus โ Sends inputs to the DUT ๐ค Capture Responses โ Observes and checks DUT outputs
๐ 1.8 Testbench Components โ Bus Functional Models (BFMs)
A testbench can contain multiple Bus Functional Models (BFMs). For example, ๐ต AMBA ๐ข USB ๐ PCI ๐ฃ SPI
๐ Key Takeaway
Testbench = More than just stimulus
A well-structured testbench can contain:
๐ฏ Tests โ ๐ฆ Transactions โ ๐ Transactors/BFMs โ ๐ DUT Interface โ ๐ Monitors โ ๐ Checkers
๐ก A Flat Testbench : When you fi rst learned Verilog and started writing tests, they probably looked like the low-level code inSample 1.1 , which does a simplifi ed APB (AMBA Peripheral Bus) Write. (VHDL users may have written similar code).
๐งช Sample 1.1 โ Driving the APB Pins
This example demonstrates a basic low-level Verilog testbench that directly drives APB signals, performs a write operation, and checks the result.
module test(PAddr, PWrite, PSel, PWData, PEnable, Rst, clk);
// Port declarations omitted...
initial begin
// ๐ Drive reset
Rst <= 0;
#100 Rst <= 1'b1;
// ๐ฏ Drive the APB control bus
@(posedge clk);
PAddr <= 16'h50;
PWData <= 32'h50;
PWrite <= 1'b1;
PSel <= 1'b1;
// โฑ๏ธ Enable APB access
@(posedge clk);
PEnable <= 1'b1;
@(posedge clk);
PEnable <= 1'b0;
// ๐ Check the result
if (top.mem.memory[16'h50] == 32'h50)
$display("Success");
else
$display("Error, wrong value in memory");
$finish;
end
endmodule ๐ Description ๐ Reset: Initializes the DUT into a known state. ๐ฏ APB Control Bus: Drives address, data, write, and select signals. โฑ๏ธ PEnable: Enables the APB access for one clock cycle. ๐ Result Check: Verifies that 32'h50 was correctly written to address 16'h50. ๐ $finish: Ends the simulation.
๐ Key Point: This is pin-level testing, where the testbench directly controls the DUT's interface signals.
๐งช Sample 1.2 โ Task to Drive APB Pins
A task is used to make APB write operations reusable.
task write(reg [15:0] addr, reg [31:0] data); @(posedge clk); PAddr <= addr; PWData <= data; PWrite <= 1'b1; PSel <= 1'b1;
@(posedge clk);
PEnable <= 1'b1;
@(posedge clk);
PEnable <= 1'b0;
endtask
๐ Key Point: Instead of driving APB pins repeatedly, simply call:
write(16'h50, 32'hABCD);
๐ Task = Reusable APB write operation.
๐งช Sample 1.3 โ Low-Level Verilog Test
This example shows a simple Verilog test using the tasks from Sample 1.2.
๐น Test Flow Reset โ Write Data โ Check Result โ Finish ๐ reset() โ Resets the DUT. โ๏ธ write(16'h50, 32'h50) โ Writes data into memory. ๐ Checks whether memory location 16'h50 contains 32'h50. โ Match โ Success โ Mismatch โ Error ๐ $finish โ Ends simulation.
๐ Key Point: Sample 1.3 is called a low-level Verilog test because the test still directly depends on Verilog tasks and DUT-level details.
๐ Sample 1.1: Directly drives APB pins ๐ Sample 1.2: Encapsulates pin driving into a task ๐ Sample 1.3: Uses the task to create a complete test case
๐ The Signal and Command Layers
๐ 1. Signal Layer
๐ 2. Command Layer
๐ Driver โ Converts commands into DUT input signals. ๐ Monitor โ Observes DUT output signals and groups them into commands. ๐ฏ Assertions โ Check individual signals and behavior across complete commands.
๐ฌ Figure 1.10 โ Testbench with Functional Layer The Functional Layer is added above the Command and Signal layers to work with high-level functionality.
๐ Functional Layer Components โ๏ธ Agent โ Connects the functional layer with the command layer. ๐ Scoreboard โ Compares expected results with actual results. ๐ Checker โ Determines whether the DUT behavior is correct.
๐ฏ The Scenario Layer The Scenario Layer is the highest layer of the testbench. It is driven by the Generator and defines complete, realistic operations that the DUT should perform.
๐ What is a Scenario?
A scenario is a sequence of operations that represents a particular use case or task.
For example, in a music player:
๐ต Play music from storage
๐ฅ Download a new song
๐ Adjust volume
โฉ Change tracks

๐ฌ Fig. 1.12 โ Full Testbench with All Layers
This figure shows a complete layered testbench, including the Scenario, Functional, Command, and Signal layers.
๐ Main Components
๐งช Test โ Starts and controls the verification scenario.
๐ฏ Generator โ Generates scenarios/transactions.
โ๏ธ Agent โ Connects the generator to the lower-level components.
๐ Driver โ Converts transactions into DUT signals.
๐ Assertions โ Check signal-level and protocol behavior.
๐ Monitor โ Observes DUT signals and collects responses.
๐ Scoreboard โ Compares expected and actual results.
โ
Checker โ Determines whether the DUT behavior is correct.
๐ Functional Coverage โ Measures which required functionality has been exercised.

๐งช Exercise 1 โ ALU Verification Plan ๐ DUT Specifications ๐ Reset: Asynchronous, active HIGH โฑ๏ธ Clock: Input clock ๐ฅ A: 4-bit signed input ๐ฅ B: 4-bit signed input ๐ค C: 5-bit signed registered output โ๏ธ C updates: Positive edge of clock ๐ข Opcodes: 4 operations
solution: module alu ( input logic clk, input logic reset, input logic signed [3:0] A, input logic signed [3:0] B, input logic [1:0] opcode, output logic signed [4:0] C );
always_ff @(posedge clk or posedge reset) begin
if (reset)
C <= 5'sd0;
else begin
case (opcode)
2'b00: C <= A + B;
2'b01: C <= A - B;
2'b10: C <= ~A;
2'b11: C <= |B;
endcase
end
end
endmodule
module alu_tb;
logic clk;
logic reset;
logic signed [3:0] A, B;
logic [1:0] opcode;
logic signed [4:0] C;
// Opcode definitions
localparam ADD = 2'b00;
localparam SUB = 2'b01;
localparam INV = 2'b10;
localparam RED_OR = 2'b11;
// DUT
alu dut (
.clk (clk),
.reset (reset),
.A (A),
.B (B),
.opcode (opcode),
.C (C)
);
// Clock generation
always #5 clk = ~clk;
initial begin
clk = 0;
reset = 0;
A = 0;
B = 0;
opcode = ADD;
// Asynchronous active-high reset
#2 reset = 1;
#2 reset = 0;
// ADD
A = 4'sd5;
B = 4'sd3;
opcode = ADD;
@(posedge clk);
#1 $display("ADD: A=%0d B=%0d C=%0d", A, B, C);
// SUB
A = 4'sd7;
B = 4'sd3;
opcode = SUB;
@(posedge clk);
#1 $display("SUB: A=%0d B=%0d C=%0d", A, B, C);
// INVERT A
A = 4'b1010;
opcode = INV;
@(posedge clk);
#1 $display("INV: A=%b C=%b", A, C);
// REDUCTION OR B
B = 4'b0001;
opcode = RED_OR;
@(posedge clk);
#1 $display("RED_OR: B=%b C=%b", B, C);
$finish;
end
endmodule
๐ Chapter 2 โ SystemVerilog Data Types
SystemVerilog provides improved data types and data structures for better performance, less memory, and easier verification.
๐น Key Features โก Two-State Types โ bit, int โ better performance & less memory ๐ฆ Queues โ Variable-size storage with built-in push/pop ๐ Dynamic Arrays โ Size decided at runtime ๐ Associative Arrays โ Key-based storage & searching ๐๏ธ Classes & Structures โ Organize complex data ๐ Unions & Packed Structures โ Multiple views of same data ๐ Strings โ Built-in text handling ๐ข Enumerated Types โ Readable and meaningful values ๐ฏ Main Benefit
SystemVerilog = Flexible + Efficient + Verification-friendly data structures ๐
๐ 2.1 โ Built-In Data Types
SystemVerilog provides several built-in data types for storing different kinds of data.
๐น Main Categories ๐ข Integer Types โ bit, logic, reg, int, integer ๐ค String Type โ string ๐ข Enumerated Type โ enum ๐ฆ Structure Type โ struct ๐ Union Type โ union โญ Important Classification
2-State: bit, byte, shortint, int, longint
โก๏ธ Stores only 0 and 1 โก
4-State: logic, reg, integer, time
โก๏ธ Stores 0, 1, X, Z ๐ฌ
๐ฏ Remember
2-state โ 0, 1 4-state โ 0, 1, X, Z
int i; // 32-bit, 2-state, signed int unsigned ui; // 32-bit, 2-state, unsigned
byte b8; // 8-bit signed shortint s; // 16-bit signed longint l; // 64-bit signed
integer i4; // 32-bit, 4-state signed time t; // 64-bit, 4-state unsigned real r; // floating-point
| Type | States | Size | Signed? |
|---|---|---|---|
bit |
2-state | 1 bit | โ Unsigned |
bit [31:0] |
2-state | 32 bit | โ Unsigned |
int unsigned |
2-state | 32 bit | โ Unsigned |
int |
2-state | 32 bit | โ Signed |
byte |
2-state | 8 bit | โ Signed |
shortint |
2-state | 16 bit | โ Signed |
longint |
2-state | 64 bit | โ Signed |
integer |
4-state | 32 bit | โ Signed |
time |
4-state | 64 bit | โ Unsigned |
real |
2-state | 64-bit floating point | โ |
๐ง Easy Memory Trick 2-state: 0, 1 โก 4-state: 0, 1, X, Z ๐ฌ Signed: Can represent โ positive and โ negative numbers.
๐ 2.2 Fixed-Size Arrays Fixed-size array = Array whose size is known at compile time and cannot change during simulation. ๐ฆ
SystemVerilog has the $clog2() function that calculates the ceiling of log base 2,
๐ 2.2.2 โ Array Literal
An array literal is a way to initialize an array with values directly using '{' and '}'. ๐งฉ

๐ 2.2.3 โ Basic Array Operations: for & foreach Both for and foreach are used to access array elements. ๐ข
๐ Basic Array Operations โ Copy & Compare
๐ Bit and Array Subscripts โ Together at Last
SystemVerilog allows you to combine bit/part-selects with array indexes. ๐ข
Verilog-2001 Improvement โ Double Comma in $display
This is a small but useful improvement in Verilog-2001. ๐ ๏ธ
๐น Double Comma ,,
In a $display statement, using two commas inserts a space in the output.
Example 1๏ธโฃ $display("Hello",,"World");
Output:
Hello World Example 2๏ธโฃ int a = 10; int b = 20;
$display("a =",a,,"b =",b);
๐ 2.2.6 โ Packed Arrays
A packed array is a collection of bits stored continuously next to each other in memory. ๐ข
With a single subscript, you get a word of data, barray[0] .With two subscripts, you get a byte of data, barray[0][3] . With three subscripts, you can access a single bit, barray[0][1][6] . Because one dimension is specifi ed after the name, barray[5] , that dimension is unpacked, so you must always give at least one subscript.
๐ 2.2.8 โ Choosing Between Packed and Unpacked Arrays
The choice depends on what you want the array to represent. ๐ข
๐น Waiting for Array Changes
The @ operator can be used with scalar values and packed arrays.
For example:
logic [7:0] barray[4];
@(barray[0]); // โ Legal
But:
@(barray); // โ Not legal
because barray is an unpacked array.
To wait for any element of the unpacked array to change:
@(barray[0] or barray[1] or barray[2] or barray[3]); ๐ง Remember ๐ข Packed array โ useful for scalar conversion and @ event control. ๐ฆ Unpacked array โ useful for storing separate elements/memory. โณ @ works with scalars and packed arrays, not an entire unpacked array.
๐ 2.3 โ Dynamic Arrays
A dynamic array is an array whose size can be decided and changed at runtime. ๐
A dynamic array is declared with empty word subscripts [] . This means that you do not specify the array size at compile time; instead, give it at run time. The array is initially empty, so you must call the new[] constructor to allocate space, passing in the number of entries in the square brackets. If you pass an array name to the new[] constructor,
๐ 2.4 โ Queues
A queue is a variable-size array that stores elements in a specific order. ๐ฆA queue is declared with word subscripts containing a dollar sign: [$] . The elements of a queue are numbered from 0 to $
if you put a $ on the left side of a range, such as [$:2] , the $ stands for the minimum value, [0:2] . A $ on the right side, as in [1:$] , stands for the maximum value, [1:2]
๐ Chapter 2.5 โ Associative Arrays in SystemVerilog ๐ฌ ๐ง 1. What is an Associative Array?
An Associative Array is an unpacked array where elements are accessed using a key/index instead of a fixed size. ๐
It is useful when:
๐ You don't know the number of elements in advance. ๐ You want to access data using meaningful keys. ๐พ You want to avoid allocating unused memory. โ๏ธ Syntax data_type array_name [index_type];
๐ Chapter 2.6 โ Array Methods in SystemVerilog ๐ฌ SystemVerilog provides built-in array methods to search, sort, locate, count, and manipulate array elements. ๐ ๏ธ
๐งฉ 1. Types of Array Methods
Array methods can be broadly divided into:
Category Methods ๐ Searching find(), find_index(), find_first(), find_last() ๐ข Counting sum(), count() ๐ Sorting sort(), rsort() ๐ Ordering reverse(), shuffle() ๐งฎ Reduction sum(), product(), and(), or(), xor() ๐ฆ Size/Manipulation size(), delete()
๐ 2.6.3 โ Array Sorting and Ordering ๐ข
SystemVerilog provides built-in methods to sort, reverse, and randomly rearrange array elements. These methods are very useful in verification for organizing transactions and test data. ๐งช
The main methods are:
Method Purpose sort() โฌ๏ธ Ascending order rsort() โฌ๏ธ Descending order reverse() ๐ Reverse existing order shuffle() ๐ฒ Randomly rearrange
Answers:
a. Byte in systemVerilog is 8-bit signed by default -128 to +127
b. my_integer = 32โb0000_1111_xxxx_zzzz; my_int = my_integer; binary = 0000_0000_0000_0000_0000_1111_0000_0000 hex = 00000f00
c. my_bit =16โh8000; 16'h8000 = 1000 0000 0000 0000 2^15 = 32768
d.my_short_int1 = my_bit; binary = 0000_1000_0000_0000 = decimal 2048
c. my_short_int2 = my_short_int1 - 1; binary in 2โcomplement form = 0111_1111_1111_1111 decimal = 32767
