• 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
  • 相关阅读:
    springboot~使用docker构建gradle项目
    CH BR8(小学生在上课-逆元和互质数一一对应关系)
    UNIX环境高级编程第二版代码笔记
    【Linux学习笔记】用nc实现两台主机间的文件传输(不需要输密码)
    hdu 1159
    轻量级的原型设计工具-Axure RP
    在Ubuntu 12.10 上安装部署Openstack
    [Android 中级]Voip之CSipSimple类库的编绎
    OpenStack云计算快速入门之一:OpenStack及其构成简介
    OpenStack云计算快速入门之二:OpenStack安装与配置
  • 原文地址:https://www.cnblogs.com/shadrach/p/15994818.html
Copyright © 2020-2023  润新知