Systemverilog(綠皮書)第六章——隨機化(四)數組的約束

在約束隨機標量 的同時,我們還可以對隨機化的數組進行約束

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一次對象,讓對象中變量得到隨機化。句柄不同懸空

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章