記錄幾個SystemVerilog的語法——隨機

1. 隨機穩定性(random stability)

隨機穩定性是指每個線程(thread)或對象(object)的random number generator(RNG)是私有的,一個線程返回的隨機值序列與其他線程或對象的RNG是無關的。隨機穩定性適用于以下情況:

  • 系統隨機方法調用:$urandom()和$urandom_range();
  • 對象和進程設置種子方法:srandom();
  • 對象隨機化方法:randomize();

在用戶代碼發生小改動時,Testbench帶有這個特性就可以有更穩定的RNG行為。另外,可以通過手動調整線程和對象的seed,這樣就可以更精確控制隨機值的產生。

隨機穩定性包含以下特性:

  • Initialization RNG(初始化RNG):每個module例化、interface例化、program例化和package都有一個初始化RNG。每一個初始化RNG都有默認的seed,它的值實現定義。一個初始化RNG用于創建靜態進程和靜態初始化器(initializer)。
  • Thread stability(線程穩定性):每一個線程都有一個獨立的RNG,該線程中調用隨機化的所有系統都會使用這個RNG。當一個新的動態線程創建時,它RNG的seed值是從parent線程生成的下一次隨機值,該方式稱為hierarchical seeding。對于一個靜態進程創建時,它RNG的seed值是從聲明該進程的初始化RNG (來自module instance、interface instance、program instance或者package)的下一個隨機值來的。程序和線程的隨機穩定性可以通過保持之前創建線程和RNG的順序一致即可。當給現存testcase增加新的線程時,可以加在代碼塊的末尾,這樣來保持之前創建流程的隨機數穩定性。
  • Object stability(對象穩定性):每一個類的例化(object)都有一個獨立的RNG,用于該類內部所有隨機化方法。當一個object創建時,它RNG的seed是來源于創建該object的線程。當一個object是被靜態初始化器創建時,它RNG的seed將會來源于該初始化RNG(來自module instance、interface instance、program instance或者package)的下一個隨機值,因為這時候沒有active線程提供seed的。對象穩定性可以通過保持之前創建object和RNG的順序一致即可。為了保持RNG穩定性,新objects、線程和隨機數的創建應該在現存objects創建之后進行。
  • Manual seeding(手動設置種子):所有沒有初始化的RNGs可以手動設置seed。結合hierarchical seeding,該機制可以用于在一個subsystem的root thread定義一個簡單seed,然后這個seed會作用到整個subsystem的運行。

2. 線程穩定性(Thread stability)例子

$urandom系統調用返回的隨機值與線程執行順序無關。如下例子:

integer x, y, z;forkbeginprocess::self.srandom(100);? // set a seed at the start of a threadx = $urandom;endbeginy = $urandom;process::self.srandom(200);? // set a seed during a threadendbeginz = $urandom + $urandom ;? // draw 2 values from the thread RNGendjoin

上述程序片段演示了一下幾個特性:

  • Thread locality(線程局部性):x、y和z的返回值與線程的執行順序無關。這是一個很重要的特性,因為它允許開發獨立、可控和可預測的子系統;
  • Hierarchical seeding(分層設置種子):在創建線程時,將使用父線程的下一個隨機值作為種子初始化它的隨機狀態。因此,這三個fork引起的線程都是從父線程中得到種子的;

每個線程都有一個唯一的種子值,僅由其父線程決定。線程執行的根(root)決定了它的子節點隨機種子。這就允許設置根線程來自動和保留子節點線程的行為。

3. 對象穩定性(Object stability)例子

每個類中內置的randomize()可以確保對象的穩定性,這使得在一個實例中調用randomize()獨立于其它實例中調用randomize(),并且獨立于調用其它randomize()函數。例如:

