本篇介紹UVM中的sequence,這是UVM中最基礎(chǔ)的部分。對(duì)于前面介紹的uvm_callback, uvm_visitor等,很少被使用到或者也只有搭建平臺(tái)的人會(huì)使用。不能認(rèn)為平臺(tái)的搭建更富有“技術(shù)含量”,用例的構(gòu)建有時(shí)候更重要。UVM提供了多種方式,常常讓使用者混淆,本篇將會(huì) “捋” 一下sequence_item,sequence,sequencer,driver的協(xié)作關(guān)系,結(jié)合設(shè)計(jì)模式中的命令模式,中介模式,橋接模式進(jìn)行介紹。
啟動(dòng)與掛載
基本理解:UVM中各個(gè)組件的相互“交流”是基于實(shí)際業(yè)務(wù)提取出的transaction(uvm_sequence_item);uvm_sequence中的body()函數(shù)負(fù)責(zé)產(chǎn)生發(fā)送這些transaction,生命周期是body()函數(shù)的執(zhí)行期;uvm_sequencer負(fù)責(zé)調(diào)度從uvm_sequence中拿到的transaction,然后發(fā)送給driver;uvm_sequcence和transaction一樣,也是繼承于uvm_sequence_item,uvm_sequcne是transaction的有機(jī)結(jié)合,代表一種具體的業(yè)務(wù)行為,描述一種scenario 這樣更有利于在創(chuàng)建用例時(shí)的復(fù)用。同時(shí)在transaction,uvm_sequence中加入SV特有的語(yǔ)法特點(diǎn),constrain約束,方便擴(kuò)展使用到不同的場(chǎng)景。
啟動(dòng):這里的啟動(dòng)就是通過(guò)哪種方式調(diào)用uvm_sequence中的body()函數(shù)的意思。(body()函數(shù)被sequence的 start()函數(shù)調(diào)用,也可以理解成 start()函數(shù)的執(zhí)行)
sequence的掛載:uvm_sequence不屬于component,沒(méi)有phase概念,需要掛載在一個(gè)sequencer上,在這個(gè)sequencer的phase中被調(diào)用(default_sequence的情形),同時(shí)uvm_sequence可以操作所掛載的sequencer的成員變量( *比如在sequence中使用sequencer中的寄存器模型句柄;在virtual sequence中調(diào)用 virtual sequcner中的其他 sequcner 句柄 * )。
transaction的掛載:對(duì)于transaction,掛載的意思就是將transaction發(fā)送給所掛載的sequencer,sequencer再發(fā)送給連接的driver。(無(wú)論sequence還是transaction,掛載的本質(zhì)就是給uvm_sequence_item中的成員變量 m_sequencer賦值,sequence/transaction都繼承于uvm_sequence_item)
( *啟動(dòng),掛載在UVM英文文檔中沒(méi)有對(duì)應(yīng)關(guān)鍵詞,僅是根據(jù)實(shí)際使用總結(jié)出來(lái)的詞匯 * )
繼承關(guān)系:
三種sequence的啟動(dòng)方式:
1. start()函數(shù)顯示調(diào)用
使用形式:
在sequence中顯示調(diào)用strat()函數(shù),第一個(gè)參數(shù)是需要掛載的sequencer;第二個(gè)是parent_sequence,一般傳入this或者不傳入;第三個(gè)是優(yōu)先級(jí);第四個(gè)call_pre_post默認(rèn)為1,則自動(dòng)執(zhí)行pre_body/ post_body()函數(shù)
執(zhí)行pre_start,body等函數(shù)。此時(shí)就完成了sequence的啟動(dòng)過(guò)程。
在start()函數(shù)中,首先調(diào)用了函數(shù)set_item_context()函數(shù),這個(gè)函數(shù)位于sequence的父類uvm_sequence_item中,負(fù)責(zé)給成員變量m_sequencer, m_parent_sequence賦值。
如果沒(méi)有指定掛載的sequencer,則掛載到parent_sequence的sequencer上。
此處seq0顯示傳入了需要掛載的p_sqr0,則調(diào)用set_sequencer()函數(shù)完成掛載,給m_sequencer賦值。
set_sequencer()函數(shù)會(huì)調(diào)用m_set_p_sequencer(),這個(gè)函數(shù)是一個(gè)空的虛函數(shù)。如果在sequence中調(diào)用了宏uvm_declare_p_sequencer則會(huì)重寫這個(gè)函數(shù),將成員變量p_sequencer指向sequence所掛載的sequencer上。所以使用者要保證start()函數(shù)傳入的sequencer應(yīng)該和宏 uvm_declare_p_sequencer聲明的類型一致。否則$cast轉(zhuǎn)換的時(shí)候會(huì)報(bào)錯(cuò)。
使用uvm_declare_p_sequencer后,就可以在sequence中調(diào)用掛載sequencer的成員函數(shù)和成員變量了。
2. `uvm_do()宏
**使用形式: **
UVM中提供了多個(gè)宏,uvm_do,uvm_do_with,`uvm_do_on_with等,但最終都是調(diào)用了uvm_do_on_pri_with宏。uvm_do_on_pri_with宏第一個(gè)參數(shù)可以傳入sequence,也可以傳入transaction。
uvm_do_on宏第一參數(shù)是sequence。uvm_do_on_pri_with宏中調(diào)用宏uvm_create_on。
create_item通過(guò)工廠模式創(chuàng)建sequence實(shí)例
調(diào)用set_item_context()函數(shù),給成員變量m_sequencer, m_parent_sequence賦值,參考上節(jié)分析。此處parent_sequence默認(rèn)是this。
調(diào)用sequence的start函數(shù),流程和上節(jié)一樣,最后調(diào)用body()函數(shù)。
通過(guò)宏的形式相比于直接調(diào)用start函數(shù),節(jié)省了sequence的實(shí)例化和隨機(jī)化的步驟,但是對(duì)于不熟悉宏的人來(lái)說(shuō),宏封裝的內(nèi)容可能與其使用意圖偏差。
3. default_sequence方式
使用形式:
第一種:
第二種:
使用default_sequence的方式也是通過(guò)工廠模式創(chuàng)建sequence,再隱式的調(diào)用seq.start(this) 函數(shù)
【拓展】
對(duì)于sequence中的資源訪問(wèn),可以參考 UVM設(shè)計(jì)模式 (三) 靜態(tài)類、資源管理、uvm_event、uvm_*_pool、uvm_config_db、UVM_REGEX_NO_DPI 中的"sequence中的資源訪問(wèn)"小節(jié),總結(jié)了5種使用方式。
命令模式
Comand Pattern:將一個(gè)請(qǐng)求(命令)封裝成一個(gè)對(duì)象,從而可以用不同的請(qǐng)求對(duì)接收者進(jìn)行參數(shù)化,實(shí)現(xiàn)請(qǐng)求的發(fā)送者和接收者解耦;還可以對(duì)請(qǐng)求排隊(duì),或者記錄請(qǐng)求日志,以及支持撤銷操作。
命令模式和前面提到的策略模式很相似,也是通過(guò)“組合 + 多態(tài)”實(shí)現(xiàn)的。設(shè)計(jì)模式更關(guān)注于設(shè)計(jì)意圖,也就是應(yīng)用場(chǎng)景,單純地從代碼實(shí)現(xiàn)上看,有些模式確實(shí)很相似,比如命令模式和策略模式。但策略模式是不同策略具有相同的目的,不同的實(shí)現(xiàn),相互之間可以替換,在命令模式中,是不同的命令具有不同的目的,對(duì)應(yīng)不同的邏輯處理,相互之間不可替換。
一個(gè)簡(jiǎn)單的示例:captain是命令的發(fā)起者,soldier是命令的接收者。
start_item finish_item
上節(jié)提到使用uvm_do宏啟動(dòng)sequence,如果宏傳入的第一個(gè)參數(shù)不是uvm_sequence_base類型,就是我們的transaction, 則調(diào)用start_item, finish_item函數(shù)。
start_item()三個(gè)參數(shù),第一個(gè)是傳入的transaction, 第二個(gè)是優(yōu)先級(jí),第三個(gè)是指定該transaction發(fā)送給哪一個(gè)sequencer, transaction掛載在哪一個(gè)sequencer上。
如果之前沒(méi)有給transaction的m_sequencer賦值,此處sequcner仍未null
調(diào)用get_sequencer()函數(shù),將transaction掛載到sequence啟動(dòng)的sequencer上。
transaction必須指定掛載的sequencer, 否者transaction無(wú)法通過(guò)sequencer發(fā)送給driver。而sequence卻不一定需要掛載到sequencer上,因?yàn)閟equence的主要目的是執(zhí)行body函數(shù),直接在tc中調(diào)用seq.start()不指定sequencer,也可以。但是default_sequence的形式必須掛載到sequencer上。
set_item_context()函數(shù)上節(jié)已提到。wait_for_grant()等待sequencer仲裁。pre_do() hook函數(shù)。
在finish_item中,調(diào)用transaction掛載sequencer的函數(shù)send_request(), 這個(gè)函數(shù)定義在uvm_sequencer_param_base中。將transaction放入m_req_fifo容器中。
當(dāng)driver中調(diào)用**seq_item_port.get_next_item(req)**時(shí),實(shí)際調(diào)用的是uvm_sequencer中的get_next_item函數(shù)。從m_req_fifo容器中拿到之前sequence放入的transaction。
driver中的seq_item_port.item_done(),實(shí)際調(diào)用的是uvm_sequencer中的item_done函數(shù)。sequence通過(guò)wait_for_item_done和sequencer的item_done握手,通過(guò)成員變量m_wait_for_item_sequence/transaction_id判斷。每個(gè)sequence, sequence中的每個(gè)transaction其ID都是唯一的。
如果item_done()傳入rsp,調(diào)用put_response函數(shù),與sequence中的get_response配合使用。
start_item/finish_item封裝函數(shù)以及sequence,sequencer,driver的握手關(guān)系如下圖:
結(jié)合命令模式,sequence作為命令的發(fā)起者,sequencer作為接收者。sequence負(fù)責(zé)發(fā)送各種transaction, 至于是哪一個(gè)sequencer接收,由transaction中的成員變量m_sequencer決定。
實(shí)現(xiàn)發(fā)送者與接收者的解耦。設(shè)計(jì)模式側(cè)重應(yīng)用場(chǎng)景,transaction僅僅是事務(wù),不具備命令的實(shí)現(xiàn)行為,所以UVM的實(shí)現(xiàn)并不完全符合命令模式。
UVM中的sequencer更像一個(gè)仲裁者,一邊是driver不斷請(qǐng)求transaction,一邊根據(jù)priority給sequcence授權(quán),接收sequence發(fā)送的transaction,支持lock,grab操作。同時(shí)driver,sequence之間也有聯(lián)系,driver可以response transaction給sequence。
在實(shí)際使用中,建議不要使用宏,而是通過(guò)start()函數(shù)顯示啟動(dòng)sequence, 通過(guò)start_item finish_item發(fā)送transaction。
中介者模式
Mediator Pattern:定義一個(gè)單獨(dú)的(中介)對(duì)象,來(lái)封裝一組對(duì)象之間的交互。將這組對(duì)象之間的交互委派給與中介對(duì)象操作,來(lái)避免對(duì)象之間的直接交互,使耦合松散。
如果不使用中介者模式,各個(gè)系統(tǒng)模塊,或者說(shuō)各個(gè)類之間,互相依賴,就會(huì)形成一個(gè)復(fù)雜的網(wǎng)裝結(jié)構(gòu);使用了中介者模式,系統(tǒng)就變成了結(jié)構(gòu)清晰的星形結(jié)構(gòu)。
UVM中virtual sequence就是一個(gè)典型的中介者模式的使用案列。在virtual sequence中可以統(tǒng)一調(diào)度各個(gè)sequence,負(fù)責(zé)每個(gè)sequence的同步,成員變量賦值,隨機(jī)約束等。中介者模式實(shí)現(xiàn)簡(jiǎn)單,具體示例不在演示。
審核編輯:劉清
-
轉(zhuǎn)換器
+關(guān)注
關(guān)注
27文章
8703瀏覽量
147175 -
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120369 -
耦合器
+關(guān)注
關(guān)注
8文章
725瀏覽量
59712 -
UVM
+關(guān)注
關(guān)注
0文章
182瀏覽量
19171 -
sequence
+關(guān)注
關(guān)注
0文章
23瀏覽量
2848
原文標(biāo)題:UVM設(shè)計(jì)模式 (七)命令模式、三種sequence啟動(dòng)方式、start_item/finish_item、中介模式
文章出處:【微信號(hào):數(shù)字芯片設(shè)計(jì)工程師,微信公眾號(hào):數(shù)字芯片設(shè)計(jì)工程師】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論