ven*_*art 4 constraints system-verilog
使用最初生成的随机元素来约束随机数组的连续元素是否有效.例如:我想生成一组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
Run Code Online (Sandbox Code Playgroud)
您的示例中的一些额外代码行将显示它是否有效.这是我的工作:
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
Run Code Online (Sandbox Code Playgroud)
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];
Run Code Online (Sandbox Code Playgroud)
我不确定你想做的事情是否合法,所以我希望其他人能直接回答你的问题。但是,我可以提供一个解决方案,以稍微不同的方式生成您想要的内容。您可以使用该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
Run Code Online (Sandbox Code Playgroud)
您会注意到,此约束将失败,因为您已经说过大小的最小值是 6'h10 ('d16) 并且您需要 10 个地址。因此,即使偏移量全为 0,最大地址也将是 'd160 ('hA0)。您没有足够的位addr来保存该值。