0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

UVM設(shè)計(jì)模式之訪問者模式

rfdqdzdg ? 來源:IC Verification Club ? 2023-08-11 09:28 ? 次閱讀

訪問者模式

Visitor Pattern:允許一個(gè)或者多個(gè)操作應(yīng)用到一組對(duì)象上,解耦操作和對(duì)象本身。換言之,如果component的數(shù)據(jù)結(jié)構(gòu)是比較穩(wěn)定的,但其是易于變化的,那么使用訪問者模式是個(gè)不錯(cuò)的選擇。

常見的訪問者模式有五種角色:

(1) Vistor(抽象訪問者):為該對(duì)象結(jié)構(gòu)中具體元素角色聲明一個(gè)訪問操作接口。

(2) ConcreteVisitor(具體訪問者):每個(gè)具體訪問者都實(shí)現(xiàn)了Vistor中定義的操作。

(3) Element(抽象元素):定義了一個(gè)accept操作,以Visitor作為參數(shù)。

(4) ConcreteElement(具體元素):實(shí)現(xiàn)了Element中的accept()方法,調(diào)用Vistor的訪問方法以便完成對(duì)一個(gè)元素的操作。

(5) ObjectStructure(對(duì)象結(jié)構(gòu)):可以是組合模式,也可以是集合;能夠枚舉它包含的元素;提供一個(gè)接口,允許Vistor訪問它的元素。

舉例:老師教學(xué)反饋得分大于等于85分或者學(xué)生成績大于等于90分,則可以獲得優(yōu)秀獎(jiǎng);如果老師論文數(shù)目大于等于2、學(xué)生論文數(shù)目大于等于1,則可以獲得1萬元的現(xiàn)金。在這個(gè)例子中,老師和學(xué)生就是Element,他們的數(shù)據(jù)結(jié)構(gòu)穩(wěn)定不變。從上面的描述中,我們發(fā)現(xiàn),對(duì)數(shù)據(jù)結(jié)構(gòu)的操作是多變的,一會(huì)兒評(píng)選成績,一會(huì)兒評(píng)選科研,這樣就適合使用訪問者模式來分離數(shù)據(jù)結(jié)構(gòu)和操作。

兩種操作,class GradeSelection class ResearchSelection 重寫實(shí)現(xiàn) visit()函數(shù)

wKgZomTVjwWAXK5iAAP4jI4N2fo731.jpg

class Teacher class Studnet中調(diào)用 visitor.visit(),不需要特別指明哪一種操作。

wKgaomTVjwWABPsSAATFa5DiKuA798.jpg

wKgZomTVjwWAPhBgAAPaxF8B9gc262.jpg

訪問者模式適用于對(duì)一組結(jié)構(gòu)固定的組件統(tǒng)一地加入一個(gè)新的操作,如上例,將student1,student2,teacher1,teacher2這四個(gè)共同屬性(都繼承于Element)的組件,加入ObjectStructure中,此例中的組件關(guān)系是前后線性的關(guān)系,依次加入element_q隊(duì)列中。當(dāng)需要對(duì)所有組件執(zhí)行researchselection操作時(shí),ObjectStructure調(diào)用accept(researchselection)即可,會(huì)自動(dòng)遍歷各個(gè)組件執(zhí)行這個(gè)researchselection的操作。如果需要切換其他操作,只需更改ObjectStructure中accept的參數(shù)即可。添加新的操作也很方便,不需要更改組件,只需要在外部重寫visitor()函數(shù),具有很好的擴(kuò)展性,實(shí)現(xiàn)組件與操作的解耦。

UVM_PHASE

UVM的環(huán)境具有明確的結(jié)構(gòu),各個(gè)組件統(tǒng)一繼承于uvm_component, 組成 ** tree structure** 。每個(gè)子類component重寫各個(gè)phase函數(shù),每個(gè)component中的phase函數(shù)相當(dāng)于visitor(),很符合使用訪問者模式的條件。但是uvm的phase機(jī)制實(shí)現(xiàn)和上述介紹的示例還有很大區(qū)別,component中的phase是在自身內(nèi)部實(shí)現(xiàn)的,而不是放在類外部;對(duì)于執(zhí)行同一個(gè)phase,樹形結(jié)構(gòu)中的component不是簡單的依次執(zhí)行,有top-down,down-top和并行執(zhí)行;對(duì)于同一個(gè)componet中的phase, 有不消耗時(shí)間的function phase, 也有消耗時(shí)間的task phase, 有依次執(zhí)行的,也有并列執(zhí)行的(run_phase和12個(gè)run-time phase)。所以存在兩個(gè)維度,一個(gè)uvm_component的維度,根據(jù)單例模式中的parent-child關(guān)系構(gòu)建了樹狀結(jié)構(gòu);一個(gè)phase維度,將每個(gè)phase以node的形式放入domain中,統(tǒng)一調(diào)度。UVM還支持objection機(jī)制,drain_time,timeout,多domain,進(jìn)程同步,phase的jump,phase_debug等操作,所以簡單的訪問者模式無法滿足要求。

