系统verilog中数组的约束

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)

dav*_*_59 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
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)


ngu*_*rie 2

我不确定你想做的事情是否合法,所以我希望其他人能直接回答你的问题。但是,我可以提供一个解决方案,以稍微不同的方式生成您想要的内容。您可以使用该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来保存该值。