mirror of https://github.com/XS-MLVP/picker.git
191 lines
6.4 KiB
Systemverilog
191 lines
6.4 KiB
Systemverilog
//==============================================================================//
|
|
// File : example_uvm_dut.sv
|
|
// Author : automatically generated by picker
|
|
// Date : 2025-12-15 19:01:04
|
|
// 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
|
|
|
|
// Single transaction mode
|
|
class example_driver extends adder_trans_xdriver;
|
|
`uvm_component_utils(example_driver);
|
|
int transaction_count;
|
|
|
|
// Analysis port to publish received transactions
|
|
uvm_analysis_port #(adder_trans) ap;
|
|
|
|
function new (string name = "example_driver", uvm_component parent = null);
|
|
super.new(name,parent);
|
|
transaction_count = 0;
|
|
ap = new("ap", this);
|
|
endfunction
|
|
|
|
virtual function void build_phase(uvm_phase phase);
|
|
super.build_phase(phase);
|
|
endfunction
|
|
|
|
virtual task sequence_receive(adder_trans tr);
|
|
adder_trans tr_clone;
|
|
transaction_count++;
|
|
`uvm_info("example_driver", $sformatf("Received transaction #%0d from Python:\n%s",
|
|
transaction_count, tr.sprint()), UVM_LOW)
|
|
|
|
// Clone and write to analysis port
|
|
if($cast(tr_clone, tr.clone())) begin
|
|
ap.write(tr_clone);
|
|
end else begin
|
|
`uvm_error("example_driver", "Failed to clone transaction")
|
|
end
|
|
endtask
|
|
|
|
function void report_phase(uvm_phase phase);
|
|
super.report_phase(phase);
|
|
`uvm_info("example_driver", $sformatf("Total transactions received: %0d", transaction_count), UVM_LOW)
|
|
endfunction
|
|
endclass
|
|
|
|
// Subscriber to handle the echo back logic
|
|
class example_echo_subscriber extends uvm_component;
|
|
`uvm_component_utils(example_echo_subscriber)
|
|
|
|
uvm_analysis_export #(adder_trans) analysis_export;
|
|
uvm_tlm_analysis_fifo #(adder_trans) fifo;
|
|
adder_trans_xmonitor mon_handle;
|
|
|
|
function new(string name = "example_echo_subscriber", uvm_component parent = null);
|
|
super.new(name, parent);
|
|
analysis_export = new("analysis_export", this);
|
|
fifo = new("fifo", this);
|
|
endfunction
|
|
|
|
function void connect_phase(uvm_phase phase);
|
|
super.connect_phase(phase);
|
|
analysis_export.connect(fifo.analysis_export);
|
|
endfunction
|
|
|
|
virtual task run_phase(uvm_phase phase);
|
|
adder_trans tr;
|
|
forever begin
|
|
fifo.get(tr);
|
|
if (mon_handle != null) begin
|
|
mon_handle.sequence_send(tr);
|
|
end
|
|
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;
|
|
example_driver drv;
|
|
example_echo_subscriber echo_sub;
|
|
virtual example_interface vif;
|
|
|
|
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_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_xdriver::get_type(), example_driver::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);
|
|
|
|
// Build echo subscriber
|
|
echo_sub = example_echo_subscriber::type_id::create("echo_sub", this);
|
|
|
|
if(!uvm_config_db#(virtual example_interface)::get(this,"","vif",vif))
|
|
`uvm_fatal("example_env","virtual interface must be set for vif")
|
|
endfunction
|
|
|
|
function void connect_phase(uvm_phase phase);
|
|
super.connect_phase(phase);
|
|
|
|
// Connect the echo subscriber to the monitor
|
|
if (xagent.adder_trans_xmon != null) begin
|
|
echo_sub.mon_handle = xagent.adder_trans_xmon;
|
|
end
|
|
|
|
// Connect driver analysis port to subscriber
|
|
if (xagent.adder_trans_xdrv != null) begin
|
|
if ($cast(drv, xagent.adder_trans_xdrv)) begin
|
|
drv.ap.connect(echo_sub.analysis_export);
|
|
end
|
|
end
|
|
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 |