系统verilog中数组的约束

时间:2014-02-24 01:56:59

标签: 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

2 个答案:

答案 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}}中没有足够的位来保存该值。