当前位置:   article > 正文

SystemVerilog面试题:使用SystemVerilog中的constraints实现randc行为

systemverilog ranc 两个变量

在SystemVerilog中,用randc关键字声明的变量是循环随机(random-cyclic)变量,在其声明范围内循环随机,直到所有的值都随机过。

例如: 声明一个2bit randc变量;

randc bit [1:0] y;

每次随机此变量时都会随机可能的范围(这种情况下为0、1、2、3),在随机到所有值之前不会重复任何值。

在SystemVerilog面试中常常被问的一个问题是如何在不使用randc变量的情况下实现这种行为?

这个问题很好地考察了应聘者对这种基础语言的掌握程度。下面是一种实现方案,原理很简单:每次生成一个值时,它都会保存在一个queue中,下一次随机为变量选择一个与现有列表中所有的值不匹配的唯一值。一旦所有值都已经循环过,那么就会删除该列表。

  1. module test;
  2. parameter N =10;
  3. rand bit[N-1:0] randc_var;
  4. bit[N-1:0] gen_done[$];
  5. function automatic bit[N-1:0] get_randc();
  6. bit succ =0;
  7. while(!succ) begin
  8.       succ =  std::randomize(randc_var) with  { unique {randc_var,gen_done};};
  9. end
  10. //If success push to queue
  11. gen_done.push_back(randc_var);
  12. if(gen_done.size() == 2**N) begin
  13. gen_done.delete();
  14. end
  15. return randc_var;
  16. endfunction
  17. initial begin
  18. for (int i=0; i <1000; i++) begin
  19. $display("randc[%0d] = %0d", i, get_randc());
  20. end
  21. end
  22. endmodule

上述task使用automatic的原因是使得succ为动态变量,每次都是新建一个空间并具有初始值0.

或者可以使用类中的rand变量来实现同样的约束。随机值push到队列的过程可以放到post_randomize()函数中。当然,这背后的原理其实是一样的。

  1. class randc_test;
  2. parameter N =10;
  3. Rand bit[N-1:0] randc_var;
  4. bit[N-1:0] gen_done[$]; //queue of items done
  5. constraint randc_var_c { unique {randc_var,gen_done};};
  6. function void post_randomize();
  7. gen_done.push_back(randc_var);
  8. if(gen_done.size() == 2**N) begin
  9. gen_done.delete();
  10. end
  11. endfunction
  12. endclass
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/938584
推荐阅读
相关标签
  

闽ICP备14008679号