πŸ“Œ Overview

A testbench is a SystemVerilog module created to test another module, known as the Device Under Test (DUT). The testbench generates input signals for the DUT and (optionally) checks if the output signals are correct. Testbenches are for simulation only and are not synthesizable into hardware.


🎯Learning Objectives

  • Know what a hardware description language is used for. βœ… 2025-09-28
  • Describe a simple combinational circuit in SystemVerilog. βœ… 2025-09-28
  • Describe a structural (hierarchical) circuit in SystemVerilog. βœ… 2025-09-28
  • Understand how delay times are used during SystemVerilog simulation. βœ… 2025-09-28
  • Write a simple testbench for a combinational circuit in SystemVerilog. βœ… 2025-09-28
  • Understand the purpose and structure of SystemVerilog testbenches. βœ… 2025-09-28

βž— Formulas


✍️ Notes

Hardware Description Languages

Overview

A Hardware Description Language (HDL) is a specialized computer language used to describe the structure and behavior of electronic circuits, and most commonly, digital logic circuits.

  • Specifies logic function: Defines the functionality of hardware at different levels of abstraction.
  • Simulation: Allows for the simulation of the intended hardware to verify its correctness before fabrication.
  • Synthesis: Can be used to generate the final hardware layout, creating an optimized netlist of components.

Key HDLs

  • SystemVerilog: An extension of Verilog, it is one of the most widely used HDLs in the industry.
  • VHDL: Known for its verbosity, it was developed by the US Department of Defense.

HDLs vs. Programming Languages

While HDLs share syntactic similarities with traditional programming languages, their execution model is fundamentally different.

  • Parallel Execution: In an HDL, all operations are concurrent, reflecting the parallel nature of hardware.
  • Hardware Modeling: Each statement in an HDL corresponds to a piece of hardware.
  • Modularity: Designs are composed of interconnected modules that are active simultaneously.

IMPORTANT: When writing in an HDL, it is crucial to think about the hardware that the code will produce.


Simulation and Synthesis

HDLs serve two primary purposes in the design flow:

  • Simulation:

    • Process: Inputs are applied to the HDL model, and a simulator computes the corresponding outputs.
    • Benefit: Allows for debugging in a virtual environment, which is significantly more cost-effective than debugging physical hardware.
  • Synthesis:

    • Process: A logic synthesizer transforms the HDL code into a netlist, which is a detailed description of the gates and their interconnections.
    • Optimization: The synthesizer optimizes the design to minimize the amount of hardware required.

Hardware Description Languages (HDLs)

HDLs like SystemVerilog are used to model digital hardware. Unlike software, HDL code runs in parallel.

// This module describes an inverter.
// 'a' is the input, 'y' is the output.
module inv(input logic a, output logic y);
  assign y = ~a; // 'y' is the logical NOT of 'a'
endmodule

SystemVerilog Modules

Modules are the basic building blocks. They have inputs and outputs called ports.

// A 2-input AND gate module
module and2(input  logic a, b,
            output logic y);
  assign y = a & b;
endmodule

Combinational Logic

πŸ“ Summary

Combinational logic in SystemVerilog is described using bitwise operators, signals (scalars and vectors), reduction operators, and conditional assignments. These constructs allow for the modeling of logic gates, multiplexers, and other circuits whose outputs depend solely on their current inputs.


πŸ’‘ Explanation

Bitwise Operators

These operators perform logic operations on a bit-by-bit basis.

OperatorMeaning
~Bitwise NOT
&Bitwise AND
``
^Bitwise XOR

Signals and Vectors

Signals can be single-bit (scalar) or multi-bit (vector). Vectors are declared with a range, e.g., logic [7:0] my_vector;. Bitwise operators can be applied to entire vectors, performing the operation on each corresponding pair of bits.

Reduction Operators

A reduction operator takes a vector as input and produces a single-bit output by applying the operation across all bits of the vector.

  • &a: Reduction AND (1 if all bits of a are 1)
  • |a: Reduction OR (1 if any bit of a is 1)
  • ^a: Reduction XOR (1 if there is an odd number of 1s in a)

Conditional Assignment (Ternary Operator)

The ?: operator allows for conditional signal assignment, which is a concise way to describe a multiplexer. assign y = s ? d1 : d0; means β€œif s is true, y gets d1, else y gets d0”.

Numbers

