uvm中如何传递信号
在tb_top里写:
mpc_if cpu_if();
uvm_config_db#(virtual mpc_if)::set(uvm_root::get(), "*", "m_mpc_if", cpu_if)
在需要的类里:
在build_phase函数里:
uvm_config_db#(virtual mpc_if)::get(this, "", "m_mpc_if", m_mpc_if);
但是我发现在tb_top定义的信号都传不进去。高手看看有什么地方可能有问题?
谢谢!
driver是这样定义的:
`ifndef _MPC_DRIVER_SV_
`define _MPC_DRIVER_SV_
class mpc_driver extends uvm_driver #(mpc_transaction) ;
`uvm_component_utils(mpc_driver)
protected virtual mpc_if m_mpc_if ;
//new -- constructor
function new(string name = "mpc_driver_inst", uvm_component parent) ;
super.new(name, parent) ;
`uvm_info("dirver", "Called mpc_driver::new", UVM_NONE) ;
endfunction : new
virtual function void build_phase(uvm_phase phase) ;
super.build_phase(phase) ;
if(!uvm_config_db#(virtual mpc_if)::get(this, "", "m_mpc_if", m_mpc_if))
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".m_mpc_if"});
endfunction : build_phase
//run phase
virtual task run_phase(uvm_phase phase) ;
get_and_drive() ;
`uvm_info("dirver", "Called mpc_driver::run_phase", UVM_NONE) ;
endtask : run_phase
//get and drive
virtual protected task get_and_drive() ;
forever begin
@(posedge m_mpc_if.clk);
`uvm_info("dirver", "clock is ok!", UVM_NONE) ;
seq_item_port.get_next_item(req);
$cast(rsp, req.clone());
rsp.set_id_info(req);
drive_transaction(rsp);
seq_item_port.item_done();
seq_item_port.put_response(rsp);
end
endtask : get_and_drive
//drive transaction
virtual protected task drive_transaction(mpc_transaction trans) ;
`uvm_info("dirver", "Called mpc_driver::drive_transaction", UVM_NONE) ;
case(trans.read_write)
NOP: nop() ;
READ: read_word(trans.addr, trans.data) ;
WRITE : write_word(trans.addr, trans.data) ;
endcase
@(posedge m_mpc_if.clk) ;
nop() ;
endtask : drive_transaction
// bus idle
virtual protected task nop() ;
m_mpc_if.csn<= 'b1 ;
m_mpc_if.wr<= 'b0 ;
m_mpc_if.rd<= 'b0 ;
m_mpc_if.addr <= 'bz ;
m_mpc_if.din<= 'bz ;
m_mpc_if.dout <= 'bz ;
endtask : nop
// read one word
virtual protected task read_word(bit [31:0] addr, output bit [31:0] data) ;
m_mpc_if.csn<= 'b0 ;
m_mpc_if.wr<= 'b0 ;
m_mpc_if.rd<= 'b1 ;
m_mpc_if.addr <= addr ;
@(posedge m_mpc_if.clk iff m_mpc_if.tan === 'b1);
//data <= m_mpc_if.dout ;
endtask : read_word
// write one word
virtual protected task write_word(bit [31:0] addr, bit [31:0] data) ;
m_mpc_if.csn<= 'b0 ;
m_mpc_if.wr<= 'b1 ;
m_mpc_if.rd<= 'b0 ;
m_mpc_if.addr <= addr ;
m_mpc_if.din<= data ;
@(posedge m_mpc_if.clk iff m_mpc_if.tan === 'b1);
endtask : write_word
endclass : mpc_driver
`endif
仿真报什么错呢?
仿真没报错,但是这句`uvm_info("dirver", "clock is ok!", UVM_NONE) ;
应该有打印信息的,没看到。
检查一下DRIVER的虚接口有没有实体注册,建议采用mentor公司示范代码的方法是用一个专门的uvm_object来管理接口和变量
如何做呢?
现在看来是clk传不进去,在driver里可以改变其他信号的值,不知道为什么clk在driver里无效。
现在发现时运行时间太短了。很快就运行到run_test的$finish这条语句了,我怎么样才能让它运行时间长一点呢?
应该是传进去了, 你可以通过GUI 窗口看看有没有连好.
还有, 你可以单步执行, 看看怎么跑的.
看看protect类型是不是有问题.
在你的测试类里的run_test(uvm_phase phase)中添加phase.raise_objection(this);
#1000;
phase.drop_objection(this);
受教了
很好,大家都有无私的精神
最后发现就像这位TX说的一样,UVM里控制运行时间是靠phase.raise_objection(this); phase.drop_objection(this)来控制的,当所有的objection执行完仿真就停止了。我一开始并没有用这样的语句,所以刚开始运行就结束了。
今天搜一个问题竟然搜到我的帖子了。发现还没有给大家最后回复下。
看来uvm还是和ovm有些东东不太一样
受教。
同问。
感觉好深奥
不错的帖子