外部约束和双向约束
1.外部约束
外部约束的外部是相对于类的,外部约束的约束名依然要定义在类内,在外部需要通过 :: 锚定回 Packet。

当在类外写了 constraint Packet::c_external {length == 1;} 后,求解器会把类内的 c_valid 和类外的 c_external 合并成一个约束池,必须同时满足:
类内要求:length > 0 且 payload.size() == length
类外要求:length == 1
这属于 “硬约束(Hard Constraint)”,和写在类里面的 c_valid 地位完全平等,没有任何优先级之分。
2.内联约束
通过断言assert(randomize() with(约束,约束之间用分号;隔开)),内联约束指的就是写在randomize中的约束,这种约束仅本次调用时临时附加。如果与类内硬约束冲突,会导致随机化失败;如果类内用了 soft,with 可以覆盖

以这个为例:assert(p.randomize() with { length == 5; });,假如类内约束或者外部约束定义了length ==1,则这个随机化必然失败。
randomize单独控制变量也行:

** 注意:randomize(med) 绝对会受到类内约束 c_up 的影响。 求解器会把当前 low 和 hi 的值作为“固定值”,强制要求新随机出的 med 必须满足 low < med < hi**
3.双向约束

双向约束的约束块不像自上而下执行的程序性代码,它们是声明性的代码,是并行执行的。所有的约束表达式同时有效,SV 求解器会同时计算所有相关的随机变量和约束条件,并寻找满足所有约束条件的解。也就是说约束快内的条件如果出现矛盾可能会随机化失败,只有没有矛盾点才能保证随机化正常进行,因此,在编写复杂的双向约束时,必须确保逻辑的一致性。
4.控制多个约束块constraint_mode()
通过constraint_mode能直接控制约束块,p.c_short.constrain(0)是禁止,p.c_short.constrain(1)是允许,而p.constrain(0)是将包p内所有约束块都禁止。

5.pro_randomize和post_randomize
很容更易理解,pre是预处理也就是比randomize先执行,设定randomize相关变量的值,post比randomize后执行,对randomize随机出来的值做后续处理。注意往往在sv中这两个以函数的形式出现,仿真器在检测到pre函数后就会先执行。
注意:randomize执行失败导致post无法执行,但是pre还能执行

5.控制随机变量rand_mode()
与前面的随机化是一样的,只不过这里换成了变量。同样也可以整体关闭所有变量的随机化

6.约束的重载

重约束的概念是将原来class类中定义的约束通过constraint_mode(0)关闭约束,然后用randomize() with()重新临时约束,注意是对约束句柄p操作不是对类进行操作
注意约束也要能看懂,在上图中的约束中当x为0时y必须为0,当x为1时y值则是不受约束的,可以是0123任何一个。
randomize的一个作用用就是进一步约束,在原本类约束的基础上在进行约束,取交集求取符合要求的值。也就是说with中的约束要与类class约束有交集。
7.约束的覆盖(子类覆盖掉父类)
将原来的约束覆盖掉,原来的是x为0,y才为0,是直接将两个都约束成0.(现在子类句柄访问的所以子类约束覆盖掉父类的,如果是父类句柄仍然是原约束)

8.randomize例子

randomize是只随机化一次,第一次hi随机化出来81,后续只是对单个变量进行随机化,因此会保持。
浙公网安备 33010602011771号