-2

我正在尝试随机化一个不应落在先前分配的段中的地址,假设如果我分配了地址 0, 10 ,40 并且块长度为 5,当我随机化地址时,它不应该落在(0-4),(10-14),(40-44)。我如何在系统verilog中限制这一点。我尝试了一种方法,但它不起作用。
这是我的代码:

constraint con {

foreach(keys[i]){

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

}

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

4

2 回答 2

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
于 2013-10-29T22:17:59.517 回答
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.xml 中使用内联约束。
见下面的代码

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),否则您的模拟将退出并出现约束不一致错误。

于 2013-10-29T10:21:47.250 回答