请帮助您理解功能并明确区别:
我在互联网上搜索过,有一些解释,如:
但我觉得还需要更多解释。有人可以帮忙吗。
答案 0 :(得分:2)
uvm_analysis_port 是发布商,他们广播交易
uvm_analysis_imp 是订阅者,他们接收事务并在定义它们的类中调用名为“write”的函数。
uvm_analysis_export 可能更令人困惑,它们用于在层次结构的更高级别公开“imp”端口。例如,如果您的代理程序包含具有analyze_imp的组件,并且您希望在代理程序的接口级别使该“imp”可用。在这种情况下,您在代理类中声明并实例化analysis_export,然后在connect_phase中将代理的analysis_export连接到内部组件的analysis_imp。
值得注意的是,出口是订阅方,但在出版方面,常规的uvm_analysis_port可以以相同的方式使用。因此,代理可以实例化analysis_ports并将它们连接到内部组件的analysis_port。
这很好,因为它允许您在连接组件时避免深入到层次结构中(这使维护更容易):
坏:
bus_agent.internal_monitor.packet_port.connect(checker.ref_model.packet_imp)
好:
bus_agent.packet_port.connect(checker.packet_export)
熟悉宏uvm_analysis_imp_decl()
也很好。它允许您在组件中使用多个analysis_imp。
答案 1 :(得分:2)
此分析端口的优点是用户可以将数据从单个生产者传输到多个未通过uvm_blocking_put_port帮助存档的使用者。
图中也说明了这一点。
在这里,我提供了示例代码,以便更加清晰地了解uvm_analysis_port。
请记住:端口连接用于连接两个或多个独立组件。
This image gives explanation of uvm_analysis_port
uvm_analysis_port示例
class transaction extends uvm_sequence_item;
`uvm_object_utils(transaction);
rand int unsigned a;
rand int unsigned b;
function new(string name ="");
super.new(name);
endfunction
endclass
class producer extends uvm_component;
`uvm_component_utils(producer);
transaction tr_inst;
uvm_analysis_port #(transaction) produce_to_consumer_p;
function new(string name ="",uvm_component parent);
super.new(name,parent);
produce_to_consumer_p = new("produce_to_consumer_p",this);
tr_inst = new("tr_inst");
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
// tr_inst.randomize();
`uvm_info(get_full_name(),"Write the data from PRODUCER",UVM_LOW);
tr_inst.a = 10; tr_inst.b = 20;
produce_to_consumer_p.write(tr_inst);
phase.drop_objection(this);
endtask
endclass
class consumer_1 extends uvm_component;
`uvm_component_utils(consumer_1);
uvm_analysis_imp#(transaction,consumer_1) write_imp_1;
function new(string name ="",uvm_component parent);
super.new(name,parent);
write_imp_1 = new("write_imp_1",this);
endfunction
function void write(transaction tr_inst);
`uvm_info(get_full_name(),"Got the data in CONSUMER_1",UVM_LOW);
`uvm_info(get_full_name(),$sformatf("The value of a = %0d and b = %0d",tr_inst.a,tr_inst.b),UVM_LOW);
endfunction
endclass
class consumer_2 extends uvm_component;
`uvm_component_utils(consumer_2);
uvm_analysis_imp#(transaction,consumer_2) write_imp_2;
function new(string name ="",uvm_component parent);
super.new(name,parent);
write_imp_2 = new("write_imp_2",this);
endfunction
function void write(transaction tr_inst);
`uvm_info(get_full_name(),"Got the data in CONSUMER_2",UVM_LOW);
`uvm_info(get_full_name(),$sformatf("The value of a = %0d and b = %0d",tr_inst.a,tr_inst.b),UVM_LOW);
endfunction
endclass
class consumer_3 extends uvm_component;
`uvm_component_utils(consumer_3);
uvm_analysis_imp#(transaction,consumer_3) write_imp_3;
function new(string name ="",uvm_component parent);
super.new(name,parent);
write_imp_3 = new("write_imp_3",this);
endfunction
function void write(transaction tr_inst);
`uvm_info(get_full_name(),"Got the data in CONSUMER_3",UVM_LOW);
`uvm_info(get_full_name(),$sformatf("The value of a = %0d and b = %0d",tr_inst.a,tr_inst.b),UVM_LOW);
endfunction
endclass
class env extends uvm_component;
`uvm_component_utils(env);
producer p_inst;
consumer_1 c_inst_1;
consumer_2 c_inst_2;
consumer_3 c_inst_3;
function new(string name="",uvm_component parent);
super.new(name,parent);
p_inst = new("p_inst",this);
c_inst_1 = new("c_inst_1",this);
c_inst_2 = new("c_inst_2",this);
c_inst_3 = new("c_inst_3",this);
endfunction
function void connect();
p_inst.produce_to_consumer_p.connect(c_inst_1.write_imp_1);
p_inst.produce_to_consumer_p.connect(c_inst_2.write_imp_2);
p_inst.produce_to_consumer_p.connect(c_inst_3.write_imp_3);
endfunction
endclass
module main();
env env_inst;
initial
begin
env_inst = new("env_inst",null);
run_test();
end
endmodule
这是一个链接,可以让您更清楚地了解分析端口以及uvm_port。
链接:http://stackoverflow.com/questions/38085875/where-to-use-uvm-blocking-put-port-and-uvm-analysis-port