当前位置:首页 > > 处芯积律


1. 正文


节气


2024 SUMMER

记录个在写SystemVerilog随机约束时遇到的一个小坑,如果没有认真去查看随机结果是否符合预期,还真不容易发现。


为了方便讲述,写了如下示例代码。类cl_a里有个随机变量aa,初始值为222。在module top里对类cl_a例化并进行约束随机。

class cl_a; rand int aa = 222;endclass module top; cl_a a; int b = 1; initial begin a = new(); $display("[initial]=> aa:%0d", a.aa); assert ( a.randomize() with { aa == (b == 1) ? 666 : 999;} ) else $fatal; $display("[random1]=> aa:%0d", a.aa); assert ( a.randomize() with { aa == ((b == 1) ? 666 : 999);} ) else $fatal; $display("[random2]=> aa:%0d", a.aa); assert ( a.randomize() with { aa == (b == 1);} ) else $fatal; $display("[random3]=> aa:%0d", a.aa); assert ( a.randomize() with { aa == 8 ? 666 : 999;} ) else $fatal; $display("[random4]=> aa:%0d", a.aa); endendmodule



先不看仿真结果,你们觉得行11和行14的随机结果一致吗?


是的,它们俩的结果完全不一样,如果你知道为什么会不一样,那么接下来的内容就不用看了。其实也很简单,对SystemVerilog运算符优先级记得很清楚的同仁,应该一眼就看出毛病了。==运算符的优先级高于三目运算符(?:)。


在行11中,会先算(b==1)为X,接下来算a==X为Y,这时候这里的==不是作为随机约束符号来使用的,它在三目运算符(?:)中判断是否相等来使用的,因此a其实是没有加任何约束,也就是a会被随机之后,再判断a==X的值Y。所以我们最终看到[random1]打印的aa为随机数。


在行14中,会先算((b == 1) ? 666 : 999)里面的内容,b==1结果为1,所以三目运算符结果为666,然后计算a==666,这里的==就作为随机约束符号了,因此最终看到[random2]打印的aa为666。


在行17中,会先算(b == 1),结果为1,然后再算a==1,这里的==也作为随机约束符号,最终看到[random3]打印的aa为1。


行20其实和行11是类似的,这里a==8的==不是作为约束符号,而是简单的判断是否相等符。因此最终aa的值是随机的。


使用VSC进行仿真,结果如下:

[initial]=> aa:222[random1]=> aa:897241389[random2]=> aa:666[random3]=> aa:1[random4]=> aa:-1705158938


2. 总结


节气


2024 SUMMER

其实说白了,要么大家认真记住SystemVerilog的符号优先级规则,要么在不大确定的地方多用写括号()来确定符号运算的顺序,减少意外发生。行11和行14就差个括号,但结果完全不一致,而且仿真也不会报任何warning或error信息。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