SystemVerilog中的随机化

时间:2013-10-29 07:03:48

标签: system-verilog

我正在尝试随机化一个地址,该地址应该不属于先前分配的段 假设我被分配了地址0,10,40,并且块长度为5, 当我随机化地址时,它不应该落在(0-4),(10-14),(40-44)的范围内。 我怎么能在系统verilog中约束它。 我尝试了一种方法,但它没有用。
这是我的代码:

constraint con {

foreach(keys[i]){

    !(address inside {[keys[i]:keys[i]+BLOCK_SIZE]});    
}

}

键是已经分配的地址数组,生成的地址不应该落在上述范围内。 谢谢 婆

2 个答案:

答案 0 :(得分:0)

你的语法对我来说是正确的。你看到了什么问题?

我尝试了以上内容,它对我有用。见下面的代码。

class t_constraints;  

  randc bit [2:0] addr; //using randc just to make all values appear.  

  int keys [2] = {0,4};  // Implies addr {0:1 and 4:5 should not assigned}  
  int BLOCK_SIZE = 1;  

  constraint con { foreach(keys[i])  
    {!(addr inside {[keys[i]:keys[i]+BLOCK_SIZE]});}  
  }  

endclass: t_constraints  

module tb_con;  
  t_constraints t_con;  

 initial begin  
   t_con = new();  
   repeat(8) begin  
     t_con.randomize();  
     $display("addr = %h",t_con.addr);  
   end  
   $finish;  
 end  
endmodule: tb_con

下面是日志,看起来很完美。

addr = 3  
addr = 6  
addr = 7  
addr = 2  
addr = 2  
addr = 3  
addr = 7  
addr = 6 
$finish called from file "t_constraints.sv", line 26.   

抱歉没有正确格式化。格式化后我无法回答。它给出了错误,说明代码格式不正确。

编辑:
如果要考虑每次为下一次随机化生成的addr,请在tb中使用内联约束 见下面的代码

module tb_con;
 t_constraints t_con;
 int t_keys [$];
 int T_BLOCK_SIZE;

 initial begin
   t_con = new();
   repeat(3) begin // constraint solver cannot solve since after 3rd iteration there won't be any legal values.
     t_keys = t_con.keys;
     T_BLOCK_SIZE = t_con.BLOCK_SIZE;
     t_con.randomize() with{
       foreach(t_keys[i])
         { !(addr inside {[t_keys[i]:t_keys[i]+T_BLOCK_SIZE]});} 
     };
     $display("addr = %h",t_con.addr);
     t_con.keys.push_back(t_con.addr);
   end
   $finish;
 end
endmodule: tb_con

注意:您必须注意不要迭代超过可能的值(此处为3),否则您的模拟将退出并出现约束不一致错误。

答案 1 :(得分:0)

它对我有用。请显示完整的测试用例以及您获得的错误结果。

class a;

   rand bit [5:0] address;
   bit [5:0] keys[] = {0,10,40};
   int       BLOCK_SIZE = 5;
   constraint con {

           foreach(keys[i]) {
      !(address inside {[keys[i]:keys[i]+BLOCK_SIZE-1]}) ; }    
           }

endclass

module top;
   a a_h;
   initial begin
      a_h = new;
      repeat (200) begin
     if (!a_h.randomize())
       $error("randomize failed"); 
     $display(a_h.address);
     assert (!(a_h.address inside {[0:4],[10:14],[40:44]}));
      end
   end
endmodule // top