簡體   English   中英

SystemVerilog約束:約束讀地址之前已經寫入

[英]SystemVerilog constraint: constrain the read address has been written before

我想寫一個約束來確保r_addr只在相同的地址之前被用作w_addr時才被允許,但是下面的約束不起作用。 你有什么建議嗎?

class try;
    rand int w_addr;
    rand int r_addr;
    int ua[$];
    int aa[int];
    constraint unique_addr_c{
        aa.size() == 0 || aa.exists(r_addr);
    }
endclass


module test;

    try a;

    initial begin
        a=new;
        repeat(20) begin
            if(a.randomize);
            $display("add=%0d", a.w_addr);
            $display("add=%0d", a.r_addr);
            a.ua.push_back(a.w_addr);
            a.aa[a.w_addr] = 1;
        end
    end

endmodule

您要使用inside運算符。

class try;
    rand bit [31:0] w_addr;
    rand int [31:0] r_addr;
    bit [31:0] ua[$];
    constraint unique_addr_c{
       ua.size() >0 -> r_addr inside {ua};
    }
    function void post_randomize();
       ua.push_back(w_addr);
       endfunction
endclass


module test;

    try a;

    initial begin
        a=new;
        repeat(50) begin
            if (!a.randomize) $error("randomization failed");
            $display("wadd=%0d", a.w_addr);
            $display("radd=%0d", a.r_addr);
        end
    end

endmodule

注意:您應該對地址使用無符號類型。 您的隨機檢查會產生錯誤。

戴夫的答案是一個很好的答案。

這是另一個使用隊列而不是關聯數組的隊列。

class try;
rand int w_addr;
rand int r_addr;
int q[$];

function void post_randomize();
    int sz;
    int idx;
    q.push_back(w_addr);
    sz = q.size();
    idx = $urandom_range(0, sz-1);
    r_addr = q[idx];
endfunction
endclass

module test;

    try a;

    initial begin
       a=new;
       repeat(20) begin
           a.randomize();
          $display("sz=%0d w_addr=%x r_add=%x", a.q.size(), a.w_addr, a.r_addr);
       end
    end
endmodule

以下代碼在 mentor 中有效,但在 synopsys 中無效

class bus;
rand bit [31:0] address;
rand bit rd_wr_en;
rand bit [1:0] interleaving;  
endclass

class my_bus;
rand bus b1[20];

function new();
 foreach(b1[n])
  b1[n] = new();
endfunction

constraint c {
  foreach (b1[n])
   if (n>0)
    if(b1[n-b1[n].interleaving].rd_wr_en ==1)
    { 
     b1[n].address == b1[n-b1[n].interleaving].address;
     b1[n].rd_wr_en == 0;
    }

   }

endclass
module tb;
my_bus b2;
 initial begin
 b2 = new();
 repeat (10) begin
   b2.randomize; 
   foreach(b2.b1[n])
   $display ( "%p", b2.b1[n]);       
   end
 end
endmodule  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM