0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

簡(jiǎn)述SystemVerilog的隨機(jī)約束方法

jf_78858299 ? 來源:芯片學(xué)堂 ? 作者:JKZHAN ? 2023-01-21 17:03 ? 次閱讀

上一篇文章介紹了SystemVerilog的各種隨機(jī)化方法,本文將在其基礎(chǔ)上引入SystemVerilog的隨機(jī)約束方法(constraints)。通過使用隨機(jī)約束,我們可以將隨機(jī)限制在一定的空間內(nèi),有針對(duì)性地提高功能覆蓋率。

SV隨機(jī)約束的應(yīng)用,就像是我們用陳述性(declarative)的語句告訴仿真器我們要的隨機(jī)數(shù)要滿足哪些條件,然后仿真器的約束解算器(constraint solver)就會(huì)去找到能夠滿足我們所有描述語句的解,再?gòu)倪@些解中隨機(jī)選出來一個(gè)值作為隨機(jī)的結(jié)果。

約束解算器

約束解算器是SV仿真器重要的一部分,它被專門用來求解約束。這里說的求解,就是指的仿真程序通過某種算法,找到能夠滿足我們所有約束條件的隨機(jī)值的過程。如果隨機(jī)被過約束(over-constraint)了,或者存在隨機(jī)值的組合情況不能滿足約束,則約束解算器就會(huì)解算失敗。在實(shí)際應(yīng)用中,仿真程序就會(huì)報(bào)錯(cuò),然后打印出來告訴我們是哪段約束沒有解算成功。

理解約束解算器的重要性,可以想想如果沒有約束解算器會(huì)怎么樣?舉一個(gè)簡(jiǎn)單的栗子,現(xiàn)在我們有一個(gè)約束條件:變量A的隨機(jī)值總是小于變量B的隨機(jī)值。如果沒有約束功能,代碼可以這么實(shí)現(xiàn):

do begin
    A = $urandom;
    B = $urandom;
end while (! (A

使用約束語句代碼是這樣的:

class ictalking;
    rand bit [7:0] A, B;
    constraint c_ab { A < B; }
endclass

可以看得出來,如果沒有約束解算器,我們?cè)诿枋黾s束的時(shí)候就會(huì)變得比較繞,通常會(huì)花掉很多時(shí)間去重復(fù)執(zhí)行相同的一段代碼,有時(shí)候甚至?xí)芰税胩於甲膊怀鰜硪粋€(gè)滿足約束的隨機(jī)值,更別說那些復(fù)雜的約束了。有了約束解算器,我們就可以在其框架內(nèi)加入各種約束語句,它總能幫我們快速找到那個(gè)解。

約束關(guān)系和控制

約束的解算順序: 約束的解算順序可以使用solve-before來控制。約束解算器會(huì)優(yōu)先求解before之前的約束,因此使用solve-before會(huì)影響隨機(jī)數(shù)組合的概率分布情況。

class ictalking;
    rand bit [7:0] A, B;
    constraint c_a { A > B; }
    constraint c_order {solve A before B;}
    // 順序約束可以寫在同一個(gè)約束塊中,    // 也可以分開寫在不同的約束塊中(如本例)endclass

硬約束和軟約束: 當(dāng)我們?cè)诓煌膶哟螌?duì)隨機(jī)變量附加約束的時(shí)候,軟約束可以被后面指定的約束給覆蓋。典型的應(yīng)用場(chǎng)景是在UVM的sequence_item(或者叫transaction)定義時(shí),我們可以通過軟約束指定默認(rèn)的隨機(jī)約束,這樣方便我們后面在繼承或者例化的時(shí)候可以使用更高優(yōu)先級(jí)的約束對(duì)其覆蓋。

class ictalking;
    rand int count;
    constraint c_count {
           soft count inside {[666:888]}; // 指定軟約束需要使用關(guān)鍵字soft
    }
endclass

ictalking ict = new();
ict.randomize() with { count inside {[123:456]}; }

約束的控制開關(guān): 默認(rèn)情況下,所有的約束一寫上就默認(rèn)使能,即約束解算器就會(huì)按照這些約束開始算。但SV提供約束條件的控制方法constraint_mode(),可以很方便的控制約束是否啟用,以及查詢約束的啟用狀態(tài)。

// 繼續(xù)上面的例子
int con_status;
ictalking ict_obj1 = new();
ictalking ict_obj2 = new();

ict_obj1.c_count.constraint_mode(0); // 不啟用ict_obj1中的約束c_count
ict_obj2.c_count.constraint_mode(1); // 啟用ict_obj2中的約束c_count
ict_obj1.count.rand_mode(0); // 順便提一嘴,隨機(jī)變量類似的可以使用rand_mode開關(guān)隨機(jī)功能

con_status = ict_obj1.c_count.constraint_mode(); // 獲得ict_obj1中約束c_count的啟用狀態(tài)

五花八門的約束代碼

SV中的約束非常靈活,下面給出一些常用的約束代碼,可以作為參考和總結(jié)。

  • 范圍約束: 使用inside指定隨機(jī)數(shù)的范圍或者枚舉值
rand int temp_var;
constraint c_var_1 {temp_var inside {[2000:2021]}; }           // 限定范圍
constraint c_var_2 {temp_var inside {2008, 2016, 2019}; } // 限定枚舉值
constraint c_var_3 {! (temp_var inside {[1:2007]});              // 反向限定范圍
  • 條件約束: SV中有兩種寫條件約束的方式:implication(有些地方會(huì)翻譯成蘊(yùn)藏或者關(guān)聯(lián)等等)和 if-else,用來指定在某些條件下才做進(jìn)一步的約束,這兩種方法使用上幾乎沒有區(qū)別。
rand bit mode;
rand int count;
constraint c_var_1 { mode == 1 -> count < 2021; } // 使用implication操作符->
constraint c_var_2 { if (mode == 1) {count < 2021;} else {count > 6000;} } // 使用if-else
  • 權(quán)重約束: 約束可以指定隨機(jī)值的權(quán)重,主要有兩種方式:dist和randcase。dist一般用在constraint約束塊中,但randcase一般用在程序執(zhí)行塊中,比如某個(gè)函數(shù)、任務(wù)或者initial塊等。
rand bit mode;
rand int count;
constraint c_var_1 {
    mode == READ  -> count inside {[2008:2016]};
    mode == WRITE -> count inside {[2017:2021]};
    mode dist {READ := 4, WRITE := 6}; // mode隨機(jī)成READ的概率為40%,WRITE為60%
}

initial begin
    repeat (100) begin
        randcase            2: $display("In 1st branch."); //100次循環(huán)中,執(zhí)行分支1的概率是20%            7: $display("In 2nd branch."); //100次循環(huán)中,執(zhí)行分支2的概率是70%
            1: $display("In 3rd branch."); //100次循環(huán)中,執(zhí)行分支3的概率的10%
         endcase
     end
end
  • 唯一約束: 唯一約束使用unique關(guān)鍵字來限定變量之間的值是唯一的,即兩兩之間互不相等。
rand int a, b, c;
rand int array[5];
int q[$] = `{200, 53, 656};

constraint c_unique {
    unique {a, b, c};     // 該約束要求a和b和c兩兩之間互不相等
    unique {a, b, array}; // 該約束要求a和b和array中的所有值互不相等
    unique {array};       // 該約束要求array數(shù)組內(nèi)的5個(gè)值互不相等
    unique {a, q};        // 該約束要求a隨機(jī)出來的值不等于q中的任一值
}
  • 循環(huán)約束: 在對(duì)隊(duì)列或者數(shù)組進(jìn)行隨機(jī)化的時(shí)候,可以使用foreach來對(duì)其循環(huán)施加約束。
rand int q[$];
constraint c_foreach {
    q.size() inside {[3:8]};
    foreach (q[i]) {
        if (i > 0) q[i] > q[i-1]; // 約束q隊(duì)列的下一個(gè)值總比上一個(gè)值大
    }
}
  • 縮位約束: 縮位約束會(huì)相對(duì)復(fù)雜一些,但是很好理解。1. 縮位運(yùn)算:比如對(duì)于數(shù)組arr[5],arr.sum就是arr[0] + arr[1] + ... + arr[4]。除sum之外,還有product、and、or、xor,分別表示乘積、與、或、異或運(yùn)算。2. 這些縮減運(yùn)算的方法的返回值類型,跟隊(duì)列或者數(shù)組的元素類型一樣,因此當(dāng)類型不匹配的時(shí)候,需要做類型轉(zhuǎn)換的操作。3. 縮減運(yùn)算的方法可以可選的加with條件,用來篩選隊(duì)列或者數(shù)組中的元素。另外關(guān)鍵字item表示當(dāng)前的數(shù)組元素,item.index表示當(dāng)前數(shù)組元素的索引。
rand bit qbit[$];
rand int qint[$];

constraint c_qbit {
    qbit.size() inside {[4:6]};
    (qbit.sum with (int'(item))) == 3; // 將當(dāng)前元素item轉(zhuǎn)為int類型,并約束所有元素有且只有3個(gè)為1
}

constraint c_qint {
    qint.size() inside {[5:9]};
    (qint.sum with ((item.index < 3) ? item : 0)) == 45; // 約束qint隊(duì)列的前三個(gè)加起來等于45
}
  • 靜態(tài)約束: 靜態(tài)約束使用的關(guān)鍵字static跟靜態(tài)變量是一樣的。靜態(tài)約束表示的是所有的對(duì)象實(shí)例都使用的同一個(gè)約束,所以使用constraint_mode()進(jìn)行開關(guān)控制的時(shí)候具有全局性。
class ictalking;
    rand int count;
    static constraint c_count {count > 34;}
endclass

module testbench;
    initial begin        ictalking ict_obj1 = new();        ictalkingict_obj2=new();        ict_obj1.c_count.constraint_mode(0); // 關(guān)掉的之后ict_obj2中的c_count也會(huì)失效  ...
     end
endmodule

參考文獻(xiàn)

[1] IEEE Standard Association. "IEEE Standard for SystemVerilog-Unified Hardware Design, Specification, and Verification Language." (2013).

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Verilog
    +關(guān)注

    關(guān)注

    28

    文章

    1351

    瀏覽量

    110107
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4788

    瀏覽量

    68625
  • 約束
    +關(guān)注

    關(guān)注

    0

    文章

    82

    瀏覽量

    12733
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    SystemVerilog 的VMM驗(yàn)證方法學(xué)教程教材

    SystemVerilog 的VMM 驗(yàn)證方法學(xué)教程教材包含大量經(jīng)典的VMM源代碼,可以實(shí)際操作練習(xí)的例子,更是ic從業(yè)人員的絕佳學(xué)習(xí)資料。SystemVerilog 的VMM 驗(yàn)證方法
    發(fā)表于 01-11 11:21

    驗(yàn)證方法簡(jiǎn)介

    則和指南。驗(yàn)證方法提供了構(gòu)建穩(wěn)健、可靠和完整的驗(yàn)證環(huán)境的方法。驗(yàn)證方法通過其預(yù)定義的庫(kù)減少了驗(yàn)證工作。 驗(yàn)證方法進(jìn)一步提供了一個(gè)框架,用于簡(jiǎn)化覆蓋驅(qū)動(dòng)的
    發(fā)表于 02-13 17:03

    設(shè)計(jì)驗(yàn)證中的隨機(jī)約束

    隨機(jī)約束在現(xiàn)代集成電路驗(yàn)證中已得到國(guó)際IC 設(shè)計(jì)業(yè)界的普遍認(rèn)可,并逐漸開始普及。與傳統(tǒng)的定向測(cè)試比較,它在驗(yàn)證效率、驗(yàn)證覆蓋率等方面具有諸多優(yōu)勢(shì)。最新公布的Sys
    發(fā)表于 12-14 09:54 ?13次下載

    如何利用SystemVerilog仿真生成隨機(jī)數(shù)

    采用SystemVerilog進(jìn)行仿真則更容易生成隨機(jī)數(shù),而且對(duì)隨機(jī)數(shù)具有更強(qiáng)的可控性。對(duì)于隨機(jī)變量,在SystemVerilog中可通過r
    的頭像 發(fā)表于 10-30 10:33 ?1.1w次閱讀
    如何利用<b class='flag-5'>SystemVerilog</b>仿真生成<b class='flag-5'>隨機(jī)</b>數(shù)

    SystemVerilog中的操作方法

    SystemVerilog提供了幾個(gè)內(nèi)置方法來支持?jǐn)?shù)組搜索、排序等功能。
    的頭像 發(fā)表于 10-31 10:10 ?2838次閱讀

    簡(jiǎn)述SystemVerilog的各種隨機(jī)方法

    我習(xí)慣將驗(yàn)證空間理解為:驗(yàn)證中原則上需要覆蓋的芯片所有有可能出現(xiàn)的工作狀態(tài)的集合。為了探索這片廣袤的驗(yàn)證空間,驗(yàn)證的時(shí)候搞出了帶有約束隨機(jī)測(cè)試(constrainted-random testing),并搞了覆蓋率(coverage)作為評(píng)估機(jī)制。這也是一套成熟可信的工
    的頭像 發(fā)表于 01-21 16:59 ?6256次閱讀
    <b class='flag-5'>簡(jiǎn)述</b><b class='flag-5'>SystemVerilog</b>的各種<b class='flag-5'>隨機(jī)</b>化<b class='flag-5'>方法</b>

    使用SystemVerilog解決數(shù)組問題

    數(shù)獨(dú)是一種非常流行的游戲,數(shù)獨(dú)本質(zhì)上也是一個(gè)約束問題,所以我們可以讓SystemVerilog約束求解器來幫助我們解決。 約束求解器的精妙之處就是,我們只描述
    的頭像 發(fā)表于 03-08 14:06 ?1595次閱讀

    一些有趣的數(shù)組相關(guān)的SystemVerilog約束

    我們?cè)诠ぷ髦谐3?huì)針對(duì)數(shù)組施加各式的約束,下面列舉一下有趣的Systemverilog數(shù)組約束示例。
    的頭像 發(fā)表于 03-08 13:12 ?973次閱讀

    SystemVerilog中“軟約束”與“硬約束”的應(yīng)用示例

    示例中采用的是“硬約束”,因?yàn)槎x在類中的約束隨機(jī)時(shí)指定的內(nèi)嵌約束“矛盾”,所以導(dǎo)致約束解析器解析隨機(jī)
    發(fā)表于 03-15 16:56 ?4755次閱讀

    列舉一下有趣的Systemverilog數(shù)組約束示例

    上面是最先想到的寫法,但是會(huì)報(bào)錯(cuò),因?yàn)镾V約束語法不允許使用size()或任何其他隨機(jī)值作為索引。
    的頭像 發(fā)表于 05-04 17:35 ?1045次閱讀

    systemverilog隨機(jī)約束implication的概率分析

    在此設(shè)計(jì)三種不同的隨機(jī)先后順序,分析x和y取值的其概率分布。
    的頭像 發(fā)表于 05-04 18:24 ?1192次閱讀
    <b class='flag-5'>systemverilog</b><b class='flag-5'>隨機(jī)</b><b class='flag-5'>約束</b>implication的概率分析

    一些有趣的數(shù)組相關(guān)的SystemVerilog約束

    我們?cè)诠ぷ髦谐3?huì)針對(duì)數(shù)組施加各式的約束,下面列舉一下有趣的**Systemverilog數(shù)組約束**示例
    的頭像 發(fā)表于 05-30 11:13 ?795次閱讀

    創(chuàng)建約束隨機(jī)測(cè)試目標(biāo)

    數(shù)據(jù)項(xiàng)的順序。 這種方法提供了更多的靈活性和控制。 約束數(shù)據(jù)項(xiàng)? 默認(rèn)情況下,sequencers會(huì)生成完全隨機(jī)的數(shù)據(jù)項(xiàng)。測(cè)試用例編寫者可以控制生成的數(shù)據(jù)項(xiàng)數(shù)量,并向數(shù)據(jù)項(xiàng)添加約束。為
    的頭像 發(fā)表于 06-17 14:06 ?648次閱讀
    創(chuàng)建<b class='flag-5'>約束</b><b class='flag-5'>隨機(jī)</b>測(cè)試目標(biāo)

    SystemVerilog隨機(jī)約束方法

    上一篇文章《暗藏玄機(jī)的SV隨機(jī)化》介紹了SystemVerilog的各種隨機(jī)方法,本文將在其基礎(chǔ)上引入SystemVerilog
    的頭像 發(fā)表于 09-24 12:15 ?1735次閱讀

    SV約束隨機(jī)化總結(jié)

    constraint 約束隨機(jī)化類中的變量 在main_phase 之前就已經(jīng)提前產(chǎn)生一個(gè)變量的隨機(jī)值。 用法:一般在類中定義一個(gè)rand 類型的變量, 然后根據(jù)需求寫約束
    的頭像 發(fā)表于 12-14 14:30 ?900次閱讀
    SV<b class='flag-5'>約束</b><b class='flag-5'>隨機(jī)</b>化總結(jié)