下面根據(jù)源碼對(duì)uvm_phase從這兩個(gè)維度分析:

1. phase的執(zhí)行順序

在第二篇,提到了uvm_root中函數(shù)run_test()根據(jù)工廠模式創(chuàng)建testcase的實(shí)例。接下來run_test()調(diào)用uvm_phase中的靜態(tài)函數(shù)m_run_phase()開始執(zhí)行各個(gè)phase。這里用到了SV內(nèi)建的class process,提供了精細(xì)控制進(jìn)程的方法。

uvm_domain調(diào)用靜態(tài)函數(shù)get_common_domain(), 從名字上可以看到這是獲得一個(gè)domain。uvm_domain繼承于uvm_phase,是phase的一個(gè)容器。

comon_domain調(diào)用add函數(shù)依次加入不消耗時(shí)間的function phase, 一共9個(gè)。第一個(gè)uvm_build_phase::get()獲得build_phase的實(shí)例,uvm_build_phase和uvm_root一樣采用了單例模式,所以全局只有一個(gè)build_phase,通過 uvm_build_phaes::get()獲得。所以我們平常在不同component中的wKgZomTVjwWAGfyNAAADG_EH5-w724.jpg傳入的phase,其實(shí)指向的都是那個(gè)唯一的uvm_build_phaes::get() 實(shí)例。其他phase也一樣,實(shí)例全局唯一。

add()函數(shù)實(shí)現(xiàn)了將不同phase以node的形式加入,node有predecessor,successor的概念,構(gòu)成鏈表結(jié)構(gòu)。類似component中parent,child的關(guān)系,構(gòu)成樹狀結(jié)構(gòu)。根據(jù)add加入的順序,組織了先后順序。所以connect_phase_node的predecessor是build_phase_node, successor是end_of_elaboration_phase.

get_uvm_domain()獲得另一個(gè)domain:uvm_domain。uvm_domain中加入的是task phase, 一共12個(gè)。然后common_domain再將uvm_domain和run_phase同時(shí)加入,實(shí)現(xiàn)rum_phase和12個(gè)小phase組成的run-time phase并行執(zhí)行。

到此,各個(gè)phase的執(zhí)行順序就固定了。如果沒有單獨(dú)創(chuàng)建domain,那么只有common_domain和uvm_domain這兩個(gè)domain會(huì)被默認(rèn)創(chuàng)建。結(jié)構(gòu)如下:

wKgaomTVjwWAAe5uAAAujlqzaBQ086.jpg

回到m_run_phases(), 有一個(gè)forever begin ... end一直循環(huán)從m_phae_hopper.get()獲得phase執(zhí)行exectute_phase()。最開始m_phase_hopper( 一個(gè)放入uvm_phase類型的mailbox)放入的是common domain,common domain執(zhí)行完畢后,會(huì)將successor build phase 放入m_phase_hopper中;在forever循環(huán)中m_phae_hopper.get()獲得build phase,執(zhí)行完build phase最后會(huì)放入build phase的successor connect phase,直到遍歷完所有phase。

wKgaomTVjwWAcRRiAAbbZswg0Wg714.jpg

2. component的執(zhí)行順序

接上面,phase.execute_phase()的具體實(shí)現(xiàn)會(huì)根據(jù)不同的uvm_phase_type和uvm_phase_state走不同的分支。
uvm_build_phase, uvm_final_phase繼承于uvm_topdown_phase, 其余function phase繼承于uvm_downtop_phase, task phase繼承于uvm_task_phase。

對(duì)于build_phase, 函數(shù)exectue_phase會(huì)調(diào)用m_imp.traverse(top,this,UVM_PHASE_EXECUTING), traverse()函數(shù)在uvm_topdown_phase中定義,build_phase從top to down的執(zhí)行順序也是在這里實(shí)現(xiàn)的。

