I wrote this code for "Introducing Transactions" class under Basic UVM course.
I am sending some sample address, command, and data from the driver. However, DUT is not
receiving the data. I pasted most relevant SV files in my TB at the top. Please help me point to the error.
Here is the output
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
$time = 105, addr = 0, data = 0, cmd = x
UVM_INFO @ 200: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO @ 200: reporter [UVM/REPORT/CATCHER]
Here is the Code base
DUT Interface ---> dut_if.sv
interface dut_if;
logic clock, reset;
logic cmd;
int data, addr;
endinterface
DUT Config File
class dut_config extends uvm_object;
`uvm_object_utils(dut_config)
function new(string name = "dut_config");
endfunction
virtual dut_if dut_vif;
endclass
DUT module ---> dut_module.sv
module dut(dut_if _if);
initial begin
_if.clock = 0;
#5 _if.clock = ~_if.clock;
#100 $display("$time = %d, addr = %d, data = %d, cmd = %d \n", $time, _if.addr, _if.data, _if.cmd);
end
always@(_if.data or _if.cmd or _if.addr) begin
$display("$time = %d, addr = %d, data = %d, cmd = %d \n", $time, _if.addr, _if.data, _if.cmd);
end
endmodule : dut
Driver --> my_driver.svh
class my_driver extends uvm_driver#(my_transaction);
`uvm_component_utils(my_driver)
dut_config dut_config_0;
//virtual interface dut_if dut_vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
function void connect_phase(uvm_phase phase);
if(!uvm_config_db#(dut_config)::get(this, "", "dut_config", dut_config_0))
`uvm_fatal(get_type_name(), "Could not instantiate dut_config in my_driver")
endfunction
task run_phase(uvm_phase phase);
my_transaction tx;
@(posedge dut_config_0.dut_vif.clock);
seq_item_port.get_next_item(tx);
dut_config_0.dut_vif.addr = tx.addr;
dut_config_0.dut_vif.cmd= tx.cmd;
dut_config_0.dut_vif.data = tx.data;
@(posedge dut_config_0.dut_vif.clock);
seq_item_port.item_done();
endtask
endclass
Top Module --> top.sv
module top;
import uvm_pkg::*;
import my_pkg::*;
dut_if dut_if1();
dut dut_inst(._if(dut_if1));
initial
begin
uvm_config_db#(virtual dut_if)::set(null, "uvm_test_top", "dut_vif", dut_if1);
run_test("my_test");
end
endmodule : top
Top level Test ---> my_test.svh
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env my_env_h;
dut_config dut_config_0;
function new(string name, uvm_component parent);
super.new(name, parent);
my_env_h = my_env::type_id::create("my_env_h", this);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
dut_config_0 = new();
if(!uvm_config_db#(virtual dut_if)::get(this, "", "dut_vif", dut_config_0.dut_vif))
`uvm_fatal(get_type_name(), "dut_if has not been instantiated")
uvm_config_db#(dut_config)::set(this, "*", "dut_config", dut_config_0);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
#200;
phase.drop_objection(this);
endtask
endclass : my_test
Env File --> my_env.svh
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_agent my_agent_h;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
my_agent_h = my_agent::type_id::create("my_agent_h", this);
endfunction
task run_phase(uvm_phase phase);
endtask
endclass : my_env
Agent --> my_agent.svh
class my_agent extends uvm_agent;
`uvm_component_utils(my_agent)
my_driver my_driver_h;
my_sequencer my_sequencer_h;
my_monitor my_monitor_h;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(is_active == UVM_ACTIVE) begin
my_driver_h = my_driver::type_id::create("my_driver_h", this);
my_sequencer_h = my_sequencer::type_id::create("my_sequencer_h", this);
end
my_monitor_h = my_monitor::type_id::create("my_monitor_h", this);
endfunction
function void connect_phase(uvm_phase phase);
if(is_active == UVM_ACTIVE)
my_driver_h.seq_item_port.connect(my_sequencer_h.seq_item_export);
endfunction
endclass
Sequence ---> my_sequence.svh
class my_sequence extends uvm_sequence#(my_transaction);
`uvm_object_utils(my_sequence)
function new(string name = "");
super.new(name);
endfunction
task body();
forever begin
my_transaction tx = my_transaction::type_id::create("tx");
start_item(tx);
if(!tx.randomize())
`uvm_fatal(get_type_name(), "Randomization of my_transaction instance failed")
finish_item(tx);
end
endtask
endclass
Sequence Item
class my_transaction extends uvm_sequence_item;
`uvm_object_utils(my_transaction)
rand bit cmd;
rand int addr;
rand int data;
function new(string name = "");
super.new(name);
endfunction
constraint c_addr {addr >= 0; addr <256;}
constraint c_data {addr >= 0; addr <256;}
endclass
typedef uvm_sequencer #(my_transaction) my_sequencer;