2013-10-29 44 views
-2

我想隨機化一個地址,應該是不應該落在以前分配的段 假設如果我分配了地址0,10,40,並且塊長度爲5, 當我隨機地址,它不應該落在(0-4),(10-14),(40-44)的範圍內。我如何在系統verilog中約束這個。 我試過一種方法,但它不工作。
這是我的代碼:隨機在SystemVerilog

constraint con { 

foreach(keys[i]){ 

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

} 

鍵是地址的數組,已經獲分配,生成地址不應落在上述範圍內。 謝謝 溼婆

回答

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)否則你的模擬將與約束不一致的錯誤而退出了。

+0

class t_constraints; randc bit [5:0] addr; //使用randc只是爲了使所有的值出現。 int keys [$]; //隱含addr {0:1和4:5不應該分配} int BLOCK_SIZE = 4; 約束CON {的foreach(鍵[I]) {(ADDR內部{[鍵[I]:鍵[I] + BLOCK_SIZE]});} !} endclass:t_constraints 模塊tb_con; t_constraints t_con; 初始開始 t_con = new(); repeat(8)begin t_con.randomize(); $ display(「addr =%h」,t_con.addr); \t t_con.keys.push_back(t_con.addr);結束 $完成; 結束 endmodule:tb_con – bachu

+1

@bachu:將該代碼添加到您的問題。 – toolic

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