我想在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
答案 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