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

时间:2017-08-27 20:02:01

标签: constraints system verilog

我想在System Verilog中约束一个地址,使地址等于值的两倍。例如,生成的地址(16位)应为

addr = 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

4 个答案:

答案 0 :(得分:2)

您可以按照以下方式编写约束,以检查随机值是否为2的幂。

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

答案 1 :(得分:1)

constraint c_addr { $onehot0(addr) == 1; }

答案 2 :(得分:0)

她是一个没有约束的变体和类,在你的情况下效果非常好。

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

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

如果您愿意而不是$ urandom,我猜你可以为rnd提出一个班级随机化。

答案 3 :(得分:0)

这是另一种执行相同操作的替代方法。另外我更喜欢 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