最開始traverse傳入的是top,也就是最頂層uvm_root,②處調(diào)用get_first_child獲得uvm_test_top(在之前的run_test中已被創(chuàng)建),遞歸調(diào)用traverse函數(shù),執(zhí)行ph.execute(uvm_test_top, phase), 實(shí)際調(diào)用的是comp.build_phase, 也就是uvm_test_top的 builde_phase()。builde_phase會(huì)創(chuàng)建uvm_test_top的child env。執(zhí)行完ph.exectute,再次執(zhí)行traverse函數(shù),此時(shí)傳入的component是env, 執(zhí)行env的build_phase,創(chuàng)建env的child agt。一直遞歸循環(huán),實(shí)現(xiàn)所有component的創(chuàng)建。

對(duì)于繼承uvm_downtop_phase的phase,則是從底部開始循環(huán)。相比uvm_topdowun_phase,將遞歸函數(shù)traverse放在ph.execute前面,便實(shí)現(xiàn)了down to top的順序。

對(duì)于繼承uvm_task_phase的函數(shù),雖然遞歸函數(shù)traverse放在ph.execut前面,也是down to top的順序,但是fork ... join_none讓不同component的同一種phase函數(shù)在不同process上同時(shí)執(zhí)行,實(shí)際效果是一塊同時(shí)運(yùn)行的。

所以對(duì)于component中phase的執(zhí)行遍歷,是根據(jù)調(diào)用遞歸函數(shù)遍歷child完成的。在uvm_root中的find()函數(shù),也是遞歸調(diào)用函數(shù)完成遍歷。

wKgZomTVjwWAS7mgAAS-62PXmPY160.jpg

uvm objection

uvm objection涉及對(duì)進(jìn)程的控制,先介紹一下systemverilog提供的class process。(計(jì)算機(jī)體系中的進(jìn)程,線程和內(nèi)核的調(diào)度有關(guān),而仿真平臺(tái)是跑在仿真軟件上的,由 simulation kernel進(jìn)行調(diào)度 (IEEE 4.Scheduling semantics clause) 按照時(shí)間片執(zhí)行,以下進(jìn)程,線程不做區(qū)分,統(tǒng)一叫做進(jìn)程)

SV中的fork相關(guān)函數(shù)可以創(chuàng)建新的進(jìn)程,但是對(duì)于進(jìn)程的管理, 只有 wait fork, disable identifier, disable fork這些。其他語言中一般都有專門管理進(jìn)程的操作方法,比如python中的multiprocessing模塊。所以SV中加入了一個(gè)class process,提供了更精細(xì)的進(jìn)程管理。class process并不可以用于創(chuàng)建進(jìn)程,只可以在initial begin ..end,always,fork等創(chuàng)建進(jìn)程的語句中通過process::self()獲取該進(jìn)程;status()獲得進(jìn)程狀態(tài),kill()終止進(jìn)程及子進(jìn)程,suspend()掛起進(jìn)程,resume()恢復(fù)進(jìn)程,srandom(int seed)設(shè)置進(jìn)程的隨機(jī)種子。

wKgaomTVj4CALdYIAAEIbLqVg_E132.png

uvm objection機(jī)制的源代碼實(shí)現(xiàn)不再探究,總結(jié)需要注意的幾點(diǎn):

每個(gè)phase的實(shí)例是唯一的,每個(gè)phase在創(chuàng)建的時(shí)候,自動(dòng)創(chuàng)建了屬于這個(gè)phase的objection。

對(duì)于消耗時(shí)間的task phase,其中必須raise_objection, 才會(huì)執(zhí)行,否者直接退出。

對(duì)于同一個(gè)phase,可以多次raise_objection, 但是raise_objection和drop_objection必須成對(duì)存在。只有raise數(shù)量等于dorp數(shù)量時(shí)才會(huì)退出這個(gè)phase。

raise_objection前面不可以有消耗時(shí)間的語句,也就是剛進(jìn)入phase的0時(shí)刻,就需要檢測(cè)到raise_objection, 否則直接退出這個(gè)phase。

對(duì)于run_phase和并行的12個(gè)task phase, 如果在run_phase中raise_objection,但是main_phase沒有raise_obejection,那么main_phase直接退出。如果在main_phase有raise_obejection,run_phase沒有raise_objection,run_phase也會(huì)執(zhí)行。所以盡量run_phase和12個(gè)小phase不要同時(shí)使用,以免出錯(cuò)。

通過簡單的代碼使用process來實(shí)現(xiàn)一下UVM中的objection:

wKgZomTVjwWAENP5AARqjCWBZ8g517.jpg