class C1;rand integer x;endclassclass C2;rand integer y;endclassinitial beginC1 c1 = new();C2 c2 = new();integer z;void'(c1.randomize());// z = $random;void'(c2.randomize());end
  • c1.x和c2.x返回的值是互相獨立的;
  • randomize()的調用是獨立于$random系統調用。如果沒有注釋掉上述z=$random,那么分配給c1.x和c2.y的值也不會發生變化;
  • 每個實例都有一個可以獨立設置種子的唯一的隨機值源。該隨機種子可以從父線程創建實例時獲取;
  • Object可以在任何時候使用srandom()方法進行設置種子;
class C3function new (integer seed);//set a new seed for this instancethis.srandom(seed);endfunctionendclass

一旦對象被創建,就不能保證創建該對象的線程可以在另一個線程訪問該對象之前更改該對象的隨機狀態。因此,對象最好從它們內部new()構造函數而不是從外部進行自我設置種子。

一個object的seed可以在任何線程里面改變。但是一個線程的seed只能在線程內部修改的。

4. 手動進行隨機化設置例子

每個對象都維護自己內部的RNG,該RNG僅由其randomize()方法調用。這就允許對象獨立于其它對象和調用其它系統隨機化函數進行隨機化。當一個對象被創建時,它的RNG將使用創建該對象的線程的RNG中的下一個值作為種子,這個過程稱為分層對象設置種子(hierarchical object seeding)。

有時需要使用srandom()方法手動設置對象RNG的種子,這可以在類方法中完成,也可以在類定義外部完成。一個在類內部設置RNG種子的例子為:

class Packet;rand bit[15:0] header;...function new (int seed);this.srandom(seed);...endfunctionendclass

從外部設置RNG種子的例子為:

Packet p = new(200); // Create p with seed 200.p.srandom(300);? // Re-seed p with seed 300.

在對象的new()函數中調用srandom()確保對象的RNG在任何類成員值隨機化之前使用新設置的種子。在類方法內部設置會比較靠譜點。

5. 唯一性約束(uniqueness constraints)

可以使用unique關鍵字來約束一組變量的隨機值,使得該組變量再隨機之后,任何兩個變量的值都不一樣。能使用該特性的變量類型有整型scalar變量、整型unpacked數組變量的一個leaf element或一片(slice) leaf element或全部leaf element。Leaf element指的是unpacked數組變量拆解到最末尾非unpacked數組類型。例子如下:

rand byte a[5];rand byte b;rand byte excluded;constraint u { unique {b, a[2:3], excluded}; }constraint exclusion { excluded == 5; }

這上述這個例子中,a[2], a[3], b和excluded變量的值在隨機之后將會都不一樣。因為在exclusion 塊中excluded被約束為5,所以a[2], a[3]和b的值將都不會是5。

6. 迭代約束(iterative constraints)

迭代約束允許數組變量使用循環變量、索引表達式或數組縮減法(array reduction methods)去約束。Foreach迭代約束語法如下:

foreach ( ps_or_hierarchical_array_identifier [ loop_variables ] ) constraint_setloop_variables ::= [ index_variable_identifier ] { , [ index_variable_identifier ] }

例子如下:

class C;rand byte A[] ;constraint C1 { foreach ( A [ i ] ) A[i] inside {2,4,8,16}; }constraint C2 { foreach ( A [ j ] ) A[j] > 2 * j; }endclass

C1塊約束了A的每個約束在{2,4,8,16},C2塊約束了A的每個元素值大于它index的兩倍。

循環變量與數組索引之間的映射是由維度的基數所決定的,如下所示:

//???? 1?? 2? 3????????? 3???? 4????? 1?? 2??? -> Dimension numbersint A [2][3][4];??? bit [3:0][2:1] B [5:1][4];foreach( A [ i, j, k ] ) ...foreach( B [ q, r, , s ] ) ...

第一個foreach會使i從0到1迭代,j從0到2迭代,k從0到3迭代。第二個foreach會使q從5到1迭代,r從0到3迭代,s從2到1迭代。

對于動態數組和隊列來說,數組大小也可以被約束的,如果數組大小約束和迭代約束同時發生,那么會先求解數組大小約束,然后求解迭代約束。還有一個就是要防止迭代超出數組大小,用戶必須自己排除這些無效的索引。比如下面例子的k<A.size-1就是防止數組索引溢出。

