• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

UVM中的field_automation机制应用

在引入my_mointor时,在my_transaction中加入了my_print函数;在引入reference model时,加入了my_copy函数;在引入scoreboard时,加入了my_compare函数。上述三个函数虽然各自不同,但是对于不同的transaction来说,都是类似的:它们都需要逐字段地对transaction进行某些操作。
这就是UVM中的field_automation机制,使用uvm_field系列宏实现:

//my_transaction.sv
4 class my_transaction extends uvm_sequence_item;
5
6 rand bit[47:0] dmac;
7 rand bit[47:0] smac;
8 rand bit[15:0] ether_type;
9 rand byte pload[];
10 rand bit[31:0] crc;
…
25 `uvm_object_utils_begin(my_transaction)
26 `uvm_field_int(dmac, UVM_ALL_ON)
27 `uvm_field_int(smac, UVM_ALL_ON)
28 `uvm_field_int(ether_type, UVM_ALL_ON)
29 `uvm_field_array_int(pload, UVM_ALL_ON)
30 `uvm_field_int(crc, UVM_ALL_ON)
31 `uvm_object_utils_end
…
37 endclass

这里使用uvm_object_utils_begin和uvm_object_utils_end来实现my_transaction的factory注册,在这两个宏中间,使用uvm_field宏注册所有字段。uvm_field系列宏随着transaction成员变量的不同而不同,如上面的定义中出现了针对bit类型的uvm_field_int及针对
byte类型动态数组的uvm_field_array_int。
当使用上述宏注册之后,可以直接调用copy、compare、print等函数,而无需自己定义。这极大地简化了验证平台的搭建,提高了效率:

//my_model.sv
26 task my_model::main_phase(uvm_phase phase);
27   my_transaction tr;
28   my_transaction new_tr;
29   super.main_phase(phase);
30   while(1) begin
31     port.get(tr);
32     new_tr = new("new_tr");  
33     new_tr.copy(tr);  //
34     `uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)
35     new_tr.print();  //
36     ap.write(new_tr);
37   end
38 endtask
//my_scoreboard.sv
…
34 while (1) begin
35   act_port.get(get_actual);
36     if(expect_queue.size() > 0) begin
37       tmp_tran = expect_queue.pop_front();
38       result = get_actual.compare(tmp_tran);//
39       if(result) begin
40         `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);
41       end

引入field_automation机制的另外一大好处是简化了driver和monitor。my_driver的drv_one_pkt任务和my_monitord的collect_one_pkt任务代码很长,但是几乎都是一些重复性的代码。使用field_automation机制后,drv_one_pkt任务可以简化为:

//my_driver.sv
38 task my_driver::drive_one_pkt(my_transaction tr);
39   byte unsigned data_q[];
40   int data_size;
41
42   data_size = tr.pack_bytes(data_q) / 8;  //
43   `uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
44   repeat(3) @(posedge vif.clk);
45   for ( int i = 0; i < data_size; i++ ) begin
46     @(posedge vif.clk);
47     vif.valid <= 1'b1;
48     vif.data <= data_q[i];
49   end
50
51   @(posedge vif.clk);
52   vif.valid <= 1'b0;
53   `uvm_info("my_driver", "end drive one pkt", UVM_LOW);
54 endtask

第42行调用pack_bytes将tr中所有的字段变成byte流放入data_q中。pack_bytes极大地减少了代码量。在把所有的字段变成byte流放入data_q中时,字段按照uvm_field系列宏书写的顺序排列。在上述代码中是先放入dmac,再依次放入smac、ether_type、pload、crc。假如my_transaction定义时各个字段的顺序如下:

`uvm_object_utils_begin(my_transaction)
`uvm_field_int(smac, UVM_ALL_ON)
`uvm_field_int(dmac, UVM_ALL_ON)
`uvm_field_int(ether_type, UVM_ALL_ON)
`uvm_field_array_int(pload, UVM_ALL_ON)
`uvm_field_int(crc, UVM_ALL_ON)
`uvm_object_utils_end

那么将会先放入smac,再依次放入dmac、ether_type、pload、crc。
my_monitor的collect_one_pkt可以简化成:

//my_monitor.sv
34 task my_monitor::collect_one_pkt(my_transaction tr);
35   byte unsigned data_q[$];
36   byte unsigned data_array[];
37   logic [7:0] data;
38   logic valid = 0;
39   int data_size;
…
46   `uvm_info("my_monitor", "begin to collect one pkt", UVM_LOW);
47   while(vif.valid) begin
48     data_q.push_back(vif.data);
49     @(posedge vif.clk);
50   end
51   data_size = data_q.size();
52   data_array = new[data_size];
53   for ( int i = 0; i < data_size; i++ ) begin
54     data_array[i] = data_q[i];
55   end
56   tr.pload = new[data_size - 18]; //da sa, e_type, crc
57   data_size = tr.unpack_bytes(data_array) / 8;    //
58   `uvm_info("my_monitor", "end collect one pkt", UVM_LOW);
59 endtask

这里使用unpack_bytes函数将data_q中的byte流转换成tr中的各个字段。unpack_bytes函数的输入参数必须是一个动态数组,所以需要先把收集到的、放在data_q中的数据复制到一个动态数组中。由于tr中的pload是一个动态数组,所以需要在调用unpack_bytes之前指定其大小,这样unpack_bytes函数才能正常工作。

posted on 2022-07-23 23:51  SOC验证工程师  阅读(1222)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3