UVM——callback机制应用示例

 

 

 

对应代码:

1、在UVM组件中主操作函数或者任务之前或者之后内嵌callback函数或任务

 1 class driver extends uvm_driver #(transaction);
 2     `uvm_register_cb(driver, driver_callback);         //登记
 3     ...  
 4     virtual task run_phase(uvm_phase phase)l
 5          forever begin
 6              seq_item_port.get_next_item(req);
 7              `uvm_do_callbacks(driver, driver_callback, pre_send(this, req));      //使用宏嵌入函数或任务
 8              send(req);
 9              `uvm_do_callbacks(driver, driver_callback, post_send(this, req));    // 就是在哪个类中,使用哪个callback,以及这个callback的哪个方法
10              seq_item_port.item_done();
11          end
12  
13 endclass: drvier
14  

2、创建一个uvm_callback 空壳类(facade class)

 1 typedef class driver;
 2 class driver_callback extends uvm_callback;
 3     function new(string name = "driver_callback");
 4          super.new(name);
 5     endfunction: new
 6  
 7     virtual task pre_send(driver drv, transaction tr);   //这是注入错误的
 8     endtask
 9  
10     virtual task post_send(driver drv, transaction tr);  //这是用来收集覆盖率的
11     endtask
12 endcalss: driver_callback

3、从callback空壳类扩展

  ①注入错误

1 class driver_error_callback extends driver_callback;
2     virtual task pre_send(driver drv, transaction tr);
3          drv.req.payload.delete()
4     endtask: pre_send
5 endclass: driver_error_callback

  ②收集覆盖率

 1 class driver_cov_callback extends driver_callback;
 2     covergroup drv_cov with function sample(transaction tr);
 3          coverpoint tr.sa;
 4          coverpoint tr.da;
 5     endcovergroup    
 6  
 7     function new();
 8          drv_cov = new();
 9     endfunction: new
10  
11     virtual task post_send(driver drv, transaction tr);
12          drv_cov.sample(tr);
13     endtask: pre_send
14 endclass: driver_error_callback

4、在验证环境中创建并登记UVM callback 实例

  ①

1 class driver_err_test extends test_base;
2     driver_error_callback drv_err_cb;                           //
3     virtual function void connect_phase(uvm_phase, phase);
4          super.connect_phase(phase);
5          drv_err_cb = new();                                              //创建
6          uvm_callbacks #(driver, driver_callback)::add(env.drv, drv_err_cb);     // 登记对象
7          uvm_callbacks #(driver, driver_callback)::display();  //方便调试
8     endfunction: connect_phase
9 endcalss: driver_err_test

  ②

 1 class driver_cov_test extends test_base;
 2     ...
 3     driver_cov_callback drv_err_cb;                           //
 4     virtual function void connect_phase(uvm_phase, phase);
 5          super.connect_phase(phase);
 6          drv_cov_cb = new();                                              //创建
 7          uvm_callbacks #(driver, driver_callback)::add(env.drv, drv_cov_cb);     // 登记对象
 8          uvm_callbacks #(driver, driver_callback)::display();  //方便调试
 9     endfunction: connect_phase
10 endcalss: driver_cov_test

这个例子就到此结束了。还有一个例子。


 

两个例子基本一致的,就是个别宏的使用方法有点小异。

  1 `include "uvm_macros.svh"
  2 
  3 package bus_driver_pkg;
  4 
  5 import uvm_pkg::*;
  6 
  7 typedef class bus_driver;
  8 typedef class bus_driver_cb;
  9 typedef uvm_callbacks #(bus_driver,bus_driver_cb) bus_driver_cbs_t;  // 这样定义好之后,使用::add的时候就不要带那么多参数了。
 10 
 11 class bus_tr extends uvm_transaction;
 12   rand int addr;
 13   rand int data;
 14   virtual function string convert2string();
 15     convert2string = $sformatf("addr=%0h data=%0h",addr,data);
 16   endfunction
 17 endclass
 18 
 19 virtual class bus_driver_cb extends uvm_callback;   // 空壳类
 20 
 21   virtual function bit trans_received(bus_driver driver, bus_tr tr);
 22     return 0;
 23   endfunction
 24 
 25   virtual task trans_executed(bus_driver driver, bus_tr tr);
 26   endtask
 27 
 28   function new(string name="bus_driver_cb_inst");
 29     super.new(name);
 30   endfunction
 31 
 32   static string type_name = "bus_driver_cb";
 33 
 34   virtual function string get_type_name();
 35     return type_name;
 36   endfunction
 37 
 38 endclass
 39 
 40 class bus_driver extends uvm_component;
 41 
 42   uvm_blocking_put_imp #(bus_tr,bus_driver) in;
 43 
 44   `uvm_register_cb(bus_driver, bus_driver_cb)    // 注册
 45 
 46   function new (string name, uvm_component parent=null);
 47     super.new(name,parent);
 48     in = new("in",this);
 49   endfunction
 50 
 51   static string type_name = "bus_driver";
 52 
 53   virtual function string get_type_name();
 54     return type_name;
 55   endfunction
 56 
 57   virtual function bit trans_received(bus_tr tr);
 58     `uvm_do_callbacks_exit_on(bus_driver,bus_driver_cb,trans_received(this,tr),1)    // 这里的callback函数用在了主任务所调用的函数里,也是可以的
 59   endfunction
 60 
 61   virtual task trans_executed(bus_tr tr);
 62     `uvm_do_callbacks(bus_driver,bus_driver_cb,trans_executed(this,tr))
 63   endtask
 64 
 65   virtual task put(bus_tr t);
 66     uvm_report_info("bus_tr received",t.convert2string());
 67     if (!trans_received(t)) begin
 68       uvm_report_info("bus_tr dropped",
 69           "user callback indicated DROPPED\n");
 70       return;
 71     end
 72     #100;
 73     trans_executed(t);
 74     uvm_report_info("bus_tr executed",{t.convert2string(),"\n"});
 75   endtask
 76 
 77 endclass
 78 
 79 endpackage // bus_driver_pkg
 80 
 81 import uvm_pkg::*;
 82 import bus_driver_pkg::*;
 83 
 84 class my_bus_driver_cb extends bus_driver_cb;    //第一个重载
 85 
 86   function new(string name="bus_driver_cb_inst");
 87     super.new(name);
 88   endfunction
 89 
 90   virtual function bit trans_received(bus_driver driver, bus_tr tr);
 91     static bit drop = 0;
 92     driver.uvm_report_info("trans_received_cb",
 93       {"  bus_driver=",driver.get_full_name()," tr=",tr.convert2string()});
 94     drop = 1 - drop;
 95     return drop;
 96   endfunction
 97 
 98   virtual task trans_executed(bus_driver driver, bus_tr tr);
 99     driver.uvm_report_info("trans_executed_cb",
100       {"  bus_driver=",driver.get_full_name()," tr=",tr.convert2string()});
101   endtask
102 
103   virtual function string get_type_name();
104     return "my_bus_driver_cb";
105   endfunction
106 
107 endclass
108 
109 class my_bus_driver_cb2 extends bus_driver_cb;    //第二个
110 
111   function new(string name="bus_driver_cb_inst");
112     super.new(name);
113   endfunction
114 
115   virtual task trans_executed(bus_driver driver, bus_tr tr);
116     driver.uvm_report_info("trans_executed_cb2",
117       {"  bus_driver=",driver.get_full_name()," tr=",tr.convert2string()});
118   endtask
119 
120   virtual function string get_type_name();
121     return "my_bus_driver_cb2";
122   endfunction
123 
124 endclass
125 
126 module top;
127   import uvm_pkg::*;
128   import bus_driver_pkg::*;
129 
130   bus_tr            tr     = new;
131   bus_driver        driver = new("driver");
132   my_bus_driver_cb  cb1    = new("cb1");    // 由于本例结构简单,声明实例一起完成了
133   my_bus_driver_cb2 cb2    = new("cb2");
134 
135   initial begin
136     bus_driver_cbs_t::add(driver,cb1);
137     bus_driver_cbs_t::add(driver,cb2);
138     bus_driver_cbs_t::display();
139     for (int i=1; i<=5; i++) begin
140       tr.addr = i;
141       tr.data = 6-i;
142       driver.in.put(tr);
143     end
144     begin
145        uvm_report_server svr = uvm_report_server::get_server();
146        svr.summarize();
147     end
148   end
149 
150 endmodule

 

posted @ 2022-03-11 18:02  HsiehTengK`o  阅读(783)  评论(0编辑  收藏  举报