Numbers can be specified with a size, base, and value (e.g., 8'hAF).

  • Size: in bits.
  • Base: b (binary), d (decimal), o (octal), h (hex).
  • Underscores (_) can be used for readability.

πŸ–ΌοΈ Diagrams & Visuals

// 4-bit 2-to-1 Multiplexer
module mux2(input  logic [3:0] d0, d1,
            input  logic       s,
            output logic [3:0] y);
  assign y = s ? d1 : d0;
endmodule
// 8-input AND gate using reduction operator
module and8(input  logic [7:0] a,
            output logic       y);
  assign y = &a;
endmodule

Structural Modeling

Building complex modules by connecting simpler ones.

// Build a 2-to-1 multiplexer from basic gates
module mux2(input  logic d0, d1, s,
            output logic y);
  logic s_n, y0, y1;
 
  inv inv_s(s, s_n);          // Invert select signal
  and2 and_0(d0, s_n, y0);   // y0 = d0 AND (NOT s)
  and2 and_1(d1, s, y1);     // y1 = d1 AND s
  or2  or_y(y0, y1, y);      // y = y0 OR y1
 
endmodule

Testbenches

A module used to simulate and verify the correctness of another module (the β€œDevice Under Test” or DUT).

module test_and2();
  logic a, b, y;
 
  // Instantiate the module we want to test
  and2 dut (.a(a), .b(b), .y(y));
 
  // Apply test inputs
  initial begin
    a=0; b=0; #10; // Wait 10 time units
    a=0; b=1; #10;
    a=1; b=0; #10;
    a=1; b=1; #10;
  end
endmodule
 
# Testbenches
 
## πŸ’‘ Explanation
### Purpose of a Testbench
The primary goal of a testbench is to verify the functional correctness of a design. It does this by:
1.  **Instantiating** the Device Under Test (DUT).
2.  **Generating** and applying a sequence of input stimuli to the DUT.
3.  **Observing** the outputs and comparing them against expected values.
 
### Key Components
A typical testbench has the following structure:
*   It is a module, but usually with no input or output ports.
*   Internal signals (`logic`) are declared to connect to the DUT's ports.
*   The DUT is instantiated within the testbench.
*   An `initial` block is used to define the sequence of input stimuli. This block executes only once at the beginning of the simulation.
*   Delays (`#10`) are used to control the timing of input changes, allowing the DUT time to respond.
 
### `initial` Block
This is a procedural block that contains sequential statements.
*   `a = 0; b = 0; c = 0;`: Sets initial values for the input signals.
*   `#10;`: A delay statement that pauses the execution within the block for a specified number of time units. After the delay, the next statement is executed.
 
---
 
## πŸ–ΌοΈ Diagrams & Visuals
 
> ```systemverilog
> // Device Under Test (DUT)
> module sillyfunction(input  logic a, b, c,
>                      output logic y);
>   assign y = ~b & ~c | a & ~b;
> endmodule
>
> // Testbench
> module testbench1();
>   // Signals to connect to DUT
>   logic a, b, c;
>   logic y;
>
>   // Instantiate device under test
>   sillyfunction dut(a, b, c, y);
>
>   // Apply inputs every 10 time-units
>   initial begin
>     a = 0; b = 0; c = 0; #10;
>     c = 1;               #10;
>     b = 1; c = 0;         #10;
>     c = 1;               #10;
>     a = 1; b = 0; c = 0; #10;
>     c = 1;               #10;
>     b = 1; c = 0;         #10;
>     c = 1;               #10;
>   end
> endmodule
> ```
 
---
 
## πŸ“š Related Resources
 
  - [[2025-09-08_topic_SystemVerilog-Modules]]

οΏ½ Resources

  • Presentation:

❓ Post lecture

SystemVerilog Modules

πŸ“ Summary

A module is the fundamental building block in SystemVerilog. It encapsulates a design and interfaces with the external environment through ports. Modules can be described behaviorally (what it does) or structurally (how it’s built from other modules).


πŸ’‘ Explanation

Module Definition

A module is defined using the module and endmodule keywords. It has a name and a list of ports.

  • Ports: These are the inputs and outputs of the module. They are declared with a direction (input, output), a type (e.g., logic), and a name.
  • Data Types: The logic data type is commonly used for signals and can hold four values: 0, 1, x (unknown/uninitialized), and z (high-impedance).

Behavioral vs. Structural Descriptions

There are two main ways to describe the internal logic of a module:

  1. Behavioral: Describes the functionality of the module using continuous assignments (assign) or procedural blocks (always). It focuses on the relationship between inputs and outputs.
  2. Structural: Describes the module as a netlist of interconnected sub-modules (instances). This creates a hierarchical design.

Concurrency

A key concept in HDLs is that all statements inside a module execute in parallel, reflecting the concurrent nature of hardware. The order in which assign statements or module instances are written does not affect the final circuit.


πŸ–ΌοΈ Diagrams & Visuals

// Behavioral Description
module nand3(input  logic a, b, c,
             output logic y);
  logic n1;
  assign n1 = a & b & c;
  assign y = ~n1;
endmodule
// Structural Description
module nand3(input  logic a, b, c,
             output logic y);
  logic n1;
  and3 i1 (a, b, c, n1);  // Instance of and3 module
  inv  i2 (n1, y);       // Instance of inv module
endmodule


πŸ“– Homework