SystemVerilog 中一组变量的循环随机化

use*_*407 2 verilog constraints system-verilog

我试图在系统 verilog 中随机化 3 个不同的变量,但以循环方式。我的意思是,我有以下 3 个变量

rand int a;
rand int b;
rand int c;

constraint c_a{
  a inside {1,2};     
}
constraint c_b{
  b inside {1,2,3,4,5,6};
}
constraint c_c{
  c inside {1,2,3}
}
Run Code Online (Sandbox Code Playgroud)

有了上述约束,所有 3 个变量 (2x6x3) 总共有 36 种组合。

但如果我们运行 36 次循环,如下所示:

repeat(36) begin
  this.randomize(a,b,c);
  $display("%d   %d   %d", a,b,c);
end
Run Code Online (Sandbox Code Playgroud)

我们不会击中所有可能的组合,因为某些组合可能会重复。因此,我希望找到一种方法,通过精确运行循环 36 次来实现所有这些组合。

我编写了一种强力方法来实现此目的,方法是声明另一个 rand 变量来表示每个组合并在其上使用 randc,如下所示:

int a;
int b;
int c;
randc int k;

constraint c_k{
  k inside {[1:36]};
}

repeat(36) begin
  this.randomize(k);
  // randomizing variable 'a' to one of the 2 values.
  if(k<9)
    a = 1;
  else
    a = 2;
  // randomizing variable 'b' to one of the 6 values.
  case(k)
    1,2,3,19,20,21 : b = 1;
    4,5,6,22,23,24 : b = 2;
    7,8,9,25,26,27 : b = 3;
    //
    //   finishing the sequence
    // 
  endcase  

  case(k)
     // similar case statement for the final variable
  endcase

  $display("%d, %d, %d", a,b,c);
end
Run Code Online (Sandbox Code Playgroud)

上面的方法工作得很好,但对我来说,这似乎是一种忙碌的方法(也不能应用于大型组合),因此想知道是否有更优雅的方法来实现这一点。

谢谢你的帮助。

dav*_*_59 5

您可以做的是将变量连接到打包结构中,并将其设为randc变量。

module top;
class A;
    typedef struct packed {
    bit [1:0]   a;
    bit [2:0]   b;
    bit [1:0]   c;
    } abc_t;
randc abc_t k;
constraint c_a{
  k.a inside {1,2};     
}
constraint c_b{
  k.b inside {1,2,3,4,5,6};
}
constraint c_c{
  k.c inside {1,2,3};
}
endclass
   A h = new;
   initial 
     repeat(40) begin
       h.randomize();
       $display("%0p",h.k);
     end
endmodule
Run Code Online (Sandbox Code Playgroud)

请注意,变量允许的总位数randc可能受到模拟器的限制

  • 想想处理 _6 位_ 循环随机性需要什么。你基本上必须列出所有可能的解决方案并随机选择其中一个。约束求解器必须做类似的事情,并且问题随着位数的增加呈指数增长。解决这个问题的任何其他方法都需要知道可能的解决方案的确切数量,随着约束变得更加复杂,这变得非常困难。 (2认同)