在約束隨機標量 的同時,我們還可以對隨機化的數組進行約束
class dyn_size;
rand logic [31:0] d[]; //隨機化d[]數組;
constraint d_size (d.size() inside {[1:10]};) //調用d.size對數組長度範圍進行約束
endclass
動態數組分別可以對其長度和內容做隨機化處理。此外,還可以通過在約束中結合數組的其它方法sum(), product(), and(), or()和xor()。
class good_sum5;
rand uint len[];
constraint c_len{
foreach (len[i]) len[i] inside {[1:255]};
len.sum() < 1024;
len.size() inside {[1:8]};
}
endclass
本題目中,要求隨機出來的數組 元素滿足(1)個數在1-8 之間;每個數組的數值大小在1-255之間;每個數組的求和要小於1024。
class UniqueSlow;
rand bit [7:0] ua[64];
constraint c {
foreach (ua[i]) //對數組中每一個元素操作
foreach (ua[j])
if(i != j) //除了元素自己
ua[i] != ua[j]; //和其它元素比較
}
endclass
使用randc變量輔助生成唯一元素。
class randc8;
randc bit [7:0] val; //隨機變量的值的範圍爲0~255,每一次randmize的256次值都不相同
endclass
class LittleUniqueArray;
bit [7:0] ua [64]; //定義一個含有64個元素的數組
function void pre_randomize();
randc8 rc8;
rc8 = new();
foreach (ua[i]) begin
assert(rc8.randomize()); //從256個元素中隨機化64次,每次隨機化的值都不同
ua[i] = rc8.val; //之後將隨機化後的值賦值給數組
end
endfunction
endclass
pre_randomize主要的功能是:
LittleUniqueArray lua = new();
lua.randmozie();
在外部聲明句柄lua, 通過句柄調用函數lua.randomize()函數時,先調用pre_randomize,其作用就是把 每個值後複製到每個數組中,因爲LittleUniqueArray中沒有元素被聲明爲rand。
另一方面這裏我們只new一次對象。由於new一次之後,相當於一次新的隨機過程,此時再 進行隨機化的結果可能元素不唯一。
案例1:
class packet;
rand bit[3:0] da[]; //rand修飾動態數組
constraint int da {
da.size() inside {[3:5]}; //約束數組的個數爲3-5
foreach(da[i]) da[i] <= da[i+1];
}
endclass
packat p;
initial begin
p = new();
p.randomize() with {da.size() inside {3,5};}; //約束da數組的個數或者3或者5
end
本題中考查動態數組的範圍,邊界範圍da[4] < da[5]中超出了範圍。
修改:
class packet;
rand bit[3:0] da[]; //rand修飾動態數組
constraint int da {
da.size() inside {[3:5]}; //約束數組的個數爲3-5
foreach(da[i])
if i <= da.size-2; //增加if判斷條件
da[i] <= da[i+1];
}
endclass
parameter MAX_SIZE = 10;
class RandStuff;
bit[1:0] value = 1;
endclass
class RandArray;
rand RandStuff array[];
constraint c {
array.size() inside
{[1:MAX]};
}
function new();
//分配最大容量
array = new[MAX_SIZE];
foreach (array[i])
array[i] = new();
endfunction
endclass
RandArray ra;
initial begin
//構造數組所有對象
ra = new();
//隨機化數組,但是可能會減小數組
assert(ra.randomize());
foreach (ra.array[i])
$display(ra.array[i].value);
end
ra.randomize() with {array.size == 2}的合法求解是多少呢?
array[0].value = 1,array[1].value = 1。
分析ra.randomize隨機化函數, 首先隨機化句柄的個數爲2;同時由於 rand RanfStuff array[];語句,因此還需要隨機化句柄中的動態數組元素。句柄爲randomize表明句柄指向的類中變量,但本例中類中的變量違背randomize修飾,因此該值一直未1。
同時, 首先要對變量數組分配最大 容量,每次new一次對象,讓對象中變量得到隨機化。句柄不同懸空。