I'm trying to get the overridden transaction item in UVM driver. I made a UVM sequence item class which has multiple inherited classes.
class mem_seq_item extends uvm_sequence_item;
//---------------------------------------
//data and control fields
//---------------------------------------
rand bit [1:0] addr;
rand bit wr_en;
rand bit rd_en;
rand bit [7:0] wdata;
bit [7:0] rdata;
//---------------------------------------
//Utility and Field macros
//---------------------------------------
`uvm_object_utils_begin(mem_seq_item)
`uvm_field_int(addr,UVM_ALL_ON)
`uvm_field_int(wr_en,UVM_ALL_ON)
`uvm_field_int(rd_en,UVM_ALL_ON)
`uvm_field_int(wdata,UVM_ALL_ON)
`uvm_object_utils_end
//---------------------------------------
//Constructor
//---------------------------------------
function new(string name = "mem_seq_item");
super.new(name);
endfunction
//---------------------------------------
//constaint, to generate any one among write and read
//---------------------------------------
constraint wr_rd_c { wr_en != rd_en; };
endclass
class child_seq_item extends mem_seq_item;
//---------------------------------------
//data and control fields
//---------------------------------------
rand bit [7:0] A;
rand bit [7:0] B;
rand bit [7:0] C;
//---------------------------------------
//Utility and Field macros
//---------------------------------------
`uvm_object_utils_begin(child_seq_item)
`uvm_field_int(A,UVM_ALL_ON)
`uvm_field_int(B,UVM_ALL_ON)
`uvm_field_int(C,UVM_ALL_ON)
`uvm_object_utils_end
//---------------------------------------
//Constructor
//---------------------------------------
function new(string name = "child_seq_item");
super.new(name);
endfunction
endclass
And I create the my_sequence
class my_sequence extends mem_sequence;
child_seq_item child_item;
`uvm_object_utils(my_sequence)
//---------------------------------------
//Constructor
//---------------------------------------
function new(string name = "my_sequence");
super.new(name);
endfunction
virtual task body();
child_item = child_seq_item::type_id::create("child_item");
`uvm_do(child_item)
child_item.print();
endtask
endclass
and tried to execute the my_sequence class in my_test
class .
class my_test extends mem_wr_rd_test;
`uvm_component_utils(my_test)
//---------------------------------------
// sequence instance
//---------------------------------------
my_sequence my_seq;
//---------------------------------------
// constructor
//---------------------------------------
function new(string name = "my_test",uvm_component parent=null);
super.new(name,parent);
endfunction : new
//---------------------------------------
// build_phase
//---------------------------------------
virtual function void build_phase(uvm_phase phase);
set_type_override_by_type(mem_seq_item::get_type(), child_seq_item::get_type());
super.build_phase(phase);
// Create the sequence
my_seq = my_sequence::type_id::create("my_seq");
endfunction : build_phase
//---------------------------------------
// run_phase - starting the test
//---------------------------------------
task run_phase(uvm_phase phase);
phase.raise_objection(this);
my_seq.start(env.mem_agnt.sequencer);
phase.drop_objection(this);
//set a drain-time for the environment if desired
phase.phase_done.set_drain_time(this, 50);
endtask : run_phase
endclass
But Problem is I can't get overridden transaction item in UVM driver.
class mem_driver extends uvm_driver #(mem_seq_item);
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
...
endfunction: build_phase
//---------------------------------------
// run phase
//---------------------------------------
virtual task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
drive(req);
`DRIV_IF.addr <= req.addr;
`DRIV_IF.addr <= req.B; //<=== B is not a class item.
seq_item_port.item_done();
end
endtask : run_phase
virtual task drive(input mem_seq_item trans );
`DRIV_IF.wr_en <= 0;
`DRIV_IF.rd_en <= 0;
@(posedge vif.DRIVER.clk);
`DRIV_IF.addr <= trans.A;
The error message I can't get the A item.
`DRIV_IF.addr <= trans.A;
|
xmvlog: *E,NOTCLM (mem_driver.sv,52|27): A is not a class item.
How can I get the overridden transaction item in UVM driver?
Since the driver is parameterized with a mem_seq_item
and has no information about overridden transactions, you need to downcast the class variable to a type that would know about the override
virtual task drive(input mem_seq_item trans );
child_seq_item csi;
`DRIV_IF.wr_en <= 0;
`DRIV_IF.rd_en <= 0;
@(posedge vif.DRIVER.clk);
if ($cast(csi,trans)
`DRIV_IF.addr <= csi.A;
If the trans is not a child_seq_item, then you will need to decide what happens in that case.