picker/example/Pack/02_UVM2Py/example.sv

139 lines
4.4 KiB
Systemverilog

//==============================================================================//
// File : example_uvm_dut.sv
// Author : automatically generated by picker
// Date : 2025-12-15 20:01:23
// Description: UVM testbench for adder_trans example
// Supports bidirectional communication (Python ←→ UVM)
// - Driver receives transactions from Python
// - Monitor sends transactions back to Python
// Version : v0.1
//==============================================================================//
import uvm_pkg::*;
import uvmc_pkg::*;
// Include common utility package before agents
`include "adder_trans/utils_pkg.sv"
// Single transaction mode: include transaction definition and agent
`include "../example/Pack/adder_trans.sv"
`include "adder_trans/xagent.sv"
interface example_interface(input clk, input rst_n);
// Add your DUT interface signals here if needed
// For this example, we just verify that transactions are received
endinterface //example_interface
class adder_python_monitor extends adder_trans_xmonitor;
`uvm_component_utils(adder_python_monitor)
adder_trans prev_tr;
function new(string name = "adder_python_monitor", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
prev_tr = adder_trans::type_id::create("prev_tr");
endfunction
// Monitor independently samples interface
virtual task run_phase(uvm_phase phase);
adder_trans tr;
forever begin
// Wait for signal change (input change indicates new transaction)
// Wait for combinational logic to settle
#1step
// Sample all signals
tr = adder_trans::type_id::create("tr");
tr.randomize();
sequence_send(tr);
prev_tr.copy(tr);
`uvm_info("ADDER_MON", $sformatf("Sampled: a=0x%0x, b=0x%0x, cin=%0d -> sum=0x%0x, cout=%0d",
tr.a, tr.b, tr.cin, tr.sum, tr.cout), UVM_LOW)
end
endtask
endclass
class example_env extends uvm_env;
`uvm_component_utils(example_env)
// Single transaction mode
adder_trans_xagent xagent;
adder_trans_xagent_config xagent_config;
adder_python_monitor mon;
function new (string name = "example_env", uvm_component parent = null);
super.new(name,parent);
// Single transaction config - use factory override for custom driver type
xagent_config = new("xagent_config");
// Set to UVM_ACTIVE for both monitor and driver (default behavior)
xagent_config.is_active = UVM_PASSIVE; // UVM_ACTIVE;
uvm_config_db#(adder_trans_xagent_config)::set(this,"xagent", "adder_trans_xagent_config", xagent_config);
// Use factory override to replace default driver with example driver
set_type_override_by_type(adder_trans_xmonitor::get_type(), adder_python_monitor::get_type());
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// Build single agent
xagent = adder_trans_xagent::type_id::create("xagent",this);
endfunction
virtual task main_phase(uvm_phase phase);
phase.raise_objection(this);
// Just wait for Python to send transactions
// Python controls the simulation time via Step() calls
#10000; // Wait long enough for Python to complete
phase.drop_objection(this);
endtask
endclass
class example_test extends uvm_test;
`uvm_component_utils(example_test)
example_env env;
function new (string name = "example_test", uvm_component parent = null);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = example_env::type_id::create("example_env",this);
endfunction
endclass
module sv_main;
logic clk;
logic rst_n;
example_interface vif(clk,rst_n);
initial begin
clk = 0;
forever begin
#2
clk <= ~clk;
end
end
initial begin
rst_n <= 1'b0;
#10
rst_n <= 1'b1;
end
initial begin
uvm_config_db #(virtual example_interface)::set(null,"uvm_test_top.example_env","vif",vif);
run_test("example_test");
end
endmodule