我正在尝试生成随机单个位,只要您想要正常的随机化,这很简单:
wire R;
assign R = $random % 2;
我正在寻找的是一种加权概率,如:
wire R;
assign R = 60%(0) || 40%(1);
请原谅我,如果它不符合标准的Verilog代码,那只是想知道我想要什么。 谁能帮我吗? 谢谢
答案 0 :(得分:9)
SystemVerilog解决方案在randomize
内的分发方法称为dist
。权重由value_or_range := weight
或value_or_range :/ distributed_weight
指定。这篇来自IEEE Std 1800-2012§18.5.4第476页的论文给出了一个明确的例子:
当权重应用于范围时,它们可以应用于范围中的每个值,或者它们可以作为整体应用于范围。例如:
的x dist { [100:102] := 1, 200 := 2, 300 := 5}
强>
装置x等于100,101,102,200或300,加权比为1-1-1-2-5,和 的x dist { [100:102] :/ 1, 200 := 2, 300 := 5}
强>
表示x等于100,101,102,200或300中的一个,其加权比率为 的1 / 3-1 / 3-1 / 3-2-5。
dist
用于随机化,因此它需要是randomize() with
(或类constraint
)的母马。 randomize
会返回一个成功位,因此应该在assert
,void'()
或作业的RHS中调用。
在我们的设置中,我们可以设置0到6的重量和1到4的重量,总重量为10,分布为60/40。例如:
reg R;
initial begin
assert( randomize(R) with { R dist { 0 := 6, 1 := 4 }; } );
end
有关dist
的更多信息,请参阅IEEE Std 1800-2012§18.5.4“发布”。
答案 1 :(得分:2)
然后根据值返回1或0创建一个随机整数;注意,您可能希望为随机数播种,重复性使用相同的种子。这样,当测试失败时,可以调试它。
$urandom
与$random
的工作方式略有不同,它不会更新种子值,因此只应在第一次在线程中调用时播种(始终阻止)。它也是线程安全的,每个块总是独立工作。
initial begin
$urandom(seed);
$urandom;
$urandom;
end
integer temp;
reg r ;
always @ ... begin
temp = $urandom; //Range: +2_147_483_647 -2_147_483_648
// weighting; 0 would be 50:50
// real weighting is (0.1 + 0.5), 0.5 inherent from positive number.
r = (temp > (2_147_483_647*0.1);
end
注意:随机函数不可合成,只能用于测试平台。如果您想要一个随机数进行综合,请查看this Question
答案 2 :(得分:1)
对于Verilog,你总是可以这样:
integer R;
R = ($dist_uniform(0,100) < 60) : $dist_uniform(0,5) : $dist_uniform(6,10)
这与SystemVerilog中的相同:
std::randomize(R) with {R dist {[0:5] :/60, [6:10] :/ 40} ;};
您也可以执行此程序代码: randcase 60:R = 1; 40:R = 0; ENDCASE
答案 3 :(得分:0)
类似的东西:
wire R;
if ($random[7:0]>(40*255/100))
assign R = 1'b0;
else
assign R = 1'b1;
我假设$random
使用的算法产生的数字在您从中获取的任何位数都是随机的。
答案 4 :(得分:0)
以下代码将根据您的要求生成随机变量:
program top;
class Packet;
rand reg R;
constraint percentage {R dist {1:=60,0:=40};};
function void display;
$display("Random Reg : %0d",this.R);
endfunction
endclass
Packet P;
initial
begin
P = new;
repeat(10)
begin
P.randomize();
P.display;
end
end
endprogram
答案 5 :(得分:0)
verilog似乎没那么难。
reg [7:0] R;
reg rand_bit;
R = $random();
if (R < 76)
rand_bit = 1'b0;
else
rand_bit = 1'b1;
这里我假设$ random非常统一。我认为它应该有效:)