[英]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.