do_monitor是一個(gè)無線循環(huán),在driver_main_phase中控制objection的raise和drop。

如果line42加上時(shí)間延遲,則會(huì)直接退出main_phase,進(jìn)入下一個(gè)phase. 如果注釋掉line43行也是直接退出main_phase,進(jìn)入下一個(gè)phase. 打印結(jié)果:wKgaomTVjwWATLxdAAATba_m2Ds400.jpg

如果加上line49, line51,main_phase則無法退出。打印結(jié)果:

wKgZomTVjwWAUiZZAAA-ljRw7AA642.jpg

uvm_visitor

UVM1.2中新加入了訪問者模式的基礎(chǔ)類,供使用者擴(kuò)展使用:

wKgaomTVjwWAKXaQAADU-MZJQ_U947.jpg

uvm_visitor:提供了visit()方法,以及begin_v(),end_v()兩個(gè)hook。

重寫visit方法,簡單的打印component的full_name.

wKgaomTVjwaAV5q7AAL93lM6eUY809.jpg

uvm_visitor_adapter:提供了accept函數(shù),用于實(shí)現(xiàn)visitor和component的連接,并對(duì)每個(gè)component調(diào)用visti方法。

wKgZomTVjwaAVjYWAAJoT_UIhnk179.jpg

env中創(chuàng)建visitor, adapter的實(shí)例,accept傳入的是env這個(gè)comonent,打印處uvm_test_top.env

wKgaomTVjwaAUyJpAAKGV5G3qHs181.jpg

對(duì)于component的組織調(diào)用順序,用戶可以自定義structure。UVM提供了三種sturcture, 對(duì)應(yīng)的adapter,如下:

wKgZomTVjwWAKRriAAEwQB7-9ww049.jpg

使用的top to down的structure, 從上到下遍歷component調(diào)用visit()函數(shù):

wKgZomTVjwaAFHhqAAYGE2BylyQ650.jpg

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:UVM設(shè)計(jì)模式 (六)訪問者模式、uvm_phase、uvm objection、process control

