uvm-1.2 examples —— 2.4 package

2.4 package



前言

本文以uvm-1.2/examples/simple/basic_examples/pkg为例,主要的内容包括:1、两种方式注册工厂模式,手动注册和宏注册;2、打印调试config_db机制。


一、基本介绍

这个测试用例和上一节2.3的module类似,不过这个测试用例的侧重点,在于展示通过两种不同的方式,将一个组件注册到UVM工厂中去,另外还展示了如何开启了config_db的打印调试功能。

和上一个测试用例相比,系统的层次化结构一样,但换了一种打印风格。

mu: (myunit@335) {
  l1: (lower@344) {
    data: 'h30 
    str: "" 
  }
  l2: (lower@353) {
    data: 'h40 
    str: "" 
  }
  a: {
    [0]: 'h0 
    [1]: 'h1 
    [2]: 'h4 
    [3]: 'h9 
    [4]: 'h10 
  }
}

执行完仿真,得到的仿真结果如下。

mu: (myunit@335) {
  l1: (lower@344) {
    data: 'h37 
    str: hi 
  }
  l2: (lower@353) {
    data: 'h65 
    str: hi 
  }
  a: {
    [0]: 'h0 
    [1]: 'h1 
    [2]: 'h4 
    [3]: 'h9 
    [4]: 'h10 
  }

二、代码分析

这个测试用例只有一个文件test.sv

1、test.sv

test.sv的代码如下所示。

module test;
  import uvm_pkg::*;

  //--------------------------------------------------------------------
  // lower
  //--------------------------------------------------------------------
  class lower extends uvm_component;
    int data;
    string str;

    function new (string name, uvm_component parent);
      super.new(name, parent);
    endfunction

    task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      $display("%0t: %m: start run", $time);
      #10 $display("%0t: %s HI", $time, get_full_name());
      phase.drop_objection(this);
    endtask

    function string get_type_name();
      return "lower";
    endfunction

    function void build_phase(uvm_phase phase);
       void'(uvm_config_int::get(this, "", "data", data));
       void'(uvm_config_string::get(this, "", "str", str));
    endfunction 

    function void do_print(uvm_printer printer);
      printer.print_field("data", data, 32);
      printer.print_string("str", str);
    endfunction
  endclass

  //--------------------------------------------------------------------
  // myunit
  //--------------------------------------------------------------------
  class myunit extends uvm_component;
   lower l1;
   lower l2;
   int a[];

    function new (string name, uvm_component parent);
      super.new(name, parent);
      l1 = new ("l1", this);
      l2 = new ("l2", this);
      uvm_config_string::set(this, "l1", "str", "hi");
      uvm_config_int::set(this, "*", "da*", 'h100);
      l1.data = 'h30;
      l2.data = 'h40;
      a = new[5]; for(int i=0; i<5;++i) a[i] = i*i;
    endfunction

    task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      #10 $display("%0t: %s HI", $time, get_full_name());
      phase.drop_objection(this);
    endtask

    function string get_type_name();
      return "myunit";
    endfunction

    function void do_print(uvm_printer printer);
      printer.print_array_header("a", a.size());
      for(int i=0; i<a.size(); ++i) 
        printer.print_field($sformatf("a[%0d]", i), a[i], 32, UVM_HEX, "[");
      printer.print_array_footer();
    endfunction
      
  endclass


  // Factory registration 

  //--------------------------------------------------------------------
  // lower_wrapper
  //--------------------------------------------------------------------
  class lower_wrapper extends uvm_object_wrapper;
  
    function uvm_component create_component(string name, uvm_component parent);
      lower u;
      u = new(name, parent);
      return u;
    endfunction
  
    function string get_type_name();
      return "lower";
    endfunction
  
    static function bit register_me(); uvm_coreservice_t cs_ = uvm_coreservice_t::get();

      uvm_factory factory = cs_.get_factory();
      lower_wrapper w; w = new;
      factory.register(w);
      return 1;
    endfunction

    static bit is_registered = register_me();
  endclass

  //--------------------------------------------------------------------
  // myunit_wrapper
  //--------------------------------------------------------------------
  class myunit_wrapper extends uvm_object_wrapper;

    function uvm_component create_component(string name, uvm_component parent);
      myunit u;
      u = new(name, parent);
      return u;
    endfunction

    function string get_type_name();
      return "myunit";
    endfunction

    static function bit register_me(); uvm_coreservice_t cs_ = uvm_coreservice_t::get();

      uvm_factory factory = cs_.get_factory();
      myunit_wrapper w; w = new;
      factory.register(w);
      return 1;
    endfunction

    static bit is_registered = register_me();
  endclass

  myunit mu = new("mu", null);

  //--------------------------------------------------------------------
  // mydata
  //--------------------------------------------------------------------
`ifdef USE_MACROS
  class mydata extends uvm_object;
    `uvm_object_utils(mydata)

  function new(string name="mydata");
     super.new(name);
  endfunction

  endclass
`else
  class mydata extends uvm_object;
    function uvm_object create(string name="");
      mydata d; d=new; d.set_name(name);
      return d;
    endfunction // uvm_object
    function string get_type_name();
      return "mydata";
    endfunction
  endclass

  //--------------------------------------------------------------------
  // mydata_wrapper
  //--------------------------------------------------------------------
  class mydata_wrapper extends uvm_object_wrapper;

    function uvm_object create_object(string name="");
      mydata u;
      u = new;
      if(name !="") u.set_name(name);
      return u;
    endfunction

    function string get_type_name();
      return "myobject";
    endfunction

    static function bit register_me(); uvm_coreservice_t cs_ = uvm_coreservice_t::get();

      uvm_factory factory = cs_.get_factory();
      mydata_wrapper w; w = new;
      factory.register(w);
      return 1;
    endfunction

    static bit is_registered = register_me();
  endclass
`endif 

  mydata bar = new;

  initial begin automatic uvm_coreservice_t cs_ = uvm_coreservice_t::get();

    uvm_factory factory;
    factory=cs_.get_factory();
    uvm_top.finish_on_completion = 0;
    uvm_config_int::set(null, "mu.*", "data", 101);
    uvm_config_string::set(null, "mu.*", "str", "hi");
    uvm_config_int::set(null, "mu.l1", "data", 55);
    //uvm_config_object::set(null, "mu.*", "obj", bar);
    //mu.print_config_settings("", null, 1);
    mu.print_config(1);
    uvm_default_printer = uvm_default_tree_printer;
    mu.print();
    factory.print(1);
    run_test();
    mu.print();
  end
  //initial
  //  #5 mu.l1.kill();
endmodule

第1行,例化test这个module,这个测试用例将所有的组件都放在了module里边。
第7到73行,定义从uvm_component继承过来的类lower和myunit,这个定义和上一节2.3的一样。
第81到102行和107到128行,通过一个wrapper类,手动的将lower类和myunit类,注册到UVM的工厂中。有几点需要注意的是:1、wrapper类必须继承自uvm_object_wrapper类;2、在create_component函数中,例化的是需要注册的类。
第135到181行,通过一个宏USE_MACROS来切换,是选择采用宏注册,还是手动注册的方式注册mydata类,通过对比可以看出,宏注册的方式只需要一条语句就完成了注册,而手动注册则需要另外构造一个wrapper的类去实现。
第185到201行,通过一个initial来实现仿真,其中195行的print_config(1)函数会遍历整个验证平台的所有结点,找出那些被设置过的信息并打印出来,打印的信息如下所示。这个函数在张强的《UVM实战》中的3.5.10节也有介绍。

UVM_INFO @ 0: mu [CFGPRT] visible resources:
UVM_INFO ../../../../src/base/uvm_resource.svh(1321) @ 0: reporter [UVM/RESOURCE/PRINT] <none>
UVM_INFO @ 0: mu.l1 [CFGPRT] visible resources:
 str [/^mu\..*$/] : (string) "hi"   
 str [/^mu\.l1$/] : (string) "hi"   
 data [/^mu\.l1$/] : (logic signed[4095:0]) 55   
 data [/^mu\..*$/] : (logic signed[4095:0]) 101   
 da* [/^mu\..*$/] : (logic signed[4095:0]) 256   
UVM_INFO @ 0: mu.l2 [CFGPRT] visible resources:
 str [/^mu\..*$/] : (string) "hi"   
 data [/^mu\..*$/] : (logic signed[4095:0]) 101   
 da* [/^mu\..*$/] : (logic signed[4095:0]) 256   

2、仿真结果

仿真log如下所示,通过log还可以看到一个现象,由于代码196行,改变了打印的方式,所以,mu打印的格式也发生的改变,变成了树状结构。

UVM_INFO @ 0: mu [CFGPRT] visible resources:
UVM_INFO ../../../../src/base/uvm_resource.svh(1321) @ 0: reporter [UVM/RESOURCE/PRINT] <none>
UVM_INFO @ 0: mu.l1 [CFGPRT] visible resources:
 str [/^mu\..*$/] : (string) "hi"   
 str [/^mu\.l1$/] : (string) "hi"   
 data [/^mu\.l1$/] : (logic signed[4095:0]) 55   
 data [/^mu\..*$/] : (logic signed[4095:0]) 101   
 da* [/^mu\..*$/] : (logic signed[4095:0]) 256   
UVM_INFO @ 0: mu.l2 [CFGPRT] visible resources:
 str [/^mu\..*$/] : (string) "hi"   
 data [/^mu\..*$/] : (logic signed[4095:0]) 101   
 da* [/^mu\..*$/] : (logic signed[4095:0]) 256   
mu: (myunit@335) {
  l1: (lower@344) {
    data: 'h30 
    str: "" 
  }
  l2: (lower@353) {
    data: 'h40 
    str: "" 
  }
  a: {
    [0]: 'h0 
    [1]: 'h1 
    [2]: 'h4 
    [3]: 'h9 
    [4]: 'h10 
  }
}
UVM_INFO ../../../../src/base/uvm_factory.svh(1645) @ 0: reporter [UVM/FACTORY/PRINT] 
#### Factory Configuration (*)

  No instance or type overrides are registered with this factory

All types registered with the factory: 50 total
  Type Name
  ---------
  lower
  mydata
  myunit
(*) Types with no associated type name will be printed as <unknown>

####


UVM_INFO @ 0: reporter [RNTST] Running test ...
0: test.\lower::run_phase : start run
0: test.\lower::run_phase : start run
10: mu.l1 HI
10: mu.l2 HI
10: mu HI
UVM_INFO ../../../../src/base/uvm_report_server.svh(847) @ 10: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :    7
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[CFGPRT]     3
[RNTST]     1
[UVM/FACTORY/PRINT]     1
[UVM/RELNOTES]     1
[UVM/RESOURCE/PRINT]     1

mu: (myunit@335) {
  l1: (lower@344) {
    data: 'h37 
    str: hi 
  }
  l2: (lower@353) {
    data: 'h65 
    str: hi 
  }
  a: {
    [0]: 'h0 
    [1]: 'h1 
    [2]: 'h4 
    [3]: 'h9 
    [4]: 'h10 
  }
}
           V C S   S i m u l a t i o n   R e p o r t 
Time: 10 ns

总结

通过这个测试用例,主要可以学习到两点,其一是通过手动的方式将组件注册到UVM的工厂中去,其二是可以调用print_config(1)函数实现config_db的调试。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: uvm-1.1a.tar.gz是一个库文件,它是Universal Verification Methodology(UVM)的开源版本,旨在帮助硬件验证工程师实现更高效、更准确的系统级验证工作。该版本的发布包括完整的UVM框架和示例代码,它们可以被应用于各种验证环境。其包含了基于SystemVerilog的类库、通用模型、事务级建模器和随机验证,同时也包括了DPI、OVM等不同验证间件框架的支持。该版本提供了更多的互操作性和可扩展性,让用户能够快速开发和部署大规模验证工作。UVM已经成为ASIC和FPGA验证领域的事实标准,可以在不同的平台和工具上进行移植。因为它的开源特性和流行度,UVM支持社区持续创新和最佳实践的分享,不断提高Verilog验证技术的水平和效率。 ### 回答2: uvm-1.1a.tar.gz是一种开源的验证方法学框架,为现代芯片验证提供了一种完整而灵活的解决方案。它提供了一套可重用的Class Library,包括了各种验证组件,如监控,分析器,交通形成器和交通收集器,并提供了一种现代的验证方法学,包括创建可重用的测试用例和环境。UVM框架是基于SystemVerilog语言的,是目前工业界最常用的验证环境之一。该框架可以帮助芯片设计者和验证工程师更有效地制定验证计划和执行测试,缩短开发周期,提高产品质量和可重复性。同时,UVM也在学术界和研究机构广泛应用,为芯片验证方法学的研究和发展提供了有力的支持和平台。总之,uvm-1.1a.tar.gz是一个非常有用的开源验证方法学框架,为芯片验证提供了强大的支持和帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值