sv 约束问题
1、默认取值和注错取值
有时候transactiont中的变量var,在写case时如果我们不对他进行约束,它在默认的一个范围内取值,而某些我们希望对它取默认范围之外的数值时,这时候可以有下面几种做法。
1、提前规划,在transaction定义时额外加入一个ex_flag,当ex_flag=0时var取值在一个范围内,当ex_flag=1时,var取值在更大的一个范围。这样一般的case中我们约束ex_falg==0,特殊的case中我们约束ex_falg==1,然后var==默认范围外的值。
2、通过constraint_mode(0)关闭默认范围的约束块,然后对变量赋值。
3、用soft关键字修饰特定的约束语句,这样既可以让变量在一般的情况下取默认值,也可以直接给变量赋默认值范围外的取值。
2、randc
之前一直以为只要把transaction 中的变量声明为randc,那么变量的取值就会遍历取值范围然后才会重复,这其实是有问题的。
只有对一个对象来说,即new一次,多次随机化,每次随机的结果之间遵循randc的效果,遍历完所有取值结果后才重复。
对于多个对象来说,即new多次,并随机化,这多个对象之间的randc 变量的随机结果不会满足遍历完所有取值结果后才重复这样的说法。
所以在如果想要使用randc,就应该只new一个对象obj1,然后定义另外一个对象obj2,每次obj1随机化完成之后,将obj1的copy给obj2。
3、array 约束的效率问题
通过task将array中每个元素进行赋值比在constraint中对array的每个元素进行约束速率提升5倍,所以对于transaction中array中元素的赋值,一般可以放在post_randomize这个回调函数中的一个专门的task或function中。
4、implication constraint :if和 ->和<->
求解器对所有的约束并行执行;
A -> B 和表达式(!A || B)等价,即A==1时,B==1;A==0时,B可以为0/1。
if(A==1) B==1; else C==1;等价于两个约束即(A && B); (!A && C);
A<->B is defined as ((A->B) &&(B->A)) 即A==1时,B==1;A==0时,B==0;
{表达式1} == {表达式2};//这种约束和{表达式1} -> {表达式2}效果一样。
5、randomize() task
约束可以重载;
pre_randomize,post_randomize也可以被重载,但是他们定义的时候没有virtual关键字
本文来自博客园,作者:hematologist,转载请注明原文链接:https://www.cnblogs.com/littleMa/p/8569770.html
posted on 2018-03-14 20:09 hematologist 阅读(1368) 评论(1) 编辑 收藏 举报