使用最初生成的随机元素约束随机数组的连续元素是否有效。 例如:我想生成一组10个addr,size对来模仿典型的内存分配例程,并且有一个类如下:
class abc;
rand bit[5:0] size[8];
rand bit[5:0] addr[8];
constraint mem_unique{
foreach(size[i]) begin
solve size[i] before addr[i];
size[i] inside {[6'h2:6'h10]};
if(i>0)
addr[i] > addr[i-1]+size[i-1];
end
}
endclass:abc
答案 0 :(得分:5)
您的示例中的一些额外代码行将显示它是否有效。这就是我的工作:
module top;
class abc;
rand bit[5:0] size[8];
rand bit[6:0] addr[8];
constraint mem_unique
{
foreach(size[i]) {
size[i] inside {[6'h2:6'h10]};
if(i>0) // concatenate 1'b0 to catch overflow
{1'b0,addr[i]} > addr[i-1]+size[i-1];
}
}
endclass : abc
abc c=new();
initial repeat(5) begin
$display();
assert(c.randomize());
foreach(c.addr[i]) $displayh(c.addr[i],, c.size[i]);
end
endmodule top
foreach约束被展开,就像合成工具一样。所以你留下的东西看起来像:
size[0] inside {[6'h2:6'h10]};
size[1] inside {[6'h2:6'h10]};
{1'b0,addr[1]} > addr[0]+size[0];
size[2] inside {[6'h2:6'h10]};
{1'b0,addr[2]} > addr[1]+size[1];
...
size[7] inside {[6'h2:6'h10]};
{1'b0,addr[7]} > addr[6]+size[6];
答案 1 :(得分:1)
我不确定你想做什么是合法的,所以我希望其他人会直接回答你的问题。但是,我可以提供一种解决方案,以稍微不同的方式生成您想要的内容。您可以使用post_randomize
功能:
class abc;
rand bit[5:0] size[10];
rand bit[5:0] offset[10];
bit[5:0] addr[10];
constraint mem_unique{
foreach(size[i]) size[i] inside {[6'h10:6'h20]};
(size.sum + offset.sum) <= 6'h3F;
}
function void post_randomize();
foreach(addr[i]) begin
if(i == 0) addr[i] = offset[i];
else addr[i] = addr[i-1] + size[i-1] + offset[i];
end
endfunction
endclass
你会注意到这个约束会失败,因为你说大小的最小值是6'h10('d16)而你想要10个地址。因此,即使偏移量都为0,最大地址也将为'd160('hA0)。 <{1}}中没有足够的位来保存该值。