本文依然是比較多的干貨,也偏保姆級,介紹Sequence之間發(fā)生競爭的時候,我們需要或者說可以做些什么,包括如何配置sequence的仲裁算法和優(yōu)先級、如何讓sequence占用sequencer(這個地方UVM 1.2有個bug),以及如何中斷sequence的執(zhí)行。
01 Arbitrary
在UVM中,多個sequence可以同時被綁定到相同的sequencer并啟動。這種測試場景在實際中是存在的,比如在模擬同一個總線master口上的不同類型的數(shù)據(jù)流時,可以將符合這些不同類型的數(shù)據(jù)流的sequence綁定到同一個sequencer,并啟動它們,以構(gòu)造出復(fù)雜的測試場景。
這樣一來,在驗證環(huán)境運行中就會出現(xiàn)競爭的問題,當多個sequence同時企圖向下游發(fā)transaction的時候,sequencer需要能夠決定處理這些transaction的順序。而給出答案的,是sequencer內(nèi)建的仲裁機制。
下面給出一個簡單的UVM例程:例程同時啟動三個sequence(seq_0, seq_1, seq_2),它們會往同一個sequencer發(fā)transaction,并且在啟動的時候還分配了權(quán)重值(start方法的第三個參數(shù)),每個sequence會循環(huán)發(fā)送4個transaction。在Env中例化sequencer和driver,并完成連接。例程中在driver拿到transaction之后,會根據(jù)transaction的成員變量id和index打印出來當前transaction產(chǎn)生自哪個sequence,以及是循環(huán)的第幾次。
仿真結(jié)果如下,可以看得出來在沒有配置仲裁算法的情況下,即使我們?yōu)閟equence都分配了權(quán)重值,sequencer對三個sequence還是“雨露均沾”:
實際上,UVM給我們預(yù)設(shè)了六種仲裁算法供選擇,同時保留了用戶自定義的接口。默認情況下,使用的仲裁算法是UVM_SEQ_ARB_FIFO,嚴格按照先進先出的原則來做選擇,所以才會出現(xiàn)上面說的,仿真結(jié)果跟權(quán)重值沒有關(guān)系。關(guān)于仲裁算法,需要根據(jù)實際測試場景來做出選擇。
那么如何配置仲裁算法?在代碼中,可以通過調(diào)用sequencer的方法set_arbitration()來對仲裁算法進行配置。比如在上面例程env_demo類的build_phase函數(shù)的最后一行,可以加上sqr.set_arbitration(UVM_SEQ_ARB_WEIGHTED)來配置仲裁算法,仿真結(jié)果我貼在下面,可以看到,我們分配的權(quán)重值開始起作用了:
02 LockingMechanism
Locking mechanism指的是sequence對sequencer的占用,sequence可以優(yōu)先獲得sequencer的使用權(quán)限,并且在它自己釋放之前,其他sequence無法通過該sequencer和driver發(fā)送transaction。
Sequence搶占功能同樣來源于測試場景的需求,應(yīng)用于當有某個sequence需要優(yōu)先并獨占sequencer的時候,比如對中斷(interrupt)的處理。如下圖所示,當sequence_2占用了sequencer之后,其他sequence在sequence_2釋放之前將無法聯(lián)系上sequencer。
UVM提供了兩種搶占方法:lock和grab。lock方式會等待仲裁機制正常調(diào)度到該sequence(即將請求放在仲裁隊里的最后),并占用該sequencer直到sequence調(diào)用unlock()來解鎖;grab方式則會使該sequence在下一輪仲裁中被執(zhí)行(即將請求放在仲裁隊列的最前面),并占用該sequencer直到sequence調(diào)用unlock()和ungrab()。
Sequencer被某個sequence搶占了之后,我們可以通過調(diào)用它的成員方法來獲取當前的狀態(tài)信息。比如,可以在sequence的body()里面使用m_sequencer.is_grabbed()函數(shù)來看當前sequencer是不是被誰鎖住了;還可以使用m_sequencer.current_grabber()函數(shù)來獲得當前鎖住sequencer的sequence句柄;還有其他函數(shù)可以使用,具體可以參考UVM的手冊。
關(guān)于lock和grab的使用在其他地方有很多示例代碼,這里將基于上面的例程,展示UVM 1.2潛藏的一個bug。先在上述代碼中seq_demo_0類的body()任務(wù)的入口和出口處,分別加上lock()和unlock(),如上圖所示,然后進行仿真,就會發(fā)現(xiàn):最終只有seq_0搶先鎖住了sequencer,雖然我們在body()的最后調(diào)用了unlock(),但是seq_1和seq_2在seq_0結(jié)束之后依然搶不到鎖,仿真最后結(jié)束在UVM timeout,如下圖:
這是一個UVM的bug,問題的根源在uvm_sequencer_base的源碼中,當有多個sequence在lock_list隊列里面時,調(diào)用m_wait_for_available_sequence()方法獲取sequence句柄會使代碼掛死。該UVM issue已經(jīng)有人提交到了accellera,具體可以參見參考資料2。這個bug在UVM 2017-1.1或者UVM 2020中可能已經(jīng)修掉了,有興趣的讀者可以自己試一下。鑒于目前有很多代碼是基于UVM 1.2構(gòu)建的,用戶在使用lock/grab的時候需要特別注意這個bug。
03Sequence Interrupt
在處理器等數(shù)字系統(tǒng)中,通常硬件中斷都是由某個信號脈沖或者電平來觸發(fā),并通過中斷控制仲裁之后,由控制器發(fā)送給處理器進行處理。
在Sequence中的中斷操作也類似,分兩部分實現(xiàn):第一部分是將通過虛擬接口監(jiān)視中斷源信號的變化,以實現(xiàn)軟硬件的隔離;第二部分是在主sequence中發(fā)起一個監(jiān)視進程(monitor process),在等到中斷到來之后啟動用作中斷處理的sequence。
另外,Sequence一旦被啟動,通常不會去想著將它異常結(jié)束(通過seq.kill()或者seqr.stop_sequences()調(diào)用),否則我們需要更加復(fù)雜的實現(xiàn)去查看當前driver是否空閑,以確保sequencer跟driver的握手機制不出問題。如果有必要將sequence提前結(jié)束,建議在sequence內(nèi)部去做條件判斷和處理。
審核編輯:劉清
-
中斷
+關(guān)注
關(guān)注
5文章
900瀏覽量
41792 -
UVM
+關(guān)注
關(guān)注
0文章
182瀏覽量
19234 -
FIFO芯片
+關(guān)注
關(guān)注
0文章
10瀏覽量
8859
原文標題:SystemVerilog | UVM | Sequence的仲裁和鎖定,還有要避開UVM的bug
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
freertos中斷優(yōu)先級在哪設(shè)置
APS智能優(yōu)化排產(chǎn)軟件的優(yōu)先級應(yīng)用
![APS智能優(yōu)化排產(chǎn)軟件的<b class='flag-5'>優(yōu)先級</b>應(yīng)用](https://file1.elecfans.com/web2/M00/F4/0A/wKgaomZ74pSAamRgAABGv1f1AXE050.png)
ESP32S2如何設(shè)置中斷優(yōu)先級?
請問有什么方法降低WIFI中斷的優(yōu)先級?
如何在不同優(yōu)先級安裝相同的處理程序?
systick的中斷優(yōu)先級是否應(yīng)該設(shè)置為最高優(yōu)先級的嵌套中斷?
stm32的中斷優(yōu)先級分組了之后還能改分組嗎?
創(chuàng)建了兩個task如果一個優(yōu)先級高 一個優(yōu)先級低,高優(yōu)先級的那個一直在做,什么時候會調(diào)度到低優(yōu)先級的呢?
STM8中斷優(yōu)先級不夠怎么解決?
嵌入式實時操作系統(tǒng)中的優(yōu)先級反轉(zhuǎn)問題
![嵌入式實時操作系統(tǒng)中的<b class='flag-5'>優(yōu)先級</b>反轉(zhuǎn)問題](https://file1.elecfans.com/web2/M00/DC/2D/wKgaomYrXJaAYQ0AAAAQgXX2vuA412.jpg)
評論