前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SystemVerilog面试题:使用SystemVerilog中的constraints实现randc行为

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

作者头像
AsicWonder
发布2021-07-16 16:03:00
1.9K0
发布2021-07-16 16:03:00
举报

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

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

代码语言:javascript
复制
randc bit [1:0] y;

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

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

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

代码语言:javascript
复制
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()函数中。当然,这背后的原理其实是一样的。

代码语言:javascript
复制
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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数字芯片实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档