The UVM Primer -- Chpater 21 UVM Transaction

本文深入探讨了UVM中的交易(Transaction),包括如何在对象中存储数据,定义数据的随机范围,以及如何实现uvm_transaction的new、do_copy、do_compare和convert2string等关键函数。通过创建和使用UVM交易,可以优化测试平台的效率,提高代码复用性,并简化代码结构。文章还介绍了如何在测试平台的不同组件中升级和应用交易,以便更好地管理和比较数据。
摘要由CSDN通过智能技术生成

Chpater 21 UVM Transaction

21.1 Storing Data in Objects

从学习本书开始,我们将测试平台拆分形成一个小模块,每个模块,每个class只专注于一件事情。尽力避免一个class需要详细了解另一个class的工作内容的场景,两个不同class之间可以通过port的方式传递数据。以上工作都使得我们的测试平台变得十分高效,但是我们还留下了一些遗憾:没有对传输的数据进行处理!
TinyALU测试平台中的数据结构比较简单,command_s中包含三个变量:A,B,op。即使我们的TinyALU测试平台很小,我们也在许多地方反复调用这些值。driver,coverage,scoreboard,因此如果我们可以对数据进行处理优化,就可以进一步提升测试平台的工作效率。将数据存储在class中,可以使用函数进行数据处理,这是class优于struct的地方。

  • 在UVM中这种数据class称作transaction,transaction封装了数据和数据的所有操作类型,这些操作如下:
    • convert2string(): 将数据以字符串的形式打印;
    • do_copy(): 将另外一个transaction的数据拷贝至当前transaction;
    • do_compare(): 比较两个transaction的数据是否一致;
    • randomize(): 利用SystemVerilog的random机制;
  • 定义Transaction:
    • 我们扩展uvm_transaction以生成需要的command_transaction,我们需要重新改写以下三个函数:
    • do_copy()
    • do_compare()
    • convert2string()

21.1.1 定义数据的随机范围

command_transaction中需要定义随机变量,采用SV的rand定义,并用constraint约束变量的随机范围。这样我们就不再需要get_op()函数和get_data()函数,SV可以接手所有的随机工作,我们只需要在定变量的时候在前面增加rand关键字即可:

class command_transaction extends uvm_transaction;
   `uvm_object_utils(command_transaction)
   rand byte unsigned        A;      //定义操作数A,只需要在定义之前加rand关键字
   rand byte unsigned        B;
   rand operation_t         op;

   constraint data {
    A dist {
   8'h00:=1, [8'h01 : 8'hFE]:=1, 8'hFF:=1};
                     B dist {
   8'h00:=1, [8'h01 : 8'hFE]:=1, 8'hFF:=1};} 
    //指定A B的范围可以指定,甚至可以用dist决定随机值的出现概率

21.1.2 uvm_transaction的new函数

uvm_transaction扩展自uvm_object,不是component类型,在构造时不需要parent handle,只需要name即可。(component类型的class在构建的时候需要知道在环境中的具体节点位置,所以需要parent)

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

21.1.3 do_copy函数

uvm_object类和其子类都包含copy()函数和clone()函数,其中copy函数拷贝一个对象的数据至另一个同类型对象,clone函数返回数据完全一致的同类型的对象;copy是将数据拷贝一份,clone是返回一个新的对象。
copy函数和clone函数能够工作的前提是:我们必须重构do_copy函数,do_copy函数的工作机制和我们上一章节定义lion的convert2string的机制一致,需要调用父类的同名函数。

   function void do_copy(uvm_object rhs);
      command_transaction copied_transaction_h;

      if(rhs == null) 
        `uvm_fatal("COMMAND TRANSACTION", "Tried to copy from a null pointer")
      
      //检查传输的rhs不是command_transaction类型,拷贝失败
      if(!$cast(copied_transaction_h,rhs))
        `uvm_fatal("COMMAND TRANSACTION", "Tried to copy wrong type.")
      
      super.do_copy(rhs); // copy all parent class data

      A = copied_transaction_h.A;
      B = copied_transaction_h.B;
      op = copied_transaction_h.op;

   endfunction : do_copy

21.1.4 clone_me函数

  • 使用uvm_transaction的好处之一:在多个模块多个对象中都可以看到相同的数据,在模块较小的TinyALU中可能考不到优势,如果我们的设计包含250个port,原本需要250份备份数据的空间,现在只需要一个即可。
  • 双刃剑:上述机制也存在一定的短板:无论任何一个对象对数据进行了修改,整个测试环境看到的数据都会变化。因此引入了MOOCOW(Manual Obligatory Object Copy On Write)机制,如果我们希望对transaction中的数据进行操作就需要强制拷贝一个备份,并在自己的世界里进行修改。
  • 当然,有些设计中希望在某个模块(如uvm_callbacks)检测transaction数据,发现异常的时候就进行修改,这样也是充分利用了uvm_transaction的优势。
   function command_transaction clone_me();
      command_transaction clone;
      uvm_object tmp;

      tmp = this.clone()
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值