文章出處:【微信號(hào):數(shù)字芯片設(shè)計(jì)工程師,微信公眾號(hào):數(shù)字芯片設(shè)計(jì)工程師】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    數(shù)字IC驗(yàn)證“什么是UVM”“UVM的特點(diǎn)”“UVM提供哪些資源”(2)連載中...

    會(huì)在一定范圍內(nèi)產(chǎn)生,減少無用的激勵(lì),提高效率。支持覆蓋率驅(qū)動(dòng)模式,根據(jù)當(dāng)前覆蓋率的情況,驗(yàn)證工程師可以決定下一步的驗(yàn)證內(nèi)容,當(dāng)覆蓋率達(dá)到了一定的要求時(shí),就可以宣告驗(yàn)證工作的完成。uvm驗(yàn)證平臺(tái),它具有很高的可重用性
    發(fā)表于 01-21 16:00

    Java設(shè)計(jì)模式分析觀察

    觀察模式的流程跟報(bào)紙訂閱方式一致,即:觀察模式=出版+訂閱,只是名稱不一樣,出版
    發(fā)表于 09-26 17:36 ?0次下載

    Java設(shè)計(jì)模式(二十一):中介模式

    中介模式(Mediator Pattern) 中介模式(Mediator Pattern): 屬于對(duì)象的行為模式。又叫調(diào)停
    發(fā)表于 01-24 11:28 ?311次閱讀

    UVMsequence/item見解 sequencer特性及應(yīng)用(下)

    _SEQ_ARB_WEIGHTED;UVM_SEQ_ARB_RANDOM ;UVM_SEQ_ARB_STRICT_FIFO等。出其中三種需要特別區(qū)分外其它的模式可以滿足絕大多數(shù)的仲裁需求。
    的頭像 發(fā)表于 02-19 10:14 ?4807次閱讀
    談<b class='flag-5'>UVM</b><b class='flag-5'>之</b>sequence/item見解 sequencer特性及應(yīng)用(下)

    嵌入式軟件設(shè)計(jì)設(shè)計(jì)模式

    文章目錄前言1.設(shè)計(jì)模式適配器模式2.設(shè)計(jì)模式單例模式3.設(shè)計(jì)
    發(fā)表于 10-21 11:07 ?9次下載
    嵌入式軟件設(shè)計(jì)<b class='flag-5'>之</b>設(shè)計(jì)<b class='flag-5'>模式</b>

    配置Nginx訪問日志

    每當(dāng)處理客戶請(qǐng)求時(shí),Nginx都會(huì)在訪問日志中生成一個(gè)新記錄。每個(gè)事件記錄都包含一個(gè)時(shí)間戳,并包含有關(guān)客戶端和所請(qǐng)求資源的各種信息。訪問日志可以顯示訪問者的位置,訪問者
    的頭像 發(fā)表于 05-24 09:59 ?2327次閱讀

    嵌入式軟件設(shè)計(jì)模式 好文值得收藏

    本文引用自本人公眾號(hào)文章: 嵌入式開發(fā)中的兩點(diǎn)編程思想 ? C語言也很講究設(shè)計(jì)模式?一文講透 ? 包含如下: 01)C語言和設(shè)計(jì)模式(繼承、封裝、多態(tài)) ? 02)C語言和設(shè)計(jì)模式訪問者
    的頭像 發(fā)表于 06-20 09:09 ?1971次閱讀

    GoF設(shè)計(jì)模式訪問者模式

    訪問者模式的目的是,解耦數(shù)據(jù)結(jié)構(gòu)和算法,使得系統(tǒng)能夠在不改變現(xiàn)有代碼結(jié)構(gòu)的基礎(chǔ)上,為對(duì)象新增一種新的操作。
    的頭像 發(fā)表于 10-08 11:05 ?693次閱讀

    設(shè)計(jì)模式訪問者設(shè)計(jì)模式

    訪問者設(shè)計(jì)模式是一種行為型設(shè)計(jì)模式,用于將算法與對(duì)象結(jié)構(gòu)分離。它允許你在不改變對(duì)象結(jié)構(gòu)的前提下定義新的操作。
    的頭像 發(fā)表于 06-06 11:25 ?820次閱讀

    設(shè)計(jì)模式行為型:訪問者模式

    訪問者模式(Visitor Pattern)中,我們使用了一個(gè)訪問者類,它改變了元素類的執(zhí)行算法。
    的頭像 發(fā)表于 06-07 15:11 ?762次閱讀
    設(shè)計(jì)<b class='flag-5'>模式</b>行為型:<b class='flag-5'>訪問者</b><b class='flag-5'>模式</b>

    設(shè)計(jì)模式行為型:觀察模式

    定義對(duì)象之間的一種一對(duì)多依賴關(guān)系,使得每一個(gè)對(duì)象發(fā)生狀態(tài)的變化時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新,又稱為發(fā)布-訂閱模式、模型-視圖模式、源-監(jiān)聽器模式或從屬
    的頭像 發(fā)表于 06-07 16:56 ?678次閱讀
    設(shè)計(jì)<b class='flag-5'>模式</b>行為型:觀察<b class='flag-5'>者</b><b class='flag-5'>模式</b>

    設(shè)計(jì)模式創(chuàng)造性:建造模式

    建造模式(Builder Pattern)使用多個(gè)簡單的對(duì)象一步一步構(gòu)建成一個(gè)復(fù)雜的對(duì)象。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。
    的頭像 發(fā)表于 06-09 16:25 ?736次閱讀
    設(shè)計(jì)<b class='flag-5'>模式</b>創(chuàng)造性:建造<b class='flag-5'>者</b><b class='flag-5'>模式</b>

    一文詳解UVM設(shè)計(jì)模式

    本篇是對(duì)UVM設(shè)計(jì)模式 ( 二 ) 參數(shù)化類、靜態(tài)變量/方法/類、單例模式、UVM_ROOT、工廠模式、
    的頭像 發(fā)表于 08-06 10:38 ?1838次閱讀
    一文詳解<b class='flag-5'>UVM</b>設(shè)計(jì)<b class='flag-5'>模式</b>

    行為型設(shè)計(jì)模式UVM中的應(yīng)用

    接下來介紹行為型設(shè)計(jì)模式UVM中的應(yīng)用。
    的頭像 發(fā)表于 08-09 14:01 ?718次閱讀
    行為型設(shè)計(jì)<b class='flag-5'>模式</b>在<b class='flag-5'>UVM</b>中的應(yīng)用

    迭代模式UVM中的應(yīng)用有哪些

    行為型設(shè)計(jì)模式數(shù)量較多,上一篇介紹了模板模式和策略模式,下面對(duì)迭代模式進(jìn)行介紹,挖掘其在UVM中的應(yīng)用。
    的頭像 發(fā)表于 08-14 17:15 ?622次閱讀
    迭代<b class='flag-5'>模式</b>在<b class='flag-5'>UVM</b>中的應(yīng)用有哪些