randcase 权重行为意外
randcase weight behaviour unexpected
class test1;
function test_randcase();
for (int idx=0; idx < 10; idx++) begin
randcase
50: begin
$display("displaying from first cases");
end
50: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
program main;
initial begin
test1 t1=new();
t1.test_randcase();
end
endprogram
由于这里每个案例的权重相同 (50/100=0.5),所以预计我总共会看到每个展示 5 次。但是,我看到“第一种情况”打印了 6 次,“第二种情况”打印了 4 次。如果这是 randcase 的行为,那么我将如何实现我的等重意图?我使用 vcs 编译器执行此操作。
输出:
displaying from second case
displaying from first cases
displaying from first cases
displaying from first cases
displaying from first cases
displaying from second case
displaying from first cases
displaying from second case
displaying from second case
displaying from first cases
换个角度看这个问题,假设你必须选择一个完全随机的 10 位数字,其中每一位有 50% 的几率是 0 或 1。有 1024 个可能的数字,有 1/1024 的几率是有 10 个 1 和 1/1024 的机会有 10 个 0。选择恰好有 5 个 1 和 5 个 0 的数字的几率约为 25%。如果您 运行 更多次迭代,您的 randcase
分布将接近 0.50,但获得 精确 0.5 分布的几率会降低。
如果您的要求是获得 精确 分布,您需要预先知道您计划进行多少次迭代。您可以采用多种方法,我可以向您展示其中一种
class test1;
enum {FIRST, SECOND} itor[10];
function new;
itor[0:4] = '{5{FIRST}};
itor[5:9] = '{5{SECOND}};
endfunction
function void test_randcase();
itor.shuffle();
foreach(itor[i]) begin
case(itor[i])
FIRST: begin
$display("displaying from first cases");
end
SECOND: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
module main;
test1 t1=new();
initial repeat(10)begin
$display("---");
t1.test_randcase();
end
endmodule
我在 DVCon 2020 的论文中展示了其他方法,SystemVerilog Constraints: Appreciating What You Forgot in School to Get Better Results
class test1;
function test_randcase();
for (int idx=0; idx < 10; idx++) begin
randcase
50: begin
$display("displaying from first cases");
end
50: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
program main;
initial begin
test1 t1=new();
t1.test_randcase();
end
endprogram
由于这里每个案例的权重相同 (50/100=0.5),所以预计我总共会看到每个展示 5 次。但是,我看到“第一种情况”打印了 6 次,“第二种情况”打印了 4 次。如果这是 randcase 的行为,那么我将如何实现我的等重意图?我使用 vcs 编译器执行此操作。
输出:
displaying from second case
displaying from first cases
displaying from first cases
displaying from first cases
displaying from first cases
displaying from second case
displaying from first cases
displaying from second case
displaying from second case
displaying from first cases
换个角度看这个问题,假设你必须选择一个完全随机的 10 位数字,其中每一位有 50% 的几率是 0 或 1。有 1024 个可能的数字,有 1/1024 的几率是有 10 个 1 和 1/1024 的机会有 10 个 0。选择恰好有 5 个 1 和 5 个 0 的数字的几率约为 25%。如果您 运行 更多次迭代,您的 randcase
分布将接近 0.50,但获得 精确 0.5 分布的几率会降低。
如果您的要求是获得 精确 分布,您需要预先知道您计划进行多少次迭代。您可以采用多种方法,我可以向您展示其中一种
class test1;
enum {FIRST, SECOND} itor[10];
function new;
itor[0:4] = '{5{FIRST}};
itor[5:9] = '{5{SECOND}};
endfunction
function void test_randcase();
itor.shuffle();
foreach(itor[i]) begin
case(itor[i])
FIRST: begin
$display("displaying from first cases");
end
SECOND: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
module main;
test1 t1=new();
initial repeat(10)begin
$display("---");
t1.test_randcase();
end
endmodule
我在 DVCon 2020 的论文中展示了其他方法,SystemVerilog Constraints: Appreciating What You Forgot in School to Get Better Results