System Verilog 将等于 2 的地址随机化为断电

System Verilog randomize address equal to 2 to the power off

我想在 System Verilog 中约束一个地址,使该地址等于值的 2 次方。例如生成的地址(16 位)应该是

地址 = 0, 2, 4, 8, 16, 32 .... 32,768

以下适合我。但是,我正在寻找任何其他简短而优雅的方法。

class two_power_addr;
  rand bit [15:0] addr;
  bit [15:0] temp;

  constraint c_addr {
    addr == temp;
  }

endclass

module tb();
  two_power_addr c;

  initial begin
    c=new();
    c.temp=0;
    c.randomize();
    $display("%0d \n", c.addr);
    c.temp=16'h2;
    for(int i=0; i<10; i++) begin      
      c.randomize();
      c.temp=c.temp<<1;
      $display("%0d \n", c.addr);
    end
  end
endmodule

Her 是一个没有约束的变体,classes 非常适合您的情况。

 bit[3:0] rnd;
 logic address[15:0];

 rnd =  $urandom;
 address = 16'b1 << rnd;

我猜你可以为 rnd 想出一个 class 随机化,而不是 $urandom。

你可以写下你的约束来检查随机值是否是2的幂。

constraint 2_power {
  (addr != 0) -> (addr & (addr - 1)) == 0;
}
constraint c_addr { $onehot0(addr) == 1; }

这里是另一种替代方法。另外我更喜欢 Dave 的方法,因为它很短,2 的幂永远不会为 0,所以 $onehot0 可以用 $onehot 代替。但是由于问题包含 addr = 0,那么可以使用$onehot0

class gen#(parameter width = 8);

    rand bit [width-1:0] addr;
    rand int num;
  
    constraint num_c { num inside {[0:width-1]};}
    constraint solve_order { solve num before addr;}
    constraint pow_2 {  addr == 2**num;}

endclass: gen