英文:
How do I get overridden transaction item in UVM driver?
问题
我正在尝试在UVM驱动程序中获取重写的事务项。我创建了一个UVM序列项类,其中包含多个继承的类。
class mem_seq_item extends uvm_sequence_item;
// ...(您的代码)
endclass
class child_seq_item extends mem_seq_item;
// ...(您的代码)
endclass
您创建了my_sequence
类,并尝试在my_test
类中执行它。
class my_sequence extends mem_sequence;
// ...(您的代码)
endclass
class my_test extends mem_wr_rd_test;
// ...(您的代码)
endclass
但问题是,您无法在UVM驱动程序中获取重写的事务项。错误信息显示A不是一个类项。
您可以在UVM驱动程序中获取重写的事务项,确保您在mem_driver
中正确引用了子类的成员。请注意,如果要访问子类的成员,您需要将事务项强制转换为子类类型。在您的mem_driver
中,可以这样做:
virtual task drive(input mem_seq_item trans);
`DRIV_IF.wr_en <= 0;
`DRIV_IF.rd_en <= 0;
@(posedge vif.DRIVER.clk);
if (trans'is_a(child_seq_item)) begin
child_seq_item child_trans;
child_trans = trans;
`DRIV_IF.addr <= child_trans.A;
end
// 可以添加其他事务项的处理
endtask : drive
这将允许您在驱动程序中正确获取A项,前提是事务项是child_seq_item
的实例。确保在处理其他类型的事务项时也进行适当的类型检查和转换。
英文:
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?
答案1
得分: 3
由于驱动程序是使用mem_seq_item
参数化的,并且没有关于覆盖事务的信息,您需要将类变量向下转换为一个了解覆盖的类型。
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;
如果trans
不是child_seq_item
,那么您需要决定在这种情况下会发生什么。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论