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)注
68文章
19118瀏覽量
228861 -
控制器
+關(guān)注
關(guān)注
112文章
16133瀏覽量
177137 -
UVM
+關(guān)注
關(guān)注
0文章
181瀏覽量
19122 -
FIFO存儲
+關(guān)注
關(guān)注
0文章
103瀏覽量
5955
原文標題:SystemVerilog | UVM | Sequence的仲裁和鎖定,還有要避開UVM的bug
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論