对于一个 analysis_imp来说,必须在其实例化的uvm_component中定义一个write的函数。但在 现实情况中,scoreboard除了接收monitor的数据之外,还要接收reference model的数据。相应的scoreboard就要再添加一个 uvm_analysis_imp的IMP,如model_imp。此时问题就出现了,由于接收到的两路数据应该做不同的处理,所以这个新的IMP也要 有一个write任务与其对应。但是write只有一个,怎么办?
UVM考虑到了这种情况,它定义了一个宏uvm_analysis_imp_decl来解决这个问题,其使用方式为:
my_scoreboard.sv
`uvm_analysis_imp_decl(_monitor)
`uvm_analysis_imp_decl(_model)
class my_scoreboard extends uvm_scoreboard;
my_transaction expect_queue[$];
uvm_analysis_imp_monitor#(my_transaction, my_scoreboard) monitor_imp;
uvm_analysis_imp_model#(my_transaction, my_scoreboard) model_imp;
…
extern function void write_monitor(my_transaction tr);
extern function void write_model(my_transaction tr);
extern virtual task main_phase(uvm_phase phase);
上述代码通过宏uvm_analysis_imp_decl声明了两个后缀_monitor和_model。UVM会根据这两个后缀定义两个新的IMP类: uvm_analysis_imp_monitor和uvm_analysis_imp_model,并在my_scoreboard中分别实例化这两个类:monitor_imp和model_imp。当与 monitor_imp相连接的analysis_port执行write函数时,会自动调用write_monitor函数,而与model_imp相连接的analysis_port执行write 函数时,会自动调用write_model函数。所以,只要完成后缀的声明,并在write后面添加上相应的后缀就可以正常工作了:
my_scoreboard.sv
function void my_scoreboard::write_model(my_transaction tr);
expect_queue.push_back(tr);
endfunction
function void my_scoreboard::write_monitor(my_transaction tr);
my_transaction tmp_tran;
bit result;
if(expect_queue.size() > 0) begin
…
end
endfunction
参考:UVM实战:4.3.2 一个component内有多个IMP