SystemVerilog约束随机生成彩票二等奖号码约束冲突问题求助
问题根因分析
- 随机变量修饰错误:
six_jackpot_nums是在pre_randomize中已经生成固定的头奖号码,不需要参与随机化,但你给它加了randc修饰,会导致随机化过程覆盖掉预先生成的头奖值,约束的参考基准直接错误。同时jackpot_result用randc修饰不符合需求:randc对数组的作用是每个元素独立循环取值,不会保证数组内元素不重复,不符合彩票号码无重复的规则,应该改为rand修饰,额外加唯一性约束。 - 约束中调用自定义函数的逻辑错误:SystemVerilog约束求解过程中,若自定义函数的输入包含随机变量,函数会在约束求解前就完成求值,不会随随机变量的取值动态计算匹配结果,导致你的匹配数约束实际是固定值和随机值的硬冲突,无法满足。
- 缺少彩票号码基础规则约束:没有约束
jackpot_result的元素互不重复,即使约束满足也不符合实际彩票规则。
修正方案
替换原设计代码为如下版本:
`define NUM_JACKPOT 6 class Lottery; rand int six_jackpot_nums[`NUM_JACKPOT]; constraint rand_jackpot { foreach (six_jackpot_nums[i]) six_jackpot_nums[i] inside {[1:49]}; unique {six_jackpot_nums}; // 头奖号码不重复 } endclass class Pick; // 头奖号码不需要参与随机,去掉randc修饰 int six_jackpot_nums[`NUM_JACKPOT]; // 改为rand修饰,后续加唯一性约束 rand int jackpot_result [`NUM_JACKPOT]; int award_2nd_hi = `NUM_JACKPOT - 1; function pre_randomize(); Lottery l = new(); l.randomize(); $display("Jackpot bingo:"); for (int i=0; i<`NUM_JACKPOT; i++) begin six_jackpot_nums[i] = l.six_jackpot_nums[i]; $write("%0d ", l.six_jackpot_nums[i]); end $display(); endfunction constraint pick_jackpot{ // 二等奖号码范围合规 foreach (jackpot_result[i]) jackpot_result[i] inside {[1:49]}; // 二等奖号码不重复 unique {jackpot_result}; // 用求解器原生支持的sum方法计算匹配数,等于5满足二等奖要求 jackpot_result.sum with (int'(six_jackpot_nums.find(x) with (x == item).size() != 0)) == award_2nd_hi; } endclass
测试平台代码无需修改,重新运行即可正常生成符合要求的二等奖号码,无约束冲突。
内容的提问来源于stack exchange,提问作者Toby Liao
相关产品推荐
相关产品推荐