class C;rand int A[] ;constraint c1 { A.size inside {[1:10]}; }constraint c2 { foreach ( A[ k ] ) (k < A.size - 1) -> A[k + 1] > A[k]; }endclass

數組縮減法可以根據unpacked數組的元素值產生一個整型值,如:

class C;rand bit [7:0] A[] ;constraint c1 { A.size == 5; }constraint c2 { A.sum() with (int'(item)) < 1000; }endclass

c2約束塊將會翻譯成:

( int'(A[0])+int'(A[1])+int'(A[2])+int'(A[3])+int'(A[4]) ) < 1000

7. soft約束

與soft約束相對立的是hard約束,求解器solver必須要滿足hard約束,否則solver求解失敗。Soft約束可以被其它hard約束塊或更高優先級的soft約束塊覆蓋掉,因此,soft約束通常用于給隨機變量指定默認值或分布。

Soft約束之所以可以被其它soft約束覆蓋掉,是因為soft約束之間有不同的優先級,在越后面約束的soft約束優先級越高,因此,驗證環境中子層次比父層次具有更高的優先級。另外,如果只對soft約束求解,那么該次調用求解可以永遠不失敗。如果soft約束求解沒有失敗,那么求解的結果相當于是對hard約束求解一樣。

Soft約束可以被discard掉,也就是不使能,使用disable soft語法可以將比該定義disable的約束塊低優先級的soft約束都失效掉。比如:

class A;rand int x;constraint A1 { soft x == 3; }constraint A2 { disable soft x; } // discard soft constraintsconstraint A3 { soft x inside { 1, 2 }; }endclassinitial beginA a = new();a.randomize();end

A2約束塊要求求解器忽略隨機變量x所有優先級較低的soft約束,從而導致A1約束塊被忽略。因此,求解器只需要滿足最后的A3約束。上述示例將導致隨機變量x取值為1或2。需要注意的是,如果省略了A3約束塊,那么變量x將處于無任何約束的狀態。

8. 隨機化方法

每一個類內部都自帶有randomize()這個virtual方法,它的定義如下:

virtual function int randomize();

randomize()是一個virtual方法,它為類對象中所有active隨機變量提供了隨機值,當然隨機值要符合active約束。如果隨機化成功,那么返回1;反之,返回0。

每一個類也自帶pre_randomize()和post_randomize()方法,注意這兩個方法不是virtual的。pre_randomize()是在randomize()之前調用的,post_randomize()是在randomize()之后調用的。定義如下:

function void pre_randomize();function void pre_randomize();

如果randomize()失敗,那么post_randomize()也不會被調用的。如果randomize()失敗,那么隨機變量要保持原來的值。

9. In-line約束

In-line約束是指用randomize with的方法去隨機類中的變量。當randomize()調用時沒有傳參數,那么它內部所有active 隨機變量都要隨機新值。當randomize()調用時傳參數了,那么這些傳的參數是該object指定隨機變量的全集,其余隨機變量都當作state variables。如下:

class CA;rand byte x, y;byte v, w;constraint c1 { x < v && y > w );endclassCA a = new;a.randomize(); ?????????// random variables: x, y?? state variables: v, wa.randomize( x );?????? // random variables: x????? state variables: y, v, wa.randomize( v, w );? // random variables: v, w? state variables: x, ya.randomize( w, x );? // random variables: w, x? state variables: y, v

據以上可知,randomize()傳參可以改變類內部的任何屬性,設置沒有定義為rand或randc的都可以。不過該機制對于randc是無效的,它不能將非隨機變量變成randc,也不能將randc變成non-randc的。

如果調用randomize()里傳null參數,那么表示該次調用沒有任何隨機變量需要隨機賦新值的,那么該方法相當于是一個checker,它只是返回隨機狀態,這樣就可以用于檢查內部約束塊是否正確。如:

success = a.randomize( null );? // no random variables

10. local范圍解析

在使用randomize() with constraint block的時候,可以引用類屬性或調用方法中(randomize with)的local變量。如果這些變量沒有加限制,那么工具會先搜尋object 類的內部,然后才去搜去調用方法(包含method)的范圍。這樣的話,如果object類和調用方法的范圍內有相同名字的變量,且想要用local的就比較麻煩了,因此SV提供了local::去修改搜尋順序。當一個變量采用local::標識了,那么工具會去local 范圍內找,忽略object類內部的變量。如下例子:

class C;rand integer x;endclassfunction int F(C obj, integer x);F = obj.randomize() with { x < local::x; };endfunction

在obj.randomize() 調用的in-line約束塊中,沒有限定x則會綁定到C類屬性(即正在被隨機化的對象的范圍內),而限定名稱local::x則會綁定到函數F()的參數(局部作用域)。

11. 控制隨機變量和約束塊

rand_mode()可以用于控制是否將隨機變量處于active或inactive狀態。當隨機變量是inactive時,那么它就像是沒有被rand或randc修飾的變量一樣。Inactive變量不會被randomize()隨機賦值的,它們的值會被solver當作state variables。所有的隨機變量的初始態都是active的。rand_mode()方法的定義如下:

task object[.random_variable]::rand_mode( bit on_off );orfunction int object.random_variable::rand_mode();

這里object是指任何能夠獲取到定義該隨機變量的對象句柄的表達式。random_variable是指要對其執行操作的隨機變量的名稱。在作為任務調用時,可以未指定random_variable,則該操作將應用于指定對象內的所有隨機變量。task方式是用于設定variable的mode,參數傳1為active,參數傳0為inactive。function方式時用于返回隨機變量的mode,返回1表示active,返回0表示inactive。

constraint_mode()可以用于控制一個約束塊是否是active或inactive的。如果約束塊是inactive的,那么randomize()在調用時不會考慮該約束塊的了。所有約束塊的初始狀態時active。constraint_mode()方法的定義如下:

task object[.constraint_identifier]::constraint_mode( bit on_off );orfunction int object.constraint_identifier::constraint_mode();

這里object是指任何能夠獲取定義該約束塊所對應的對象句柄的表達式。constraint_identifier是指要被操作的約束塊名字。如果constraint_identifier省略掉,那么object內部的所有constraints都一塊設定。task方式用于設定約束塊的mode,傳1表示active,傳0表示inactive。function方式時用于返回約束塊的mode,返回1表示active,返回0表示inactive。

12. 隨機數系統方法

系統函數$urandom()在每次調用時會返回一個32-bit的unsigned的偽隨機數。定義如下:

function int unsigned $urandom [ (int seed ) ] ;

seed是可選的,seed可以是任何整數表達式。如果seed一致,那么random number generator(RNG)會產生相同的隨機數序列。RNG是確定的,每一次程序執行時,它會從同一個隨機序列周期性的取值。不過我們可以通過指定$urandom的不同seed來使得它變得不確定,如將每一天的時間作為seed。

系統函數$urandom_range()會返回在指定范圍內的無符號整數。定義如下:

function int unsigned $urandom_range(int unsigned maxval, int unsigned minval = 0 );

它將返回maxval到minval之間的數,如果minval省略掉,那么范圍是maxval到0。如果maxval小于minval,那么會自動翻轉,確保第一個參數不小于第二個參數。

srandom()可以用于手動設置object或thread的RNG的種子。srandom()方法使用給定種子的值初始化對象的RNG。定義如下:

function void srandom( int seed );

還有get_randstate()和set_randstate()是用于獲取或設置object的RNG的狀態。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90953.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90953.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90953.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初識 docker [下] 項目部署

項目部署Dockerfile構建鏡像DockerCompose基本語法基礎命令項目部署 前面我們一直在使用別人準備好的鏡像&#xff0c;那如果我要部署一個Java項目&#xff0c;把它打包為一個鏡像該怎么做呢&#xff1f; …省略一萬字 站在巨人的肩膀上更適合我們普通人,所以直接介紹兩種簡單…

Android15廣播ANR的源碼流程分析

Android15的廣播ANR源碼流程跟了下實際代碼的流程&#xff0c;大概如下哈&#xff1a;App.sendBroadcast() // 應用發起廣播→ AMS.broadcastIntentWithFeature() // 通過Binder IPC進入system_server進程→ AMS.broadcastIntentLocked() // 權限校驗廣播分類&#xff08;前…

密碼學中的概率論與統計學:從頻率分析到現代密碼攻擊

在密碼學的攻防博弈中&#xff0c;概率論與統計學始終是破解密碼的“利器”。從古典密碼時期通過字母頻率推測凱撒密碼的密鑰&#xff0c;到現代利用線性偏差破解DES的線性密碼分析&#xff0c;再到側信道攻擊中通過功耗數據的統計特性還原密鑰&#xff0c;統計思維貫穿了密碼分…

力扣刷題977——有序數組的平方

977. 有序數組的平方 題目&#xff1a; 給你一個按 非遞減順序 排序的整數數組 nums&#xff0c;返回 每個數字的平方 組成的新數組&#xff0c;要求也按 非遞減順序 排序。示例 1&#xff1a; 輸入&#xff1a;nums [-4,-1,0,3,10] 輸出&#xff1a;[0,1,9,16,100] 解釋&…

應用加速游戲盾的安全作用

在數字娛樂產業蓬勃發展的今天&#xff0c;游戲已從單純的娛樂工具演變為連接全球數十億用戶的社交平臺與文化載體。然而&#xff0c;伴隨游戲市場的指數級增長&#xff0c;網絡攻擊的頻率與復雜性也呈爆發式上升。從DDoS攻擊導致服務器癱瘓&#xff0c;到外掛程序破壞公平競技…

linux安裝zsh,oh-my-zsh,配置zsh主題及插件的方法

這是一份非常詳細的指南&#xff0c;帶你一步步在 Linux 系統中安裝 Zsh、配置主題和安裝插件。 Zsh&#xff08;Z Shell&#xff09;是一個功能強大的 Shell&#xff0c;相比于大多數 Linux 發行版默認的 Bash&#xff0c;它提供了更強的自定義能力、更智能的自動補全、更漂亮…

【設計模式系列】策略模式vs模板模式

策略模式是什么&#xff1f;如何定義并封裝一系列算法策略模式 (Strategy Pattern)模板模式 (Template Pattern)模板模式與策略模式的深度對比與區分混合使用兩種模式的場景策略模式 (Strategy Pattern) 應用場景&#xff1a;當需要根據不同條件選擇不同算法或行為時&#xff…

aigc(1.1) opensora-2.0

open sora-2.0相關鏈接: arxiv鏈接 huggingface頁面 HunyuanVideo VAE open sora2.0的VAE模型復用了HunyuanVideo的3D VAE,HunyuanVideo的arxiv鏈接。下圖來自論文,可見VAE是一個因果注意力的3D結構。在配圖左側,視頻會被編碼為video token序列,而在配圖右側,去噪的vide…

Linux驅動21 --- FFMPEG 音頻 API

目錄 一、FFMPEG 音頻 API 1.1 解碼步驟 創建核心上下文指針 打開輸入流 獲取輸入流 獲取解碼器 初始化解碼器 創建輸入流指針 創建輸出流指針 初始化 SDL 配置音頻參數 打開音頻設備 獲取一幀數據 發送給解碼器 從解碼器獲取數據 開辟數據空間 初始化內存 音頻重采樣…

《計算機“十萬個為什么”》之 [特殊字符] 序列化與反序列化:數據打包的奇妙之旅 ??

《計算機“十萬個為什么”》之 &#x1f4e6; 序列化與反序列化&#xff1a;數據打包的奇妙之旅 ??歡迎來到計算機“十萬個為什么”系列&#xff01; 本文將以「序列化與反序列化」為主題&#xff0c;深入探討計算機世界中數據的打包與解包過程。 讓我們一起解開數據的神秘面…

機器學習與深度學習評價指標

機器學習與深度學習評價指標完全指南 ?? 為什么需要評價指標? 想象你是一位醫生,需要判斷一個診斷模型的好壞。如果模型說"這個病人有癌癥",你需要知道: 這個判斷有多準確? 會不會漏掉真正的癌癥患者? 會不會誤診健康的人? 評價指標就像是給AI模型打分的&…

Hugging Face-環境配置

打開anaconda promptconda activate pytorchpip install -i https://pypi.tuna.tsinghua.edu.cn/simple transformers datasets tokenizerspycharm找到pytorch下的python.exe#將模型下載到本地調用 from transformers import AutoModelForCausalLM,AutoTokenizer#將模型和分詞工…

cnn中池化層作用

一、池化層概述 在卷積神經網絡中&#xff0c;池化層是核心組件之一&#xff0c;主要作用是逐步降低特征圖的空間尺寸即寬和高&#xff0c;從而減少計算量、控制過擬合并增強模型的魯棒性。 核心作用 降維與減少計算量 壓縮特征圖的尺寸&#xff0c;顯著減少后續層的參數數量和…

寫一個音樂爬蟲

今天我們寫一個網易云音樂的爬蟲&#xff0c;爬取網易云音樂熱歌榜音樂鏈接并下載&#xff0c;這里用到了之前引用的BeautifulSoup和requests。 BeautifulSoup是一個Python庫&#xff0c;用于從HTML和XML文件中提取數據。它提供了一種簡單的方式來遍歷文檔樹和搜索文檔樹中的元…

戰斗公式和傷害走配置文件

故事背景&#xff0c;上次屬性計算用的配置&#xff0c;這次傷害計算也走配置&#xff0c;下面是測試代碼和測試數據local formulas {[100001]{id 100001,name "基礎傷害",formula "function (self,tag,ishit,iscritial,counterratio)\n if ishit1 then\n …

線性代數 上

文章目錄線性代數知識整理一、求行列式1、 套公式2、利用性質&#xff0c;化為可套公式3、抽象行列式4、抽象向量二、代數余子式的線性組合三、求AnA^nAn四、證明A可逆五、求A的逆1、定義法2、初等變換3、公式六、求秩七、線性表示的判定八、線性無關九、求極大線性無關組十、等…

紅帽AI推理服務器三大特點

生成式人工智能&#xff08;Gen AI&#xff09;的迅猛發展&#xff0c;對大型語言模型&#xff08;LLM&#xff09;的部署提出了更高的性能、靈活性和效率要求。無論部署在何種環境中&#xff0c;紅帽AI推理服務器都為用戶提供經過強化并獲得官方支持的vLLM發行版&#xff0c;配…

開始記錄一步步學習pcl

安裝參考&#xff0c;大神寫的非常詳細&#xff0c;一步到位 https://blog.csdn.net/qq_36812406/article/details/144307648?ops_request_misc%257B%2522request%255Fid%2522%253A%25220e215e6ac266b90ded12ed6b2eab1257%2522%252C%2522scm%2522%253A%252220140713.13010233…

Linux系統Centos7 安裝mysql5.7教程 和mysql的簡單指令

目錄 一. 安裝 MySQL 官方 Yum 倉庫 二. 安裝 MySQL 5.7 1.查看可用的mysql版本倉庫 2.啟用MySql5.7倉庫 3.禁用更高版本的倉庫&#xff08;可選&#xff09; 4.導入 MySQL GPG 公鑰 5.安裝MySql5.7 三. 啟動 MySQL 服務 1.啟動 MySQL 服務 2. 設置開機自啟 3.查看服…

嵌入式——C語言:指針③

一、函數指針和指針函數&#xff08;一&#xff09;指針函數&#xff1a;是函數&#xff0c;函數的返回值是指針1.不能返回局部變量的值2.指針函數返回的地址可以作為下一個函數調用的參數&#xff08;二&#xff09;函數指針&#xff1a;是指針&#xff0c;指針指向一個函數in…