UVM的field automation机制,拷贝、比较和打印

UVM的field automation机制,拷贝、比较和打印
1.拷贝
通过上面的数据操作方法默认类型可以看到,当拷贝对象时,默认进行的是深拷贝,即会执行copy()和do_copy()。

module object_copy2;
  import uvm_pkg::*;
  `include "uvm_macros.svh"

  typedef enum {RED, WHITE, BLACK} color_t;

  class ball extends uvm_object;
    int diameter = 10;
    color_t color = RED;
    `uvm_object_utils_begin(ball)//域的自动化
      `uvm_field_int(diameter, UVM_DEFAULT)
      `uvm_field_enum(color_t, color, UVM_NOCOPY)
    `uvm_object_utils_end
    function new(string name="ball");
      super.new(name);
    endfunction

    function void do_copy(uvm_object rhs);
      ball b;
      $cast(b, rhs);
      $display("ball::do_copy entered..");
      if(b.diameter <= 20) begin
        diameter = 20;
      end
    endfunction
  endclass

  class box extends uvm_object;
    int volume = 120;
    color_t color = WHITE;
    string name = "box";
    ball b;
    `uvm_object_utils_begin(box)
      `uvm_field_int(volume, UVM_ALL_ON)
      `uvm_field_enum(color_t, color, UVM_ALL_ON)
      `uvm_field_string(name, UVM_ALL_ON)
      `uvm_field_object(b, UVM_ALL_ON)
    `uvm_object_utils_end
    function new(string name="box");
      super.new(name);
      this.name = name;
      b = new();
    endfunction
  endclass

  box b1, b2;
  initial begin
    b1 = new("box1");
    b1.volume = 80;
    b1.color = BLACK;
    b1.b.color = WHITE;
    b2 = new();
    b2.copy(b1);
    b2.name = "box2";
    $display("%s", b1.sprint());
    $display("%s", b2.sprint());
  end
endmodule

输出结果:

ball::do_copy entered..
-----------------------------------
Name          Type      Size  Value
-----------------------------------
box1          box       -     @336 
  volume      integral  32    'h50 
  color       color_t   32    BLACK
  name        string    4     box1 
  b           ball      -     @337 
    diameter  integral  32    'ha  
    color     color_t   32    WHITE
-----------------------------------

-----------------------------------
Name          Type      Size  Value
-----------------------------------
box           box       -     @338 
  volume      integral  32    'h50 
  color       color_t   32    BLACK
  name        string    4     box2 
  b           ball      -     @340 
    diameter  integral  32    'h14 
    color     color_t   32    RED  
-----------------------------------

这段例码新添加了一个类ball,并且在box中例化了一个对象。而在拷贝过程中,box的其它成员都正常拷贝了,但对于box::b的拷贝则通过了ball的深拷贝方式进行。即先执行自动拷贝copy(),来拷贝允许拷贝的域,由于ball::color不允许拷贝,所以只拷贝了ball::diameter。

接下来,再执行do_copy()函数,这个函数是需要用户定义的回调函数(callback function),即在copy()执行完后会执行do_copy()。如果用户没有定义该函数,那么则不会执行额外的数据操作。

从ball::do_copy()函数可以看到的是,如果被拷贝对象的diameter小于20,那么则将自身的diameter设置为20。

因此,最后对象b2.b的成员与b1.b的成员数值不同。

2.比较
对于比较方法,默认情况下,如果不对比较的情况作出额外地配置,用户可以在调用compare()方法时,省略第二项参数,即采用默认的比较配置。

module object_compare1;
  import uvm_pkg::*;
  `include "uvm_macros.svh"

  typedef enum {RED, WHITE, BLACK} color_t;

  class box extends uvm_object;
    int volume = 120;
    color_t color = WHITE;
    string name = "box";
    `uvm_object_utils_begin(box)
      `uvm_field_int(volume, UVM_ALL_ON)
      `uvm_field_enum(color_t, color, UVM_ALL_ON)
      `uvm_field_string(name, UVM_ALL_ON)
    `uvm_object_utils_end
    function new(string name="box");
      super.new(name);
      this.name = name;
    endfunction
  endclass

  box b1, b2;
  initial begin
    b1 = new("box1");
    b1.volume = 80;
    b1.color = BLACK;
    b2 = new("box2");
    b2.volume = 90;
    if(!b2.compare(b1)) begin
      `uvm_info("COMPARE", "b2 comapred with b1 failure", UVM_LOW)
    end 
    else begin
      `uvm_info("COMPARE", "b2 comapred with b1 succes", UVM_LOW)
    end
  end
endmodule

输出结果:

UVM_INFO  @ 0: reporter [MISCMP] Miscompare for box2.volume: lhs = 'h5a : rhs = 'h50
UVM_INFO  @ 0: reporter [MISCMP] 1 Miscompare(s) for object box1@336 vs. box2@337
UVM_INFO  @ 0: reporter [COMPARE] b2 comapred with b1 failure

在上面的两个对象的比较中,会将每一个自动化的域进行比较,所以在执行compare()函数时,内置的比较方法也会将比较错误输出。从上面的结果来看,比较发生了错误,返回了0值。那么,b1.color和b2.color虽然不相同,为什么没有比较错误的信息呢?原因在于,默认的比较器,即***uvm_package::uvm_default_comparer***最大输出的错误比较信息是1,也就是说当比较错误发生时,则不会进行后续的比较。

3.打印
打印方法是核心基类提供的另外一种便于开发和调试的功能。通过field automation,使得声明之后的各个成员域会在调用uvm_object::print()函数时自动打印出来。

module object_print;
  import uvm_pkg::*;
  `include "uvm_macros.svh"

  typedef enum {RED, WHITE, BLACK} color_t;

  class box extends uvm_object;
    int volume = 120;
    color_t color = WHITE;
    string name = "box";
    `uvm_object_utils_begin(box)
      `uvm_field_int(volume, UVM_ALL_ON)
      `uvm_field_enum(color_t, color, UVM_ALL_ON)
      `uvm_field_string(name, UVM_ALL_ON)
    `uvm_object_utils_end
    function new(string name="box");
      super.new(name);
      this.name = name;
    endfunction
  endclass

  box b1;
  uvm_table_printer local_printer;
  initial begin
    b1 = new("box1");
    local_printer = new();

    $display("default table printer format");
    b1.print();

    $display("default line printer format");
    uvm_default_printer = uvm_default_line_printer;
    b1.print();

    $display("default tree printer format");
    uvm_default_printer = uvm_default_tree_printer;
    b1.print();

    $display("customized printer format");
    local_printer.knobs.full_name = 1;
    b1.print(local_printer);
  end
endmodule

输出结果:

default table printer format
-------------------------------
Name      Type      Size  Value
-------------------------------
box1      box       -     @336 
  volume  integral  32    'h78 
  color   color_t   32    WHITE
  name    string    4     box1 
-------------------------------

default line printer format
box1: (box@336) { volume: 'h78  color: WHITE  name: box1  } 


default tree printer format
box1: (box@336) {
  volume: 'h78 
  color: WHITE 
  name: box1 
}

customized printer format
------------------------------------
Name           Type      Size  Value
------------------------------------
box1           box       -     @336 
  box1.volume  integral  32    'h78 
  box1.color   color_t   32    WHITE
  box1.name    string    4     box1 
------------------------------------

**从上面这段例码中,读者可以发现,只要被在field automation中声明过的域,在稍后的print()函数打印室,都将打印出它们的类型、大小和数值。如果用户不对打印的格式做出修改,那么在打印时,UVM会按照uvm_default_printer规定的格式来打印。在上面“比较”一节中,读者已经知道uvm_pkg中在仿真一开始的时候就会例化不少全局的对象,这其中就包括了uvm_default_printer和其它几个用于打印的对象,它们分别是:
uvm_default_tree_printer:可以将对象按照数状结构打印。
uvm_default_line_printer : 可以将对象打印到一行上面。
uvm_default_table_printer : 可以将对象按照表格的方式打印。
uvm_default_printer : UVM环境默认的打印设置,该句柄默认指向了uvm_default_table_printer。

所以通过给全局打印机uvm_default_printer赋予不同的打印机句柄,就可以在调用任何uvm_object的print()方法时,得到不同的打印格式。如果用户需要自定义一些打印的属性,用户可以自己创建一个打印机,进而通过修改其属性uvm_printer::knobs中的成员,来输出自己的打印格式。每一台打印机中,都有自己的打印属性,用户可以通过查看UVM类的参考手册,查找关于详细的打印属性类uvm_printer_knobs。
除了简单的print()函数,用户还可以通过uvm_object::sprint()将对象的信息作为字符串返回,或者自定义do_print()函数来定制一些额外的打印输

4.常见错误
在vcs跑sv结果时候需要运行:

vcs -sverilog -ntb_opts uvm print.sv  -full64
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值