UVM:2.3 为验证平台加入各个组件->2.3.7 加入field_automation机制
  VDP7COGanTeB 2023年11月02日 96 0


1. 前面的my_print,my_copy,my_compare函数,虽然各自不同,但对于transaction来说,都是类似的。使用UVM中的field_automation机制,可以自动实现这3个函数,不需要我们写,my_transaction:

`ifndef MY_TRANSACTION__SV
`define MY_TRANSACTION__SV

class my_transaction extends uvm_sequence_item;

   rand bit[47:0] dmac;
   rand bit[47:0] smac;
   rand bit[15:0] ether_type;
   rand byte      pload[];
   rand bit[31:0] crc;

   constraint pload_cons{
      pload.size >= 46;
      pload.size <= 1500;
   }

   function bit[31:0] calc_crc();
      return 32'h0;
   endfunction

   function void post_randomize();
      crc = calc_crc;
   endfunction

   `uvm_object_utils_begin(my_transaction)
      `uvm_field_int(dmac, UVM_ALL_ON)
      `uvm_field_int(smac, 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

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

endclass
`endif



1)pload.size还是可以限制的。

2)使用uvm_object_utils_begin 和 uvm_object_utils_end 实现my_transaction 的factory注册。

3)uvm_field系列宏不同:uvm_field_int 对 int;uvm_field_array_int  对 byte。


2.my_model变为:

task my_model::main_phase(uvm_phase phase);
   my_transaction tr;
   my_transaction new_tr;
   super.main_phase(phase);
   while(1) begin
      port.get(tr);
      new_tr = new("new_tr");
      new_tr.copy(tr);//<===========
      `uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)
      new_tr.print();//<===========
      ap.write(new_tr);
   end
endtask



之前是my_copy 和 my_print。


3.my_scoreboard变为:

while (1) begin
         act_port.get(get_actual);
         if(expect_queue.size() > 0) begin
            tmp_tran = expect_queue.pop_front();
            result = get_actual.compare(tmp_tran);//<============
            if(result) begin 
               `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);
            end



之前是my_compare。


4.field_automation的另一个好处是简化了driver 和 monitor。my_driver 的 drv_one_pkt任务和my_monitor的collect_one_pkt 很长,而且都是些重复性的代码。使用field_automation后,drv_one_pkt 可以简化为:

task my_driver::drive_one_pkt(my_transaction tr);
   byte unsigned     data_q[];
   int  data_size;
   
   data_size = tr.pack_bytes(data_q) / 8; 
   `uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
   repeat(3) @(posedge vif.clk);
   for ( int i = 0; i < data_size; i++ ) begin
      @(posedge vif.clk);
      vif.valid <= 1'b1;
      vif.data <= data_q[i]; 
   end

   @(posedge vif.clk);
   vif.valid <= 1'b0;
   `uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask



1)pack_bytes 将tr 中所有的字段变成byte流放入data_q中。字段按照uvm_field 系列宏的顺序排列。


5.my_monitor的collect_one_pkt :

task my_monitor::collect_one_pkt(my_transaction tr);
   byte unsigned data_q[$];
   byte unsigned data_array[];
   logic [7:0] data;
   logic valid = 0;
   int data_size;
   
   while(1) begin
      @(posedge vif.clk);
      if(vif.valid) break;
   end
   
   `uvm_info("my_monitor", "begin to collect one pkt", UVM_LOW);
   while(vif.valid) begin
      data_q.push_back(vif.data);
      @(posedge vif.clk);
   end
   data_size  = data_q.size();   
   data_array = new[data_size];
   for ( int i = 0; i < data_size; i++ ) begin
      data_array[i] = data_q[i]; 
   end
   tr.pload = new[data_size - 18]; //da sa, e_type, crc
   data_size = tr.unpack_bytes(data_array) / 8; 
   `uvm_info("my_monitor", "end collect one pkt", UVM_LOW);
endtask



1)使用unpack_bytes (UVM的内容)函数将data_q 中的byte流转换成tr 中的各个字段。

2)unpack_bytes的输入参数必须为一个动态数组,所以把收集到的,放在data_q 中的数据复制到一个动态数组中。

3)由于tr中pload是一个动态数据,在调用unpack_bytes前,应该指定其大小。

问题:1)data_q这个queue 不是动态数组吗? 2)data_array不能直接用push_back吗?这样就不需要data_q[$]。


6.使用field_automation机制后,打印的信息室下面格式的:

UVM:2.3 为验证平台加入各个组件->2.3.7 加入field_automation机制_sed

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  jnZtF7Co41Wg   2023年12月06日   27   0   0 sedlinux数据
  uvM09mQNI0hF   2023年11月19日   29   0   0 sedshell字符串
  eHipUjOuzYYH   2023年12月06日   33   0   0 sedbootstrapIPV6
  xIUntf9oR6GI   2023年11月28日   31   0   0 sedvim基础命令
  oIa1edJoFmXP   2023年11月24日   31   0   0 AppsedVue
  L83A5jZvvg3Q   2023年11月22日   17   0   0 HTTP重定向字段
  L83A5jZvvg3Q   2023年11月22日   27   0   0 客户端HTTP字段
VDP7COGanTeB