Verilog系列:如何$random随机数
在Verilog中提供了一种较为简单易用的随机函数$random(seed),其主要功能是根据指定的种子(当然也可以不指定)产生一个有符号的32位整型伪随机数,产生的随机数可以用于一些需要随机化数的场景中。本文将以示例展示$random的一些用法和使用过程中遇到的一些问题及注意事项。
$random(seed)中的参数seed是可选择的,即可以指定也可以不指定,$random(seed)一般会根据seed的值生成随机数(这里的seed只是一个标识符,也可以指定其他字符组成的合法标识符,不一定非要用seed这个名称,本文为了表示方便使用seed表示),seed在每次$random(seed)调用后都会自动被修改。如下例。
【示例】
【仿真结果】
上例中,可以看到每次$random调用后,seed的值都会被修改。有的朋友在使用该函数时期望能够对seed进行一定的处理,但是这里需要注意的是,在调用$random(seed)时,其中的参数seed必须是一个确定的值,不能是一个表达式,如下例。
【示例】
【仿真结果】
18行试图将“seed%3”后的值作为随机种子,但是这时不行的。其实$random后的参数既是其进行随机时的输入也是随机结束后存在函数的一种返回值,可见,如果这个参数用一个表达式或者一个具体的数字显然是不行的。所以,$random后的参数,不能直接使用表达式或者具体的数字,其后的参数必须是一个变量且使用前就有确定的数值(哪怕是0\1\x\z)。上例中还实现了产生的随机数在一定的范围内,而限定产生随机数的一般格式如下:
$random(seed)%n
即实现了产生随机数范围为[(-n+1):(n-1)],这里n为大于0的整数。这个随机数的范围包含一部分负数部分,除了可以实现包含包含负数的随机数外,还可以实现0和正数范围内的随机,如下例:
【示例】
【仿真结果】
该示例中通过“{}”将$random(seed)随机产生的数约束为无符号数,实现了一定范围内非负数的随机,其一般格式如下:
{$random(seed)}%n
即实现了一个范围在[0:(n-1)]的随机数,这里n为大于0的整数。除了上述两种以0位中心的随机数外,还可以实现指定范围内的随机数,如下例:
【示例】
【仿真结果】
示例中产生了'h10-'h16之间的随机数,其实现一般格式如下:
min+{$random(seed)}%(max-min+1)
即实现了一个范围在[min:max]的随机数。在实际使用过程中$random(seed)中的参数可有可无,不一样的使用方式产生的结果也不尽一样,如下例:
【示例】
【仿真结果】
当seed为0时$random(seed)的结果与$random()一样,但是其结果与$random不一样,所以在使用时一定要注意。Verilog中除了$random(seed)这种随机函数外,还有$dist_uniform(seed,start,end)、$dist_nromal(seed,mean,standard_deviation)、$dist_exponential(seed,mean)、$dist_poisson(seed,mean)、$dist_chi_square(seed,degree_of_freedom)、$dist_t(seed,degree_of_freedom)、$dist_erlang(seed,k_stage,mean)等多种随机函数,具体可以参考IEEE1364,此处不再赘述。综上所述,$random使用时应该注意以下几点:
-
$random(seed)中seed在调用$random之前必须有确定的值(Verilog中一般声明了的变量都有默认值,如果不期望使用默认值可以给其指定特定的初始值);
-
$random()的括号中不能出现具体的表达式或者具体的数字;
-
$random一般有三种使用方式“$random()”、“$random(seed)”和“$random”;
-
可以使用“{}”将$random(seed)产生的随机数转变为无符号数;
-
可以对$random(seed)产生的随机数进行适当的处理以实现特定范围内的随机数;