Not Gate - UVM - TB - FLOWpdf
Not Gate - UVM - TB - FLOWpdf
WITH
NOT Gate Design
This NOT gate design is a simple combinational circuit that inverts the input
signal. There is no clock or reset involved, making the design straightforward
and purely combinational.
Testbench Architecture
Design.V
endmodule
Interface
not_if is an interface that bundles two signals, in and out, which are of type logic.
This interface would typically be used in a testbench or connected to a DUT where
in is an input and out is an output, perhaps for a simple NOT gate or similar logic.
Using an interface like this simplifies connections in complex designs and enhances
code readability by grouping related signals.
Sequence Item
// Randomizable fields
rand bit in; // Input value to be randomized
bit out; // Output value to be used in the sequence item
// Constructor
function new(string name = "seq_item");
super.new(name); // Call the parent class constructor with the given name
endfunction
endclass
The constructor new initializes the class by calling the parent class's constructor
with an optional name parameter.
uvm_object_utils_begin(seq_item) and uvm_object_utils_end — These macros
provide utilities for the seq_item class, such as factory registration and field
automation.
uvm_field_int(in, UVM_ALL_ON) and uvm_field_int(out, UVM_ALL_ON) — These
macros register the in and out fields for automatic reporting, recording, and
comparison, with full access.
This class represents a sequence item in UVM, typically used to generate stimuli for
verification purposes, with the ability to randomize input values and track outputs.
Sequence
// Constructor
function new(string name ="base_seq");
super.new(name); // Call the parent class constructor
endfunction
endclass
This class is used to define and execute a sequence of operations on seq_item objects,
including item creation, randomization, and management within the UVM sequence
framework.
Sequencer
// Constructor
function new(string name="sequencer", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor with the
given name and parent
endfunction
endclass
This class sets up the sequencer component that manages the sequence of seq_item
transactions in a UVM testbench environment.
Driver
// Constructor
function new(string name="driver", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor with the
given name and parent
endfunction
// Drive the value onto the DUT via the virtual interface
vif.in <= req.in;
// Indicate that the item has been processed
seq_item_port.item_done();
endclass
• virtual not_if vif — Defines a virtual interface to interact with the DUT.
This class drives sequence items onto the DUT and performs necessary checks and
logging to ensure correct operation.
Monitor
// Constructor
function new(string name="monitor", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor with the
given name and parent
item_collect_port = new("item_collect_port", this); // Create a new
analysis port for sending data
endfunction
endclass
monitor extends uvm_monitor and is used to observe and collect data from the DUT.
• virtual not_if vif — Connects the monitor to the DUT for observing signals.
This class observes the DUT's signals, logs the values, and sends the data to the
scoreboard for further analysis and verification.
Agent
// Constructor
function new(string name="agent", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor with the
given name and parent
endfunction
// Check if the agent is active before creating the sequencer and driver
if(get_is_active == UVM_ACTIVE) begin
// Create instances of the sequencer and driver components
seqr = sequencer::type_id::create("seqr", this);
drv = driver::type_id::create("drv", this);
end
endclass
agent extends uvm_agent and acts as a container for the sequencer, driver, and
monitor components.
• build_phase(uvm_phase phase) —
o Creates instances of the sequencer and driver only if the agent is active
(get_is_active == UVM_ACTIVE).
o Always creates an instance of the monitor.
• connect_phase(uvm_phase phase) —
o Connects the driver's sequence item port to the sequencer's sequence item
export if the agent is active.
The agent class sets up and manages the sequencer, driver, and monitor, ensuring
proper connections and creation based on the agent's active state.
Environment
// Constructor
function new(string name="env", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor
endfunction
endclass
env extends uvm_env and represents the test environment that includes components
like the agent and scoreboard.
The env class sets up the test environment by instantiating and connecting the agent
and scoreboard, facilitating the overall testbench structure.
Scoreboard
// Constructor
function new(string name="scoreboard", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor with the
given name and parent
item_collect_export = new("item_collect_export", this); // Create a new
analysis import port for receiving data
endfunction
$display("-------------------------------------------");
endfunction
endclass
scoreboard extends uvm_scoreboard and is responsible for comparing and verifying
the DUT's output against expected values.
• write(seq_item req) —
o Receives a sequence item (req), checks if the output (req.out) matches the
bitwise negation of the input (req.in).
o Logs a message indicating whether the output matches the expected result
or not.
The scoreboard class is used to validate the correctness of the DUT's outputs by
comparing them with expected values and reporting results.
Test
// Constructor
function new(string name="base_test", uvm_component parent=null);
super.new(name, parent); // Call the parent class constructor
endfunction
// Repeat the sequence execution 5 times with a 5-time unit delay between
each
repeat(5) begin
#5; // Wait for 5 time units
bseq.start(env_o.agt.seqr); // Start the sequence using the sequence
driver
end
endtask
endclass
base_test extends uvm_test and is used to set up and execute a test.
The base_test class is responsible for running a test by creating the environment,
executing a sequence multiple times, and managing the test's lifecycle.
Testbench Top
module tb_top;
initial begin
// Set the interface instance in the UVM configuration database
// This allows the test to access the interface instance via the
config_db
uvm_config_db#(virtual not_if)::set(uvm_root::get(), "*", "vif", vif);
end
initial begin
// Run the testbench with the base test class
run_test("base_test");
end
endmodule
• not_gate dut — Instantiates the not_gate module (Device Under Test) and
connects its ports to the vif interface.
• Initial Blocks:
• First Block: Sets the vif interface instance in the UVM configuration database
using uvm_config_db, allowing it to be accessed by the UVM test.
• Second Block: Runs the test using the base_test class.
The tb_top module sets up the test environment, connects the DUT to the interface,
and runs the base_test class to execute the testbench.
Package