UVM糖果爱好者教程 - 3.传输和序列

Transactions

Jelly-Bean Transaction

jelly_bean_transaction类根据口味,颜色和其他特征定义jelly_bean食谱。 它还具有称为口味的特性,以保持jelly_bean_taster(DUT)对口味的反应。 口味和颜色之间的关系在约束块(12行)中定义。 例如,如果口味是苹果口味,则颜色必须是红色或绿色(不是蓝色)。

更新(2014年4月2日):在本例中,我们使用了所谓的UVM字段宏(第23行至第27行)来节省编写“do-hook”函数的工作量。 我建议您在熟悉UVM后编写自己的“do-hook”函数,而不是使用这些宏。 有关更多信息,请参阅字段宏和“do”钩子。

class jelly_bean_transaction extends uvm_sequence_item;
   typedef enum bit[2:0] { NO_FLAVOR, APPLE, BLUEBERRY, BUBBLE_GUM, CHOCOLATE } flavor_e;
   typedef enum bit[1:0] { RED, GREEN, BLUE } color_e;
   typedef enum bit[1:0] { UNKNOWN, YUMMY, YUCKY } taste_e;
 
   rand flavor_e flavor;
   rand color_e  color;
   rand bit      sugar_free;
   rand bit      sour;
   taste_e       taste;
 
   constraint flavor_color_con {
      flavor != NO_FLAVOR;
      flavor == APPLE     -> color != BLUE;
      flavor == BLUEBERRY -> color == BLUE;
   }
 
   function new(string name = "");
      super.new(name);
   endfunction: new
 
   `uvm_object_utils_begin(jelly_bean_transaction)
      `uvm_field_enum(flavor_e, flavor, UVM_ALL_ON)
      `uvm_field_enum(color_e, color, UVM_ALL_ON)
      `uvm_field_int(sugar_free, UVM_ALL_ON)
      `uvm_field_int(sour, UVM_ALL_ON)
      `uvm_field_enum(taste_e, taste, UVM_ALL_ON)
   `uvm_object_utils_end
endclass: jelly_bean_transaction

Sugar-Free Jelly Bean

通过jelly_bean_transaction类可以扩展到各种类。 例如,要创建只有无糖jelly_bean,子类可以定义约束,如第4行所示。

class sugar_free_jelly_bean_transaction extends jelly_bean_transaction;
   `uvm_object_utils(sugar_free_jelly_bean_transaction)
 
   constraint sugar_free_con {
      sugar_free == 1;
   }
 
   function new(string name = "");
      super.new(name);
   endfunction: new
endclass: sugar_free_jelly_bean_transaction

Sequences

One Jelly Bean

该sequence创建正在生成的jelly_bean的食谱。第一个sequence是最简单的,因为它的目的是创建一个单一的jelly_bean。第10行创建一个jelly_bean transaction(配方),然后第12行随机化配方。

class one_jelly_bean_sequence extends uvm_sequence#(jelly_bean_transaction);
   `uvm_object_utils(one_jelly_bean_sequence)

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

   task body();
      jelly_bean_transaction jb_tx;
      jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name()));
      start_item(jb_tx);
      assert(jb_tx.randomize());
      finish_item(jb_tx);
   endtask: body
endclass: one_jelly_bean_sequence

Same-Flavored Jelly Beans (Sequence of Transactions)

现在让我们来创建相同风味的多个jelly_bean。使用名为num_jelly_beans的类属性指定创建的jelly_bean的数量。第4行将num_jelly_beans限制在2和4之间。第14行创建单个jelly_bean,并且行15将其颜色和风味随机化。以此jelly_bean为标准,第18行创建了与num_jelly_beans指定的相同口味的jelly_bean。第21行上的in-line约束保证了相同的味道。

class same_flavored_jelly_beans_sequence extends uvm_sequence#(jelly_bean_transaction);
   rand int unsigned num_jelly_beans; // knob
 
   constraint num_jelly_beans_con { num_jelly_beans inside { [2:4] }; }
 
   function new(string name = "");
      super.new(name);
   endfunction: new
 
   task body();
      jelly_bean_transaction           jb_tx;
      jelly_bean_transaction::flavor_e jb_flavor;
 
      jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name()));
      assert(jb_tx.randomize());
      jb_flavor = jb_tx.flavor;
 
      repeat (num_jelly_beans) begin
         jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name()));
         start_item(jb_tx);
         assert(jb_tx.randomize() with { jb_tx.flavor == jb_flavor; });
         finish_item(jb_tx);
      end
   endtask: body
 
   `uvm_object_utils_begin(same_flavored_jelly_beans_sequence)
      `uvm_field_int(num_jelly_beans, UVM_ALL_ON)
   `uvm_object_utils_end
