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