以指数格式随机化实数

问题描述 投票:0回答:1

我有一个缓冲模块,我试图在其中随机化输入到输出延迟。我已将最小和最大延迟声明为实际参数。当我实例化模块时,我想以指数格式传递参数。例如,MIN_DELAY = 1e-8,MAX_DELAY = 5e-6。由于

$urandom_range
仅接受整数,因此我尝试在以下代码片段中将实际延迟转换为整数:

timeunit 1s;
timeprecision 1ps;

parameter real MIN_DELAY = 0.0;
parameter real MAX_DELAY = 5e-6;

real delay = 0;
real delay_unit = 1;
real min_delay = MIN_DELAY;
real max_delay = MAX_DELAY;

function real mod (real a, real b);
    mod = a - b*$floor(a/b);
endfunction

initial begin
    while (mod(min_delay, 10) > 1e-12 && mod(min_delay, 10) < 10 || 
           mod(max_delay, 10) > 1e-12 && mod(max_delay, 10) < 10) begin
        $display("min_delay=%g, max_delay=%g, mod_min=%g, mod_max=%g", min_delay, max_delay, mod(min_delay, 10), mod(max_delay, 10));
        delay_unit = delay_unit/10;
        min_delay = min_delay*10;
        max_delay = max_delay*10;
    end
    delay = delay_unit*real'($urandom_range(min_delay, max_delay));
end

问题是这并不总是有效。例如,当我设置 MIN_DELAY = 1.2e-6 和 MAX_DELAY = 4.2e-6 时,我看到的是:

min_delay=1.2e-06, max_delay=4.2e-06, mod_min=1.2e-06, mod_max=4.2e-06
min_delay=1.2e-05, max_delay=4.2e-05, mod_min=1.2e-05, mod_max=4.2e-05
min_delay=0.00012, max_delay=0.00042, mod_min=0.00012, mod_max=0.00042
min_delay=0.0012, max_delay=0.0042, mod_min=0.0012, mod_max=0.0042
min_delay=0.012, max_delay=0.042, mod_min=0.012, mod_max=0.042
min_delay=0.12, max_delay=0.42, mod_min=0.12, mod_max=0.42
min_delay=1.2, max_delay=4.2, mod_min=1.2, mod_max=4.2
min_delay=12, max_delay=42, mod_min=2, mod_max=2
min_delay=120, max_delay=420, mod_min=0, mod_max=10
min_delay=1200, max_delay=4200, mod_min=0, mod_max=10
min_delay=12000, max_delay=42000, mod_min=0, mod_max=10
min_delay=120000, max_delay=420000, mod_min=0, mod_max=10
min_delay=1.2e+06, max_delay=4.2e+06, mod_min=0, mod_max=10
min_delay=1.2e+07, max_delay=4.2e+07, mod_min=0, mod_max=10
min_delay=1.2e+08, max_delay=4.2e+08, mod_min=0, mod_max=10
min_delay=1.2e+09, max_delay=4.2e+09, mod_min=0, mod_max=10
min_delay=1.2e+10, max_delay=4.2e+10, mod_min=0, mod_max=9.99999
min_delay=1.2e+11, max_delay=4.2e+11, mod_min=0, mod_max=9.99994
min_delay=1.2e+12, max_delay=4.2e+12, mod_min=0, mod_max=9.99951
min_delay=1.2e+13, max_delay=4.2e+13, mod_min=0, mod_max=9.99219
min_delay=1.2e+14, max_delay=4.2e+14, mod_min=0, mod_max=9.9375
min_delay=1.2e+15, max_delay=4.2e+15, mod_min=0, mod_max=9.5

我期望 while 循环在 min_delay=120 和 max_delay=420 时结束。有更好的方法来进行随机化吗?

verilog system-verilog
1个回答
0
投票

使用此格式显示

$display("min_delay=%30.30f, max_delay=%30.30f, mod_min=%30.30f, mod_max=%30.30f",
         min_delay, max_delay, mod(min_delay, 10.0), mod(max_delay, 10.0));

你会得到这个输出