endclass: same_flavored_jelly_beans_sequence

Gift-Boxed Jelly Beans (Sequence of Sequences)

下面的代码演示了如何创建多风味的jelly_bean。使用名为num_jelly_bean_flavors的类属性(第2行)指定口味的数量。在第四行,序列随机挑选两到三种口味。sequence的主要部分是重复块(来自第12行),其中创建了一系列same_flavored_jelly_beans_sequences。

class gift_boxed_jelly_beans_sequence extends uvm_sequence#(jelly_bean_transaction);
   rand int unsigned num_jelly_bean_flavors; // knob
 
   constraint num_jelly_bean_flavors_con { num_jelly_bean_flavors inside { [2:3] }; }
 
   function new(string name = "");
      super.new(name);
   endfunction: new
 
   task body();
      same_flavored_jelly_beans_sequence jb_seq;
      repeat (num_jelly_bean_flavors) begin
         jb_seq = same_flavored_jelly_beans_sequence::type_id::create(.name("jb_seq"), .contxt(get_full_name()));
         assert(jb_seq.randomize());
         jb_seq.start(.sequencer(m_sequencer), .parent_sequence(this));
      end
   endtask: body
 
   `uvm_object_utils_begin(gift_boxed_jelly_beans_sequence)
      `uvm_field_int(num_jelly_bean_flavors, UVM_ALL_ON)
   `uvm_object_utils_end
endclass: gift_boxed_jelly_beans_sequence

这篇文章介绍了jelly_bean验证环境中的transaction和sequence。下一篇文章将提供对验证组件的解释。


原文地址:UVM Tutorial for Candy Lovers – 3. Transactions and Sequences

文末有一些评论挺有意思。

例如,有人问,你为什么不在sequence中用uvm_do宏啊,作者的回答是为了在sequence更好的控制trans。例如,你想在随机后调用trans.print()打印,就不能用uvm_do宏了,用三步走的策略可能更好一些。

就我个人而言,我会把评论都看了,看读者遇到的问题,以及作者如何回答,加深理解。


QA中的一个:

Q:你能详细解释一下`uvm_do宏的区别吗?

A:所有`uvm_do *宏在内部调用`uvm_do_on_pri_with宏。 'uvm_do_on_pri_with宏需要四个参数(SEQ_OR_ITEM,SEQR,PRIORITY和CONSTRAINTS)。每个`uvm_do *宏指定参数的一个子集,如下所示:

Macro\ArgumentSEQ_OR_ITEMSEQRPRIORITYCONSTRAINTS
`uvm_doSEQ_OR_ITEMm_sequencer-1{}
`uvm_do_withSEQ_OR_ITEMm_sequencer-1CONSTRAINTS
`uvm_do_priSEQ_OR_ITEMm_sequencerPRIORITY{}
`uvm_do_pri_withSEQ_OR_ITEMm_sequencerPRIORITYCONSTRAINTS
`uvm_do_onSEQ_OR_ITEMSEQR-1{}
`uvm_do_on_withSEQ_OR_ITEMSEQR-1CONSTRAINTS
`uvm_do_on_priSEQ_OR_ITEMSEQRPRIORITY{}
`uvm_do_on_pri_withSEQ_OR_ITEMSEQRPRIORITYCONSTRAINTS
'uvm_do_on_pri_with创建一个SEQ_OR_ITEM,用CONSTRAINTS对其进行随机化处理,然后在指定的PRIORITY的SEQR上启动它。
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值