在上一篇文章中,我们讨论并得出了一种构建可控随机的方案:
【芯片验证】异步电路碎碎念(十)在静态对象内构建可控随机·方案一
这篇文章呢我们讨论另外一种方案,为啥有方案了还要尝试其他的方案呢?我自己对$random这个函数相当的不信任,这个函数不受seed控制到低随机时候从哪找的种子我也不太清楚,万一跟地域、时间、服务器、工具等特性有关系,环境一迁移导致随机无法复现怎么办呢。所以我希望有一种原理明明白白的可控随机方案,当然这里并不是说$random+$urandom不能用哈,实际上我知道的很多地方就是直接用这个的。
原理明明白白的可控随机方案怎么来呢?既然不信任$random那必然是从$urandom入手看了,还记得$random的问题是啥来着吧?不能感知静态模块的不同例化路径差异。那么让他感知一下例化路径差异不就好了嘛,怎么感知这个事,相信大家对这个字符都很熟悉:%m,对就是在打印里用的那个字符。这个字符的作用是打印当前模块(或独立命名域)的例化路径,打印里的前半部分就是靠这个打印出来的:
$display("%m new_rand_value = 'h%0h", new_rand_value);
----->
testbench.u_rand_test1 new_rand_value = 'hd7
string path_str;
initial begin
path_str = $psprintf(path_str, "%m");
$display("inst path is %s", path_str);
end
inst path is testbench.u_rand_test0
inst path is testbench.u_rand_test1
string path_str;
int path_int;
initial begin
path_str = $psprintf(path_str, "%m");
path_int = path_str;
$display("inst path is %s, path_int = 'h%0h", path_str, path_int);
end
----->
inst path is testbench.u_rand_test0, path_int = 'h65737430
inst path is testbench.u_rand_test1, path_int = 'h65737431
string path_str;
int path_int;
initial begin
path_str = $psprintf(path_str, "%m");
path_int = $urandom();
for(int i=path_str.len; i>=0; i=i-1)begin
path_int = path_int ^ path_str.getc(i);
path_int = $urandom(path_int);
end
path_int = $abs(path_int);
$display("inst path is %s, path_int = 'h%0h", path_str, path_int);
end
经过这些操作后,咱们来看下进行随机后的结果:
inst path is testbench.u_rand_test0, path_int = 'h66b884a6
inst path is testbench.u_rand_test1, path_int = 'h49aee46
inst path is testbench.u_rand_test0, path_int = 'h21669974
inst path is testbench.u_rand_test1, path_int = 'h19e00dfa
tc seed = 62302096
inst path is testbench.u_rand_test0, path_int = 'h19bc271c
inst path is testbench.u_rand_test1, path_int = 'h7eef9304
tc seed = 81054216
inst path is testbench.u_rand_test0, path_int = 'h268220ce
inst path is testbench.u_rand_test1, path_int = 'h44c8d731
tc seed = 53991314
inst path is testbench.u_rand_test0, path_int = 'h21669974
inst path is testbench.u_rand_test1, path_int = 'h19e00dfa
tc seed = 62302096
string path_str;
int path_int;
initial begin
path_str = $psprintf(path_str, "%m");
path_int = path_str;
path_int = $urandom($urandom($urandom($urandom(path_int))));
$display("inst path is %s, path_int = 'h%0h", path_str, path_int);
end
----->
inst path is testbench.u_rand_test0, path_int = 'h6a6ed13
inst path is testbench.u_rand_test1, path_int = 'h86b6f7a1
tc seed = 0
inst path is testbench.u_rand_test0, path_int = 'h6a6ed13
inst path is testbench.u_rand_test1, path_int = 'h86b6f7a1
tc seed = 38445033
答案也很简单,封装成一个函数不就好了嘛:
string path_str;
initial path_str = $psprintf(path_str, "%m");
function integer urandom;
integer seed, i;
begin
seed = $urandom();
for(i=path_str.len; i>=0; i=i-1)begin
seed = seed ^ path_str.getc(i);
seed = $urandom(seed);
end
urandom = $abs(seed);
end
endfunction
initial begin
int rand_test;
rand_test = urandom();
$display("%m, rand_test = %0d", rand_test);
end
testbench.u_rand_test0.unnamed$$_0, rand_test = 1641770003
testbench.u_rand_test1.unnamed$$_0, rand_test = 621788312
tc name = sanity
tc seed = 59908161
testbench.u_rand_test0.unnamed$$_0, rand_test = 1271321994
testbench.u_rand_test1.unnamed$$_0, rand_test = 588367474
tc name = sanity
tc seed = 73017818
testbench.u_rand_test0.unnamed$$_0, rand_test = 97687901
testbench.u_rand_test1.unnamed$$_0, rand_test = 704389240
tc name = sanity
tc seed = 75798405
在宏定义文件中做宏:
`define module_urandom_define \
string path_str; \
initial path_str = $psprintf(path_str, "%m"); \
\
function integer urandom; \
integer seed, i; \
begin \
seed = $urandom(); \
for(i=path_str.len; i>=0; i=i-1)begin \
seed = seed ^ path_str.getc(i); \
seed = $urandom(seed); \
end \
urandom = $abs(seed); \
end \
endfunction
`module_urandom_define
initial begin
int rand_test;
rand_test = urandom();
$display("%m test1, rand_test = %0d", rand_test);
rand_test = urandom();
$display("%m test2, rand_test = %0d", rand_test);
end
testbench.u_rand_test0.unnamed$$_0 test1, rand_test = 1970541737
testbench.u_rand_test0.unnamed$$_0 test2, rand_test = 128592474
testbench.u_rand_test1.unnamed$$_0 test1, rand_test = 849448805
testbench.u_rand_test1.unnamed$$_0 test2, rand_test = 1978420876
tc name = sanity
tc seed = 17411917
testbench.u_rand_test0.unnamed$$_0 test1, rand_test = 887806234
testbench.u_rand_test0.unnamed$$_0 test2, rand_test = 216253277
testbench.u_rand_test1.unnamed$$_0 test1, rand_test = 1150158848
testbench.u_rand_test1.unnamed$$_0 test2, rand_test = 1381425996
tc name = sanity
tc seed = 50449658
testbench.u_rand_test0.unnamed$$_0 test1, rand_test = 439486355
testbench.u_rand_test0.unnamed$$_0 test2, rand_test = 1519906787
testbench.u_rand_test1.unnamed$$_0 test1, rand_test = 219267827
testbench.u_rand_test1.unnamed$$_0 test2, rand_test = 133804852
tc name = sanity
tc seed = 64935128
function integer urandom_range(); \
input integer min, max; \
integer seed, i; \
begin \
seed = $urandom(); \
for(i=path_str.len; i>=0; i=i-1)begin \
seed = seed ^ path_str.getc(i); \
seed = $urandom(seed); \
end \
urandom_range = min + $abs(seed % (max - min)); \
end \
endfunction
initial begin
int rand_test;
rand_test = urandom_range(0,100);
$display("%m test1, rand_test = %0d", rand_test);
rand_test = urandom_range(100,1000);
$display("%m test2, rand_test = %0d", rand_test);
end
testbench.u_rand_test0.unnamed$$_0 test1, rand_test = 75
testbench.u_rand_test0.unnamed$$_0 test2, rand_test = 892
testbench.u_rand_test1.unnamed$$_0 test1, rand_test = 71
testbench.u_rand_test1.unnamed$$_0 test2, rand_test = 461
tc name = sanity
tc seed = 16870716
testbench.u_rand_test0.unnamed$$_0 test1, rand_test = 63
testbench.u_rand_test0.unnamed$$_0 test2, rand_test = 944
testbench.u_rand_test1.unnamed$$_0 test1, rand_test = 54
testbench.u_rand_test1.unnamed$$_0 test2, rand_test = 172
tc name = sanity
tc seed = 47491380
系列文章入口——
【芯片验证】sva_assertion: 15道助力飞升的断言练习 |
【芯片验证】可能是RTL定向验证的巅峰之作 |
【芯片验证】RTL仿真中X态行为的传播 —— 从xprop说起 |
【芯片验证】年轻人的第一个systemVerilog验证环境全工程与解析 |
【芯片设计】verilog中有符号数和无符号数的本质探究 |
【芯片设计】论RTL中always语法的消失术 |
【芯片设计】代码即注释,注释即代码 |
【芯片设计】700行代码的risc处理器你确实不能要求太多了 |
入职芯片开发部门后,每天摸鱼之外的时间我们要做些什么呢 |
如何计算系统的outstanding 和 burst length? |
芯片搬砖日常·逼死强迫症的关键词不对齐事件 |
熟人社会里,一群没有社会价值的局外人 |