我習(xí)慣將驗(yàn)證空間理解為:驗(yàn)證中原則上需要覆蓋的芯片所有有可能出現(xiàn)的工作狀態(tài)的集合。為了探索這片廣袤的驗(yàn)證空間,驗(yàn)證的時(shí)候搞出了帶有約束的隨機(jī)測(cè)試(constrainted-random testing),并搞了覆蓋率(coverage)作為評(píng)估機(jī)制。這也是一套成熟可信的工程學(xué)方法。
因?yàn)榧s束和隨機(jī)化可以講的干貨太多,于是我做了拆分。本文要介紹的內(nèi)容就僅涉及SV的隨機(jī)化處理,包括偽隨機(jī)數(shù)的產(chǎn)生、隨機(jī)穩(wěn)定性和編程示例。
偽隨機(jī)數(shù)的產(chǎn)生
SystemVerilog提供了很多生成偽隨機(jī)數(shù)的方法,比如產(chǎn)生隨機(jī)數(shù)的內(nèi)建函數(shù)**random, **urandom, $urandom_range,對(duì)象隨機(jī)方法object.randomize(),標(biāo)準(zhǔn)庫(kù)隨機(jī)函數(shù)std::randomize()等等。這些函數(shù)的用法在很多教程中都會(huì)提到,而本文要做的,是要挖一挖這些函數(shù)的“玄機(jī)”。
1. Probabilistic Distribution System Functions
第一類隨機(jī)函數(shù)是概率分布系統(tǒng)函數(shù)(probabilistic distribution system funtions),這類函數(shù)在LRM中明確包括**random, **dist_uniform, **dist_normal, **dist_exponential, $dist_poisson等可以產(chǎn)生滿足不同概率分布的隨機(jī)數(shù)的函數(shù),并且在附錄N中用C代碼給出了這些函數(shù)的實(shí)現(xiàn)算法。這就意味著,使用相同的種子,這些函數(shù)在不同的仿真軟件中產(chǎn)生出來(lái)的隨機(jī)數(shù)序列應(yīng)該是一致的。這也是這類函數(shù)跟其他類函數(shù)的主要區(qū)別。
2. Object and Scope Randomization Method
再來(lái)看對(duì)象隨機(jī)方法object.randomize(),這個(gè)函數(shù)在LRM中被稱為“the object and scope randomization method”。顧名思義,它專門被用來(lái)隨機(jī)化對(duì)象。它是所有SV類中都會(huì)默認(rèn)存在的內(nèi)置虛函數(shù)(原型是virtual function int randomize()),但是它不能被覆蓋(overridden)。當(dāng)你使用object.randomize() 來(lái)對(duì)對(duì)象進(jìn)行隨機(jī)化的時(shí)候,注意它只會(huì)隨機(jī)化類中有rand關(guān)鍵詞修飾的成員變量,并且在成功隨機(jī)化之后會(huì)返回1,失敗則返回0。除此之外,每個(gè)類中還有randomize的兩個(gè)回調(diào)函數(shù)pre_randomize()和post_randomize(),這兩個(gè)函數(shù)分別會(huì)在執(zhí)行randomize()的前后自動(dòng)被調(diào)用。注意,這兩個(gè)函數(shù)并不是虛函數(shù)(其函數(shù)原型沒有virtual關(guān)鍵字),但他們是由虛函數(shù)randomize()來(lái)自動(dòng)調(diào)用的,因此也表現(xiàn)為虛函數(shù)的多態(tài)行為。
這套使用類來(lái)描述和控制隨機(jī)數(shù)據(jù)及其約束的機(jī)制相當(dāng)強(qiáng)大。之所以這么說(shuō),一方面是因?yàn)橛辛祟惖睦^承特性的加持,隨機(jī)變量可以方便地繼承和擴(kuò)展;另一方面是因?yàn)镾V還提供了約束的覆蓋、擴(kuò)展、使能和禁用等功能。但這里有一個(gè)問題,就是object.randomize()還是只能隨機(jī)化類的成員變量,不能隨機(jī)化局部變量。為了解決這個(gè)問題,SV又搞來(lái)了一個(gè)可用于當(dāng)前范圍內(nèi),且不限于對(duì)象成員的隨機(jī)化函數(shù)std::randomize(),它在LRM中的定性是scope randomize function。
Std lib下的std::randomize()的適用性比object.randomize()要好,不過它不能自動(dòng)隨機(jī)對(duì)象中的rand成員變量,也沒有pre和post函數(shù)可以調(diào)用,畢竟魚和熊掌不可兼得呀。std::randomize()在某些場(chǎng)景下前面的“std::”是可以省略的,但還是建議使用的時(shí)候加上比較好,能與上面講的object.randomize()做出區(qū)分。除了可以隨機(jī)化當(dāng)前范圍內(nèi)變量,std::randomize()使用的時(shí)候可以將需要隨機(jī)化的多個(gè)變量同時(shí)放到參數(shù)列表中一起做隨機(jī),且能適配這些變量的位寬。該函數(shù)返回結(jié)果跟object.randomize()一樣,成功返回1,失敗返回0。
3. Random Number System Function
最后要將講的是SV中比較古老的隨機(jī)函數(shù)和方法urandom()和urandom_range()。后者只是在前者的基礎(chǔ)上增加了范圍限制。**urandom的函數(shù)原型是function int unsigned **urandom [(int seed)]??梢钥闯鰜?lái),這兩個(gè)函數(shù)的返回值都是32bit的無(wú)符號(hào)數(shù)。如果初始隨機(jī)種子一樣,則相同工具的每一次仿真跑出來(lái)的隨機(jī)數(shù)是一致的,這是涉及到下小節(jié)要講的一個(gè)重要的特性:隨機(jī)穩(wěn)定性。
隨機(jī)穩(wěn)定性(Random stability)
在SV中,不同線程(thread)或?qū)ο螅╫bject)在隨機(jī)化時(shí)使用的隨機(jī)數(shù)產(chǎn)生器(RNG)是相互獨(dú)立的。另一方面,相同線程或相同對(duì)象在相同隨機(jī)種子的情況下,每一次仿真中產(chǎn)生的隨機(jī)數(shù)序列是一樣的。這個(gè)屬性就叫random stability。
隨機(jī)穩(wěn)定性之所以重要,是因?yàn)樵谛酒?yàn)證中,隨機(jī)驗(yàn)證方法是很重要的一部分,在用例回歸之后,那些Failed的測(cè)試用例通常需要使用觸發(fā)錯(cuò)誤的隨機(jī)種子來(lái)重現(xiàn),比如把波形Dump出來(lái)。因此,有必要了解線程和對(duì)象的隨機(jī)化機(jī)制。下面從三個(gè)層面看這套機(jī)制是怎么運(yùn)作的。
**Initialization RNG:**初始化RNG是產(chǎn)生隨機(jī)數(shù)的開始,用來(lái)給RNG初始化隨機(jī)種子。每一個(gè)模塊實(shí)例(module instance)、接口實(shí)例(interface instance)、程序塊(program)和包(package)實(shí)例都有屬于自己的初始化RNG,在不指定隨機(jī)種子的情況下,默認(rèn)的隨機(jī)種子根據(jù)不同編譯器的實(shí)現(xiàn)決定的。上小節(jié)講的每一種偽隨機(jī)數(shù)的產(chǎn)生方法都有自己指定隨機(jī)種子的函數(shù)
**Hierarchy seeding:**分層分配隨機(jī)種子是隨機(jī)穩(wěn)定性的重要機(jī)制。在創(chuàng)建新的線程或者實(shí)例化對(duì)象的時(shí)候,父線程使用的RNG的下一個(gè)隨機(jī)值會(huì)作為這個(gè)新線程或者新對(duì)象的RNG的隨機(jī)狀態(tài),即作為新的種子傳遞下去。
**Thread and Object Stability:**SV中將程序(program)、模塊(module)、接口(interface)、函數(shù)(function)、任務(wù)(task)等這些獨(dú)立的塊叫Process。每個(gè)Process都有自己的RNG。每個(gè)RNG都有自己的隨機(jī)狀態(tài)(random state)。我們可以通過process::self()這個(gè)靜態(tài)方法獲取當(dāng)前Process的RNG句柄,在通過句柄調(diào)用get_randstate()方法來(lái)獲得隨機(jī)狀態(tài)。不同的仿真工具返回來(lái)的隨機(jī)狀態(tài)的值的表現(xiàn)方式可能會(huì)不一樣,但基本都是一段看起來(lái)沒有規(guī)律的字符串,這個(gè)字符串表示下一個(gè)要產(chǎn)生的隨機(jī)數(shù)的值。
SV的這套隨機(jī)穩(wěn)定性機(jī)制,盡管通常不需要我們?nèi)プ鍪裁?,但是要知道:在我們要?fù)現(xiàn)一個(gè)執(zhí)行失敗的測(cè)試用例的時(shí)候,不要改動(dòng)之前布下的種子,也不要改變程序中線程和對(duì)象創(chuàng)建的順序,避免更改了分層隨機(jī)種子的順序。
編程示例
下面的例程和仿真結(jié)果展示了以上介紹到的隨機(jī)函數(shù)和特性,代碼中也附有必要的注釋。如果需要源碼,可以在公眾號(hào)中直接回復(fù)"SV隨機(jī)"獲得下載鏈接。
仿真結(jié)果如下圖所示:
參考文獻(xiàn)
[1] IEEE Standard Association. "IEEE Standard for SystemVerilog-Unified Hardware Design, Specification, and Verification Language." (2013).
-
芯片
+關(guān)注
關(guān)注
452文章
50224瀏覽量
420993 -
Verilog
+關(guān)注
關(guān)注
28文章
1343瀏覽量
109927 -
System
+關(guān)注
關(guān)注
0文章
165瀏覽量
36849
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論