总结verilog产生随机数的$random和seed
$random(seed)是verilog中最简单的产生随机数的系统函数。
在调用系统函数$random(seed)时,可以写成三种样式:1)$random,2)$random(),3)$random(seed)。下面分别说明:
1)$random
这是最简单的一种写法,略去了seed这个传入参数,$random会使用一个默认的seed(这个默认值为0?)。也正因此,每次进行仿真时,$random产生的随机数序列都是相同的。
2)$random()
这种写法和写法1)的作用是相同的,同样是没有给$random传入seed。
3)$random(seed)
这种写法与上面两种不同,给$random传入了参数seed,因此$random根据seed来产生随机数。seed不同,产生的随机数的序列也不同。而且,每执行一次$random(seed)产生一个随机数,seed也自动更新一次。
下面讨论seed的产生。
据我有限的知识,seed有两种产生方式:4)直接赋值为一个确定数,5)利用系统函数$get_initial_random_seed获得值。下面分别讨论:
4)直接赋值
在一个initial块中直接将seed变量写成某值,如下面代码:
integer seed;
reg [7:0] rand_num;
initial begin seed = 0; end
always @(posedge clk) begin rand_num <= $random(seed); end
在上面代码中,seed初始值被赋为0(也可以是1或其它数),在第一个时钟上升沿,rand_num取得的第一个随机数就是$random(0)产生的,seed也随即更新;在第二个时钟上升沿时,rand_num取得第二个随机数,是$random(更新后的seed)产生的,seed又随即更新;如此下去。
值得注意的是,如果把seed赋值为0,那么利用$random(seed)产生的随机数序列和直接执行$random产生的随机数序列是相同的。这个结论是我根据经验得出的。
5)seed = $get_initial_random_seed()
如下面代码:
integer seed;
reg [7:0] rand_num;
initial begin seed = $get_initial_random_seed(); end
always @(posedge clk) begin rand_num <= $random(seed); end
在上面代码中,利用系统函数得到的seed的值是1,此后seed更新后的值和$random(seed)产生的随机数序列都和将seed直接赋值成1,利用$random(seed)产生随机数的情况相同。这也是我根据经验得出的结论。
我在网上没有找到关于$get_initial_random_seed的详细介绍。
下面讨论仿真时如何改变seed的初值:
如果seed的初值是确定的,那么不论进行多少次仿真,产生的随机数的序列总是确定的,就不能覆盖更多的情况。因此在仿真时,要能够改变seed的初值。目前我所知道的改变seed的初值有两种方法:6)修改代码;7)采用deposit方式。下面分别介绍:
6)修改代码
这种方式最直接,缺点是每次要修改seed时都需要重新编辑一遍代码。
比如,第一次仿真时,代码写成下面的样子:
integer seed;
reg [7:0] rand_num;
initial begin seed = 0; end
always @(posedge clk) begin rand_num <= $random(seed); end
而第二次仿真时,想修改seed的初值,就写成下面的样子:
integer seed;
reg [7:0] rand_num;
initial begin seed = 1; end
always @(posedge clk) begin rand_num <= $random(seed); end
7)采用deposit的方式
这种方式比较灵活,不必修改代码,也不必重新编译,直接修改输入到仿真软件的命令即可。
下面是最简单的一个命令:
deposit top.seed 2
run 125ns
exit
上面命令的意思是,将信号(或变量)seed的初值设成1,然后开始仿真,仿真时间为125ns,然后结束仿真。
deposit是在仿真开始之前起作用的(如果没有给deposit加上其它时间方面的条件),而且它只是将某个信号的初始值设为某一个数(可以是确定数,也可以是随机数),此后便不再干预该信号的值。如果仿真开始后有别的条件或语句改变该变量的值,则该变量就变成改变后的值。
如果代码按下面的样子写:
integer seed;
reg [7:0] rand_num;
initial begin seed = 1; end
always @(posedge clk) begin rand_num <= $random(seed); end
我们来看一下,在仿真开始之前deposit将seed赋值为2,然而仿真开始后的0ns时刻,initial块又将seed赋为1,因此相当于deposit没有起到预期的作用。我们想要的是,seed的初值为2,$random(2)产生一个随机数后,seed再由2变成其它的数;而不是$random(1)产生一个随机数,然后seed又由1变成其它的数。
为了达到我们的预期目的,要把deposit命令改成下面的样子:
deposit top.seed 2 -after 1ns
run 125ns
exit
在仿真开始的0ns时,initial块执行,将seed设为1。加上"-after 1ns"后,deposit命令就会在仿真开始后的1ns时起作用,把seed的值改为2,然后作用于第一次$random(seed)的执行,然后seed再更新。
综上讨论,我得出以下结论:
1. 利用$random产生随机数时最好利用上seed参数,即写成$random(seed)样式。
2. 没有必要利用$get_initial_random_seed()函数给seed赋值,直接写成一个值即可,像4)一样。
3. 建议用deposit的方式在仿真时改变seed的初值,使$random(seed)产生不同的随机数序列
总结verilog产生随机数的$random和seed的更多相关文章
- java中Random(long seed)方法与rRandom()方法的使用产生随机数
Random 类作为JAVA中用于产生的随机数 ,new Random(10) :10是种子数. 注意:Random 的一个特点是:相同种子数的Random对象,对应相同次数生成的随机数字是完全相 ...
- erlang的随机数 及 random:uniform()函数
每次调用会更新进程字典里的random_seed变量,这样在同一个进程内每次调用random:uniform()时,随机数种子都不同,所以生成的随机数都不一样(调用完random:uniform()后 ...
- python模块 | 随机数模块—random模块
python随机数模块 random - 生成伪随机数,该模块实现了各种分布的伪随机数生成器. 对于整数,从范围中有统一的选择. 对于序列,存在随机元素的统一选择.用于生成列表的随机排列的函数.以及用 ...
- js 获取随机数 Math.random()
js 获取随机数 Math.random() // 结果为0-1间的一个随机数(包括0,不包括1) var randomNum1 = Math.random(); //console.log(rand ...
- python 随机数模块 -- random
一.概述 这个模块实现的伪随机数生成器. 对于整数,从区间选取.对于序列,随机元素. 在实线的,有功能来计算均匀分布,正态分布(高斯) ,对数正态分布,负指数,γ和β分布.对于生成的角度分布,冯·米塞 ...
- js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();)
js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();) ...
- [ Python入门教程 ] Python生成随机数模块(random)使用方法
1.使用randint(a,b)生成指定范围内的随机整数.randint(a,b)表示从序列range([a,b])中获取一个随机数,包括b. >>> random.randint( ...
- 生成随机数(Random类)和获取用户输入(Scanner类)
生成指定范围内的随机数 Math.random() 生成随机数,随机数在0到1之间,类型是 double. public class randCase { public static void mai ...
- 随机数类 Random
import java.util.Random; /* 随机数类 Random 需求: 编写一个函数随机产生四位的验证码. */ public class Demo5 { public static ...
随机推荐
- LINUX的ssh免密码配置
本篇将介绍LINUX的ssh免密码配置. 本篇中的有三台主机: 192.168.1.110 master.com.cn 主机192.168.1.111 salver1.com.cn192.168.1 ...
- 杂记 -- 关于less在vue项目中的使用
1.安装less,less-loader npm install less less-loader --save 2.配置wepack.js(vue3+版本中不用自己设置) //添加less路径模块 ...
- P3810 【模板】三维偏序(陌上花开)(CDQ分治)
题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai.b_ibi.c_ici 三个属性,设 f(i) ...
- windows下CreateDirectory创建路径失败的解决办法
第一: 权限不够: SECURITY_ATTRIBUTES sa;SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor(&sd,SECURI ...
- 3.docker machine 连接 aliyun 远程docker 服务器
1.在aliyun ecs 创建docker 服务器 docker-machine create -d aliyunecs machine-aliyunecs 2.远程连接 docker 获取客户端 ...
- ES6之展开运算符
本文介绍ES6新增的展开运算符(spread operator). 由上图可得,展开运算符负责拼装数组和对象,与之相反,解构赋值负责分解数组和对象. 由上图可得,展开运算符能和解构赋值一起发挥成更大的 ...
- 笔记本安装SSD固态硬盘详细的优化设置
现在好多笔记本.台式机都加上固态硬盘了,固态硬盘的优势大家应该都有所了解了,在此略写一下固态硬盘优势: 1.启动快,没有电机加速旋转的过程: 2.不用磁头,快速随机读取,读延迟极小: 3.相对固 ...
- cocoaPods安装使用亲体验
一. cocoaPods的安装. 终端中输入: $ sudo gem install cocoapods 注意:直接在terminal中输入这个是安装不成功的,因此,我们可以通过淘宝的Ruby镜像来访 ...
- C#的静态方法和实例化方法的区别
C#的静态方法和实例化方法的区别 在大多数时候,我们写一个方法,会把方法区分为实例化方法和静态方法.而当被问到静态方法和实例化方法的区别的时候,我在写这篇文章的前10分钟,或许我会回答:"静 ...
- 大言不惭 swank? talk about sth or speak too confidently
cán,意思是指说大话而毫不感到难为情.出自<论语·宪问>:“子曰:‘其言之不怍,则为之也难.’”宋·朱熹注:“大言不惭,则无必为之志,而不自度其能否也.欲践其言,其不难哉!” 是不是类似 ...