二、一个analysis port和多个IMP相连接进行通信的例子 2.1.analysis_port A
class component_a extends uvm_component;
transaction trans;
//Step-1. Declaring analysis port
uvm_analysis_port#(transaction) analysis_port_a;
`uvm_component_utils(component_a)
//---------------------------------------
// Constructor
//---------------------------------------
function new(string name, uvm_component parent);
super.new(name, parent);
//Step-2. Creating analysis port
analysis_port_a = new("analysis_port_a", this);
endfunction : new
//---------------------------------------
// run_phase
//---------------------------------------
virtual task run_phase(uvm_phase phase);
phase.raise_objection(this);
trans = transaction::type_id::create("trans", this);
//void'(trans.randomize());
assert(trans.randomize());
`uvm_info(get_type_name(), $sformatf(" tranaction randomized"),UVM_LOW)
`uvm_info(get_type_name(), $sformatf(" Printing trans, \n %s", trans.sprint()), UVM_LOW)
`uvm_info(get_type_name(),$sformatf(" Before calling port write method"), UVM_LOW)
//Ste-3. Calling write method
analysis_port_a.write(trans);
`uvm_info(get_type_name(), $sformatf(" After calling port write method"), UVM_LOW)
phase.drop_objection(this);
endtask : run_phase
endclass : component_a
2.2.analysis_imp B(需要寫写一个write任务)
class component_b extends uvm_component;
transaction trans;
//Step-1. Declaring analysis imp port
uvm_analysis_imp#(transaction,component_b) analysis_imp_b;
`uvm_component_utils(component_b)
//---------------------------------------
// Constructor
//---------------------------------------
function new(string name, uvm_component parent);
super.new(name, parent);
//Step-2. Creating analysis imp_port
analysis_imp_b = new("analysis_imp_b", this);
endfunction : new
//---------------------------------------
// Analysis Imp port write method
//---------------------------------------
//Step-3. Implementing write method
virtual function void write(transaction trans);
`uvm_info(get_type_name(), $sformatf(" Inside write method. Recived trans On Analysis Imp Port"), UVM_LOW)
`uvm_info(get_type_name(), $sformatf(" Printing trans, \n %s", trans.sprint()), UVM_LOW)
endfunction
endclass : component_b
2.3.analysis_imp D(需要寫写一个write任务)
class component_d extends uvm_component;
transaction trans;
//Step-1. Declaring analysis imp port
uvm_analysis_imp#(transaction,component_b) analysis_imp_d;
`uvm_component_utils(component_d)
//---------------------------------------
// Constructor
//---------------------------------------
function new(string name, uvm_component parent);
super.new(name, parent);
//Step-2. Creating analysis imp_port
analysis_imp_d = new("analysis_imp_d", this);
endfunction : new
//---------------------------------------
// Analysis Imp port write method
//---------------------------------------
//Step-3. Implementing write method
virtual function void write(transaction trans);
`uvm_info(get_type_name(), $sformatf(" Inside write method. Recived trans On Analysis Imp Port"), UVM_LOW)
`uvm_info(get_type_name(), $sformatf(" Printing trans, \n %s", trans.sprint()), UVM_LOW)
endfunction
endclass : component_d
2.4.Component C
class C extends uvm_component;
component_a a;
component_b b;
component_d d;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
a = component_a::type_id::create(“a”, this);
b = component_b::type_id::create(“b”, this);
d = component_d::type_id::create(“d”, this);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
a.analysis_port_a.connect(b.analysis_imp_b);
a.analysis_port_a.connect(d.analysis_imp_d);
endfunction
endclass
三、一個component中有多个uvm_analysis_imp存在的情况
通常,在monitor和scoreboard之间的通信,采用一个analysis port和一个anslysis imp相连的方式实现。我们知道,对于一个analysis imp来说,必须在其实例化的uvm_component定义一个write的task。
如果scoreboard除了接收monitor的数据之外,还要接受reference model的数据。相应的scoreboard就要再添加一个uvm_analysis_imp的IMP,如model_imp。此时问题就出现了,这个新的IMP也要有一个write任务与其对应,因为很明显,我们对接收到的两路数据的处理是不一样的。但是write只有一个,怎么办?
UVM考虑到了这种情况,它采用如下的方式处理:
`uvm_analysis_imp_decl(_monitor)
3.1、一個component中有“多個”write任務的案例
`uvm_analysis_imp_decl(_model)
class scoreboard extends uvm_scoreboard;
uvm_analysis_imp_monitor#(mac_transaction, scoreboard) monitor_imp;
uvm_analysis_imp_model#(mac_transaction, scoreboard) model_imp;
task write_monitor(mac_transaction tr);
//do something on tr
endtask
task write_model(mac_transaction tr);
//do something on tr
endtask
endclass
通过宏`uvm_analysis_imp_decl,声明了两个后缀_monitor和_model。UVM会根据这两个后缀内建两个新的imp:uvm_analysis_imp_monitor和uvm_analysis_imp_model。
当与uvm_analysis_imp_monitor相连接的analysis port执行write任务时,会自动调用write_monitor任务,
而与uvm_analysis_imp_model相连的analysis port执行write任务时,则会自动调用write_mondel任务。
所以,只要把后缀声明了,把write后面添加上相应的后缀就可以正常工作了。
注意:在PORT側,執行的都是write這個task
作者:gsithxy