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\Argument | SEQ_OR_ITEM | SEQR | PRIORITY | CONSTRAINTS |
---|---|---|---|---|
`uvm_do | ![]() | m_sequencer | -1 | {} |
`uvm_do_with | ![]() | m_sequencer | -1 | ![]() |
`uvm_do_pri | ![]() | m_sequencer | ![]() | {} |
`uvm_do_pri_with | ![]() | m_sequencer | ![]() | ![]() |
`uvm_do_on | ![]() | ![]() | -1 | {} |
`uvm_do_on_with | ![]() | ![]() | -1 | ![]() |
`uvm_do_on_pri | ![]() | ![]() | ![]() | {} |
`uvm_do_on_pri_with | ![]() | ![]() | ![]() | ![]() |