赞
踩
在SystemVerilog中,用randc关键字声明的变量是循环随机(random-cyclic)变量,在其声明范围内循环随机,直到所有的值都随机过。
例如: 声明一个2bit randc变量;
randc bit [1:0] y;
每次随机此变量时都会随机可能的范围(这种情况下为0、1、2、3),在随机到所有值之前不会重复任何值。
在SystemVerilog面试中常常被问的一个问题是如何在不使用randc变量的情况下实现这种行为?
这个问题很好地考察了应聘者对这种基础语言的掌握程度。下面是一种实现方案,原理很简单:每次生成一个值时,它都会保存在一个queue中,下一次随机为变量选择一个与现有列表中所有的值不匹配的唯一值。一旦所有值都已经循环过,那么就会删除该列表。
module test; parameter N =10; rand bit[N-1:0] randc_var; bit[N-1:0] gen_done[$]; function automatic bit[N-1:0] get_randc(); bit succ =0; while(!succ) begin succ = std::randomize(randc_var) with { unique {randc_var,gen_done};}; end //If success push to queue gen_done.push_back(randc_var); if(gen_done.size() == 2**N) begin gen_done.delete(); end return randc_var; endfunction initial begin for (int i=0; i <1000; i++) begin $display("randc[%0d] = %0d", i, get_randc()); end end endmodule
上述task使用automatic的原因是使得succ为动态变量,每次都是新建一个空间并具有初始值0.
或者可以使用类中的rand变量来实现同样的约束。随机值push到队列的过程可以放到post_randomize()函数中。当然,这背后的原理其实是一样的。
- class randc_test;
- parameter N =10;
- Rand bit[N-1:0] randc_var;
- bit[N-1:0] gen_done[$]; //queue of items done
- constraint randc_var_c { unique {randc_var,gen_done};};
-
- function void post_randomize();
- gen_done.push_back(randc_var);
- if(gen_done.size() == 2**N) begin
- gen_done.delete();
- end
- endfunction
- endclass
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。