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 modulemodule 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.
Operator
Meaning
~
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).
// 8-input AND gate using reduction operatormodule and8(input logic [7:0] a, output logic y); assign y = &a;endmodule
π Related Resources
Structural Modeling
Building complex modules by connecting simpler ones.
// Build a 2-to-1 multiplexer from basic gatesmodule 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 y1endmodule
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; endendmodule# Testbenches## π‘ Explanation### Purpose of a TestbenchThe 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 ComponentsA 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` BlockThis 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:
Behavioral: Describes the functionality of the module using continuous assignments (assign) or procedural blocks (always). It focuses on the relationship between inputs and outputs.
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 Descriptionmodule nand3(input logic a, b, c, output logic y); logic n1; assign n1 = a & b & c; assign y = ~n1;endmodule