求助:UVM中的override问题
最近在使用UVM搭建验证平台,其中涉及到override的问题,我用的是set_type_override_by_type函数来实现override,但是貌似没有替换成功啊。代码如下:
初始的test class:
- class base_test extends uvm_test;
- normal_apb_config demo_cfg;
- ...
- virual function void build_phase(uvm_phase phase);
- demo_cfg=normal_apb_config::type_id::create("demo_cfg");
- ...
- ...
新的test class代码:
- class int_test extends base_test;
- ...
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- set_type_override_by_type(normal_apb_config::get_type(),ir_apb_config::get_type());
- endfunction : build_phase
- task run_phase(uvm_phase phase);
- super.run_phase(phase);
- $display("***Debug override***");
- demo_cfg.print();
- endtask: run_phase
- ...
而两个config类的代码如下:
- class normal_apb_config extends apb_config;
- `uvm_object_utils(normal_apb_config)
- function new(string name ="normal_apb_config");
- super.new(name);
- add_master("master",UVM_ACTIVE);
- add_slave("slave0",32'h0000_0000,32'h0000_0400,0,UVM_PASSIVE);
- endfunction
- endclass : normal_apb_config
- class ir_apb_config extends normal_apb_config;
- `uvm_object_utils(ir_apb_config)
- virtual ir_if irq_if;
- function new(string name ="ir_apb_config");
- super.new(name);
- add_master("master",UVM_ACTIVE);
- add_slave("slave0",32'h0000_0000,32'h0000_0380,0,UVM_PASSIVE);
- endfunction
- task wait_for_irq;
- @(posedge irq_if.irq);
- endtask
- endclass : ir_apb_config
而运行到"demo_cfg.print()"时候,打印出来的end_addr还是32'h400,而不是32‘h380.
如何才能override成功呢?
个人感觉一定要先执行override,再create,override才会成功。都已经create好了,再override就不行了。
LZ在新的test class代码中是先执行的super.build_phase(phase),然后才是set_type_override_by_type。建议这两句换一下再试试。
我两个交换了一下两行代码,有个新问题:你可以看见我的config里面都有一个add_slave函数,然后里面产生的slave是一个数组。这两个config类都是只加载了一个slave。
新的问题是:“UVM_ERROR ./apb/sv/apb_slave_agent.sv(96) @ 0: uvm_test_top.tb0.apb0.slave[1] [NOVIF] virtual interface must be set for: uvm_test_top.tb0.apb0.slave[1].vif “
鉴于我的config都是只配置了一个slave,所以我可以认为是一部分替换成功,一部分替换不成功,因此两个config类都生效,从而产生了两个slave?
还是说是我的基本类apb_config写的有问题,而导致override的时候虽然能替换成功,但是还是多配了一个slave?
貌似不管哪种情况都不好解决呀。
另外,我想问问,是否要实现override,必须是ir_apb_config继承normal_apb_config,如果它们都继承apb_config,作为apb_config的一级子类,这样就不能进行替换了?
个人感觉你的ir_apb_configclass中的new中不应该再写super.new, 否则在ir_apb_config 的new中就会两次调用add_master和add_slave。还是你本来就想在
ir_apb_config 的new中 调用两次?
Use the type and instance override calls to override the base types with a derived types.
刚试了注释掉super.new(name),结果是一样的。
一样的,同样会多出一个不希望的slave出来。
我觉得是因为我把“add_master"和“add_slave"两个函数都放到new里面去执行的原因,而new函数又是不可重载的函数,父类和子类的new都要执行的原因。我试过把“add_master"和“add_slave"封到new之外的函数中,但是还是得在new中调用,不然没办法执行,要是uvm_object也像uvm_component一样有各种phase就好了,我可以直接在build_phase中改写。
唉——,多一个slave的问题解决了,但是又有新问题,总不消停啊
首先,多一个slave的解决办法,将”add_slave“函数放到new之外
- class normal_apb_config extends apb_config;
- `uvm_object_utils(normal_apb_config)
- function new(string name ="normal_apb_config");
- super.new(name);
- gen_master_and_slaves();
- endfunction
- virtual function void gen_master_and_slaves();
- add_master("master",UVM_ACTIVE);
- add_slave("slave0",32'h0000_0010,32'h0000_0300,0,UVM_PASSIVE);
- endfunction : gen_master_and_slaves
- endclass : normal_apb_config
- class ir_apb_config extends normal_apb_config;
- `uvm_object_utils(ir_apb_config)
- virtual ir_if irq_if;
- function new(string name ="ir_apb_config");
- super.new(name);
- endfunction
- function void gen_master_and_slaves();
- add_master("master",UVM_ACTIVE);
- add_slave("slave0",32'h0000_0000,32'h0000_0380,0,UVM_PASSIVE);
- endfunction : gen_master_and_slaves
- task wait_for_irq;
- @(posedge irq_if.irq);
- endtask
- endclass : ir_apb_config
我觉得不是因为ir_apb_config中使用super.new的问题,也不是执行creste和override顺序问题,建议你用set_inst_override_by_type函数。
你的最后出现的问题是不是跟你的使用这个ir_apb_conifg的virtual interface有不当的地方
请问小编问题解决了吗?override是不是应该在new之前呢?