uvm通信-uvc通信方式二之analysis_port/export/imp

1.analysis端口(apimp)

(1) analysis_port和analysis_export其实与put和get系列端口类似,都用于传递transaction;

(2) 一个analysis_port/analysis_export可以和多个IMP相连进行通信,但是IMP的类型必须是uvm_analysis_imp;

(3) 在analysis_imp所在的component,必须定义一个write函数.调用analysis_port.write()函数时,会依次获取与之相连的analysis_imp,并调用analysis_imp.write()函数;在analysis_imp.write()函数内,会调用analysis_imp所在uvm_component的write()函数;

注1:需要注意的是,如果analysis_imp采用的是`uvm_analysis_imp_decl(*),就不需要uvm_analysis_imp_*所在的uvm_component中有write函数,而是要有write_*函数;

注2:参考src/tlm1/uvm_analysis_port.svh & uvm-1.2/macros/uvm_tlm_defines.svh;

2.analysis端口与put/get系列端口的异同

(1) 默认情况下, 一个analysis_port (analysis_export)可以连接多个IMP(见下文示例), 也就是说, analysis_port (analysis_export)与IMP之间的通信是一对多的通信,而put和get系列端口与相应IMP的通信是一对一的通信(除非在实例化时,指定可以连接的数量).

(2) put与get系列端口都有阻塞和非阻塞的区分. 但是对于analysis_port和analysis_export来说,没有阻塞和非阻塞的概念. 因为它本身就是广播, 不用等待与其相连的其他端口的响应,所以不存在阻塞和非阻塞.

(3) 对于put系列端口, 有put、try_put、can_put等操作,对于get系列端口,有get、try_get和can_get等操作. 对于analysis_port和analysis_export来说,只有一种操作: write.

(4) 与put系列端口的PORT和EXPORT直接相连会出错的情况一样,analysis_port如果和一个analysis_export直接相连也会出错;只有在analysis_export后面再连接一级uvm_analysis_imp,才不会出错;

3.跨层次的ap,imp连接

比如o_agt的monitor与scoreboard之间的通信;

3.1连接方式一: 直接在env中跨层次引用monitor中的ap;

3.2连接方式二: 在agent中声明一个ap,并实例化它,在connect_phase将其与monitor的ap相连,并可以在env中把agent的ap直接连接到scoreboard的imp;

3.3连接方式三: 在agent中声明一个ap,但是不实例化它,让其指向monitor中的ap. 在env中可以直接连接agent的ap到scoreboard的imp;

注1:下图中有一处笔误,ap=mon.ap应当放在connect_phase或者放在build_phase中的monitor例化语句之后;

3.4 三种连接方法的对比

三种跨层次ap,imp连接方法的比较:第一种简单但层次关系不好; 第二种稍显麻烦; 第三种既具有明显的层次关系,同时较易实现.

4.一个component内多个IMP

4.1 多个IMP需要有多个write函数与之对应, 宏uvm_analysis_imp_decl可以解决一个component内多个IMP的问题.

注1:需要补充说明的是,对于blocking/nonblocking_put/get/transport/..._imp存在类似的宏,如下图所示;

4.2示例:

(1)通过宏uvm_analysis_imp_decl声明两个后缀_monitor和_model; UVM会根据这两个后缀定义两个新的IMP类-uvm_analysis_imp_monitor和uvm_analysis_imp_model;

(2)在my_scoreboard中声明并实例化uvm_analysis_imp_monitor与uvm_analysis_imp_model, 句柄分别为monitor_imp和model_imp;

(3)当与monitor_imp相连接的analysis_port执行write函数时,会自动调用write_monitor函数; 而与model_imp相连接的analysis_port执行write函数时,会自动调用write_model函数.

注1:这种情况下,uvm_analysis_imp与write函数应该还是可以使用的;

  1 //示例
  2 //注意:该实例中,多个imp共用同一个write函数;
  3 `ifndef WB_CONMAX_SCOREBOARD__SV
  4  `define WB_CONMAX_SCOREBOARD__SV
  5 
  6 `uvm_analysis_imp_decl(_master)
  7 `uvm_analysis_imp_decl(_slave) 
  8 
  9 typedef class wb_transaction;
 10 class wb_conmax_scoreboard extends uvm_scoreboard;
 11 
 12  `include "wb_conmax_env_defines.svh"
 13    uvm_analysis_imp_master #(wb_transaction,wb_conmax_scoreboard) master_export[8];
 14    uvm_analysis_imp_slave #(wb_transaction,wb_conmax_scoreboard) slave_export[16];
 15 
 16    uvm_tlm_analysis_fifo #(wb_transaction) master_fifo[8];
 17 
 18    uvm_in_order_class_comparator #(wb_transaction) comparator[16];
 19 
 20    // Built in UVM comparator will not be used. User has to define the compare logic
 21 
 22    `uvm_component_utils(wb_conmax_scoreboard);
 23    extern function new(string name = "wb_conmax_scoreboard",
 24                        uvm_component parent = null); 
 25    extern virtual function void build_phase (uvm_phase phase);
 26    extern virtual function void connect_phase (uvm_phase phase);
 27    extern virtual function void end_of_elaboration_phase (uvm_phase phase);
 28    extern virtual task main_phase(uvm_phase phase);
 29    extern virtual function void report_phase(uvm_phase phase);
 30    extern function void write_master(wb_transaction tr);
 31    extern function void write_slave(wb_transaction tr);
 32    extern function void report();
 33    extern function int get_addr(ref wb_transaction tr);
 34    extern function bit report_info_hook(input id, string message, int verbosity, string filename, int line) ;
 35 
 36 endclass: wb_conmax_scoreboard
 37 
 38    function bit wb_conmax_scoreboard::report_info_hook(input id, string message, int verbosity, string filename, int line) ;
 39       $display("called report hook, %d",$time);
 40       return 1;
 41    endfunction: report_info_hook
 42 
 43    function wb_conmax_scoreboard::new(string name = "wb_conmax_scoreboard",
 44                       uvm_component parent);
 45       super.new(name,parent);
 46    endfunction: new
 47 
 48    function void wb_conmax_scoreboard::build_phase(uvm_phase phase);
 49       super.build_phase(phase);
 50       for(int i = 0; i < 8; i = i+1) begin
 51          master_export[i] = new($sformatf("master_export%d",i) , this);
 52       end
 53       for(int i = 0; i < 16; i = i+1) begin
 54          slave_export[i] = new($sformatf("slave_export%d",i) , this);
 55      comparator[i]    = new($sformatf("comparator%d",i), this);
 56       end
 57 
 58    endfunction:build_phase
 59 
 60    task wb_conmax_scoreboard::main_phase(uvm_phase phase);
 61       super.main_phase(phase);
 62       phase.raise_objection(this,"scbd..");
 63       phase.drop_objection(this);
 64    endtask: main_phase 
 65 
 66    function void wb_conmax_scoreboard::report_phase(uvm_phase phase);
 67       super.report_phase(phase);
 68    endfunction:report_phase
 69 
 70    // Master ingress functions
 71 
 72    function void wb_conmax_scoreboard::write_master(wb_transaction tr);
 73       integer master_id;
 74       master_id = get_addr(tr);
 75       `uvm_info("SCOREBOARD_MASTER",tr.sprint(),UVM_HIGH)
 76       comparator[get_addr(tr)].before_export.write(tr);
 77    endfunction
 78    
 79    function  void wb_conmax_scoreboard::write_slave(wb_transaction tr);
 80       `uvm_info("SCOREBOARD_SLAVE",tr.sprint(),UVM_HIGH)
 81       comparator[get_addr(tr)].after_export.write(tr);
 82    endfunction
 83 
 84    function void wb_conmax_scoreboard::report();
 85 
 86       foreach (comparator[i]) begin
 87      `uvm_info("Scoreboard Report",
 88            $sformatf("Comparator[%0d] Matches = %0d, Mismatches = %0d",
 89                  i, comparator[i].m_matches, comparator[i].m_mismatches), UVM_MEDIUM);
 90       end
 91    endfunction
 92 
 93    function void wb_conmax_scoreboard::end_of_elaboration_phase(uvm_phase phase);
 94       set_report_severity_action(UVM_INFO,  UVM_DISPLAY|UVM_CALL_HOOK);
 95    endfunction
 96 
 97    function int wb_conmax_scoreboard::get_addr(ref wb_transaction tr);
 98       bit [31:0] addr;
 99       case(addr) inside
100           [`SLAVE0_MIN :`SLAVE0_MAX] :  get_addr = 0;
101         [`SLAVE1_MIN :`SLAVE1_MAX] :  get_addr = 1;
102                 ...
103         [`SLAVE14_MIN :`SLAVE14_MAX] :  get_addr = 14;
104         [`SLAVE15_MIN :`SLAVE15_MAX] :  get_addr = 15;
105       endcase
106 
107    endfunction
108 
109 `endif // WB_CONMAX_SCOREBOARD__SV

 

 

 

 

 

 

 

 

 

posted on 2021-11-16 20:17  知北游。。  阅读(3561)  评论(5编辑  收藏  举报

导航