# min_delay=0.000001199999999999999945697734, max_delay=0.000004199999999999999598183833, mod_min=0.000001199999999999999945697734, mod_max=0.000004199999999999999598183833
# min_delay=0.000012000000000000000304010289, max_delay=0.000041999999999999997675904223, mod_min=0.000012000000000000000304010289, mod_max=0.000041999999999999997675904223
# min_delay=0.000120000000000000003040102892, max_delay=0.000419999999999999963206515075, mod_min=0.000120000000000000003040102892, mod_max=0.000419999999999999963206515075
# min_delay=0.001200000000000000111716191853, max_delay=0.004199999999999999740485367994, mod_min=0.001200000000000000111716191853, mod_max=0.004199999999999999740485367994
# min_delay=0.012000000000000000249800180541, max_delay=0.041999999999999995670130203962, mod_min=0.012000000000000000249800180541, mod_max=0.041999999999999995670130203962
# min_delay=0.119999999999999995559107901499, max_delay=0.419999999999999928945726423990, mod_min=0.119999999999999995559107901499, mod_max=0.419999999999999928945726423990
# min_delay=1.199999999999999955591079014994, max_delay=4.199999999999999289457264239900, mod_min=1.199999999999999955591079014994, mod_max=4.199999999999999289457264239900
# min_delay=12.000000000000000000000000000000, max_delay=41.999999999999992894572642398998, mod_min=2.000000000000000000000000000000, mod_max=1.999999999999992894572642398998
# min_delay=120.000000000000000000000000000000, max_delay=419.999999999999943156581139191985, mod_min=0.000000000000000000000000000000, mod_max=9.999999999999943156581139191985
# min_delay=1200.000000000000000000000000000000, max_delay=4199.999999999999090505298227071762, mod_min=0.000000000000000000000000000000, mod_max=9.999999999999090505298227071762
# min_delay=12000.000000000000000000000000000000, max_delay=41999.999999999992724042385816574097, mod_min=0.000000000000000000000000000000, mod_max=9.999999999992724042385816574097
# min_delay=120000.000000000000000000000000000000, max_delay=419999.999999999941792339086532592773, mod_min=0.000000000000000000000000000000, mod_max=9.999999999941792339086532592773
# min_delay=1200000.000000000000000000000000000000, max_delay=4199999.999999999068677425384521484375, mod_min=0.000000000000000000000000000000, mod_max=9.999999999068677425384521484375
# min_delay=12000000.000000000000000000000000000000, max_delay=41999999.999999992549419403076171875000, mod_min=0.000000000000000000000000000000, mod_max=9.999999992549419403076171875000
# min_delay=120000000.000000000000000000000000000000, max_delay=419999999.999999940395355224609375000000, mod_min=0.000000000000000000000000000000, mod_max=9.999999940395355224609375000000
# min_delay=1200000000.000000000000000000000000000000, max_delay=4199999999.999999523162841796875000000000, mod_min=0.000000000000000000000000000000, mod_max=9.999999523162841796875000000000
# min_delay=12000000000.000000000000000000000000000000, max_delay=41999999999.999992370605468750000000000000, mod_min=0.000000000000000000000000000000, mod_max=9.999992370605468750000000000000
# min_delay=120000000000.000000000000000000000000000000, max_delay=419999999999.999938964843750000000000000000, mod_min=0.000000000000000000000000000000, mod_max=9.999938964843750000000000000000
# min_delay=1200000000000.000000000000000000000000000000, max_delay=4199999999999.999511718750000000000000000000, mod_min=0.000000000000000000000000000000, mod_max=9.999511718750000000000000000000
# min_delay=12000000000000.000000000000000000000000000000, max_delay=41999999999999.992187500000000000000000000000, mod_min=0.000000000000000000000000000000, mod_max=9.992187500000000000000000000000
# min_delay=120000000000000.000000000000000000000000000000, max_delay=419999999999999.937500000000000000000000000000, mod_min=0.000000000000000000000000000000, mod_max=9.937500000000000000000000000000
# min_delay=1200000000000000.000000000000000000000000000000, max_delay=4199999999999999.500000000000000000000000000000, mod_min=0.000000000000000000000000000000, mod_max=9.500000000000000000000000000000

这里有一个更好的方法来解决这个问题。

module top;
timeunit 1s;
timeprecision 1ps;

parameter real MIN_DELAY = 1.2e-6;
parameter real MAX_DELAY = 4.2e-6;

int min_delay = MIN_DELAY/1ps;
int max_delay = MAX_DELAY/1ps;
real delay;
   
  initial repeat (10) begin
  delay = $urandom_range(max_delay,min_delay) *1ps;
  $display("delay = %g",delay);
end
  
endmodule
© www.soinside.com 2019 - 2024. All rights reserved.