第六章:随机化(续1)
Posted xuqing125
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六章:随机化(续1)相关的知识,希望对你有一定的参考价值。
6.6 pre_randomize和post_randomize函数
我们在调用randomize()函数之前或者之后要立即执行一些操作。比如,在随机化之前可能要设置类里的一些非随机变量(上下限、权重),或者随机化之后需要计算随机数据的误差矫正位。
SystemVerilog中可以使用void类型的pre_randomize和post_randomize函数来完成这些功能。void类型的函数并没有返回值,与任务不同,并不会消耗时间。
6.6.1 构造浴缸型分布函数
我们在实际的应用中,通常要用到一些非线性的随机分布,这时候我们希望能够有一种浴缸型的分布,在两端的概率大,中间的概率小。
可以通过详细描述dist约束构造浴缸型的分布,但是需要多次调整才能获得需要的形状。
在Verilog中,我们已经提供了很多非线性函数,例如:$dist函数,但是并没有浴缸型函数,这时我们可以通过两条指数曲线去构造我们想要的函数。
常用的函数:
- $random() ——平均分布,返回32比特有符号随机数;
- $urandom() ——平均分布,返回32比特无符号随机数;
- $urandom_range() ——在指定范围内的平均分配;
- $dist_exponential() ——指数衰落;
- $dist_normal() ——钟型分布;
- $dist_poisson() ——钟型分布;
$dist_uniform() ——平均分布;
值得一提的是由于变量value是由function计算得到的,而不是随机约束求解器得到的,所以并不需要rand修饰符定义。6.7 约束的技巧和技术
我们怎样才能写出便于维护和修改的CRT?通常是有一些小技巧的。下面我们就这些技巧做一下介绍。
6.7.1 使用变量的约束
通常一些上下限还有一些权重值,可以通过设置一个变量来维护。
可以通过改变read8_wt=0,来禁止这项命令生效。缺省情况下,read8_wt,read16_wt,read32_wt是1,1,1.6.7.2 用约束检查值的有效性
调用handle.randomize()函数的同时,SystemVerilog会检查这些变量是否满足约束条件。
6.7.3 调试函数
在随机化的过程中,为了输出随机化的结果,我们通常会设置function void display()函数来进行可视化输出。
6.7.4 非随机值的使用
如果一套的随机约束已经产生了大部分你想要的激励向量,只有少数几个向量需要修改,那么你可以使用rand_mode()函数把这些变量设置成非随机变量。
利用调试函数得出结果
对length变量进行rand_mode()设置以后,约束丧失了对length的约束能力。6.7.5 随机化个别变量
上一小节,我们讲了从一个大的约束里面除去对某个变量的约束,那么这一小节我们来讲,只对某一个或者某几个变量进行约束。
在调用randomize()函数时只传递变量的一个子集,这样的话就只会随机化类里面的几个变量。只有参数列表里面的变量才会被随机化。所有的约束仍然保持有效。
low是一个非随机变量,却被随机化赋于了一个随机值,并且满足约束条件。6.7.5 打开或关闭约束
如果利用if-else语句声明的约束显得很复杂,可读性不是很强的情况下,可以采用打开或关闭进行约束。
6.7.6 在测试过程中使用内嵌约束
使用random()with{}内嵌约束语句使约束的作用范围局部化,作为对约束的补充是一种很好的做法。但是与之而来的问题是约束代码位于代码不同的位置,还难维护;其次很难在不同的测试里复用这些内嵌约束。
6.7.7 在测试过程中使用外部约束
我们知道函数的函数体可以在函数的外部定义,同样,约束的约束体也可以在类的外部定义。
- 外部约束可以放到另一个文件中,从而在不同的测试里可以复用外部约束。
外部约束对类的所有实例都起作用,而内嵌约束仅仅影响一次randomize()调用。
6.8 随机化常见的错误
6.8.1 小心使用有符号变量
- 除非必要,不要在随机约束里使用有符号的数据类型。
在使用无符号的数时,一定要注意是否溢出,这个问题可以通过限制位宽来解决。
6.9 迭代和数组约束
以上篇幅我们都只对标量类型的变量进行约束,现在思考如何在随机化数组时进行约束?
利用foreach约束和一些数组函数可以改变值的分布性状。
利用foreach会影响仿真器的运行速度,特别是遇到foreach嵌套的时候,这个时候我们可以通过使用randc变量来代替foreach的嵌套。6.9.1 数组的大小
size()函数可以用来约束动态数组或队列里的元素个数。
一定要设置数组的上限,否则会产生成千上万个元素。6.9.2 数组元素的和
sum()函数可以用于约束数组中元素的和。在使用sum()函数的时候,你需要注意一下几点:- 使用无符号的数
- 注意位宽
注意溢出问题
6.9.3 约束数组和队列的每一个元素
foreach能够对数组里的每一个元素进行约束。
foreach约束只能有一个数组名,不允许使用层次化的引用。6.9.4 产生具有唯一元素值的数组
怎么才能产生一个随机数组,使它的每一个元素的值都是唯一的呢?
方法一:使用嵌套的foreach循环让求解器比较任意两个元素,但是这样会降低仿真器的求解速度。
方法二:使用包含randc变量辅助类,这样的话就可以不断随机化同一个变量。
方法三:最为常用的一种方法。将方法二中的常量参数化。**
- new函数用来产生max_value,用于RandcRange的参数输入。
display函数用于调试输出。
以上是关于第六章:随机化(续1)的主要内容,如果未能解决你的问题,请参考以下文章