有些特定场景下,我们可能需要将约束块或者随机变量开启使能或者关闭来构造工程师们想要的激励而不影响其他已经调试过的cases,System verilog有两个task分别对应对约束块和随机变量的开关。
constraint_mode():首先它是内嵌的,不能overridden重载。即可以作为一个task也可以作为一个function。
作为task,它的原型如下
task object[.constraint_identifier]::constraint_mode( bit on_off );
作为function,它的原型如下
function int object.constraint_identifier::constraint_mode();
上面的object就是一般定义了constraint block约束块的对象句柄,一般就是你在system verilog的class类或者相似文件。
Constraint_identifier就是constraint block约束块名字。
如果此处调用没有constraint_identifier这一项那么它会作用到当前文件中定义(object)的所有约束块,当然这种用法仅限于被用作task,如果function这样用会报编译error的。
如果被用作task当实参设为1时当前文件类或者你指定的约束块是可以完成randomize(),否则是不能的,当然默认情况下是打开的,只有你需要构造特殊用力而不影响其他场景用例时可以选择关闭还是开启。
从function的定义我们可以看出它的返回值是一个整型变量,其实只是返回0或者1。当约束块为active状态时(就是能randomize())时返回1,反之返回0。
举个例子吧
class example;
rand unsigned int aa_bb;
constraint name_exp { aa_bb > 2 * m; };//constraint block here
endclass
function unsigned int exp_pp( example p );
if ( p.name_exp.constraint_mode() )
p.name_exp.constraint_mode(0);//当前约束块被设置为inactive
else
p.name_exp.constraint_mode(1);
exp_pp = p.randomize();
endfunction
else分支最后返回了一个p class中变量aa_bb的值作为这个function的返回值。
好了再来讲讲rand_mode()吧
rand_mode()用来控制一个随机变量是否需要随机的开关,在某些异常用例你不需要用到正常用例中对某个随机变量值得约束,而是要给它一个特定值,此刻这个家伙就看起来很帅。
它也既可以用作task,也可以用作function。
作为task,它的原型如下
task object[.random_variable]::rand_mode( bit on_off );
作为function,它的原型如下
function int object.random_variable::rand_mode();
上面的object就是一般定义了随机变量的的对象句柄,random_variable就是里面的随机变量或者被调用的子类
作为task如果此处调用没有random_variable这一项那么它会作用到当前文件中定义(object)的随机变量或者被调用的子类,同上,如果function这样用会报编译error的。
这里有以下几点需要注意
1. 如果变量是unpaked数组,那么你可以利用index选择性的开关其中一员的随机性,比如
rand logic[16:0] aa[19:0];
..aa[i][i].rand_mode(bit on_off)。如果没有指定具体哪一个就会对所有元素起作用。
注:维数在变量名声明之前的为paked array,维数在变量名声明之后的为unpaked arrary
bit [7:0]aa; // packed array of scalar bit types
real bb [7:0]; // unpacked array of real types
2.如果变量是unpaked structure,可以对其中某一元素开关随机性
如:
class packet;
typedef struct {//此处upaked struct不能使用randc
randc int addr = 1 + constant;//但是uppaked struct的元素可以定义为rand和randc
int crc;
rand byte data [] = {1,2,3,4};
} header;
rand header h1;
endclass
packet p1=new;
P1.h1.data.rand_mode(0);//此处的data.
如果没有指定就对所有元素起作用。
3.如果随机变量是一个对象句柄,则只更改该变量的随机模式,而不更改该对象中随机变量的随机模式。
作为function的定义它的返回值是一个整型变量,也其实只是返回0或者1。当约束块为active状态时(就是能randomize())时返回1,反之返回0。
比如class exp;
rand int aa_v, bb_v;
...
endclass
int cc;exp exp_a = new;
// Turn off all variables in object
exp_a.rand_mode(0);
// Enable aa_v
exp_a.aa_v.rand_mode(1);//task here
cc = exp_a.bb_v.rand_mode();//function here.
System verilog本质在于随机化,更好的控制随机化能会为你的场景构造起到事半功倍的效果。今天就到这里吧,下次有时间会提供枚举类型在环境可重用性和可读性方面的应用讲解。