最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

UVM基礎(chǔ)-Sequence、Sequencer(一)

2022-12-06 04:13 作者:不吃蔥的酸菜魚  | 我要投稿

目錄

????????Sequence、Sequencer、Driver大局觀

????????Sequence和item

????????????????item與sequence的關(guān)系

????????????????flat sequence

????????????????hierarchical sequence

????????sequence與driver的關(guān)系

????????????????事務(wù)傳輸實例

????????????????????????實例

????????????????????????flat_seq

????????????????事務(wù)傳輸過程分析

????????對于IC驗證的新晉工程師進(jìn)入到一個公司,大概率不會讓你上來就寫驗證環(huán)境,以及驗證環(huán)境的修改。但是會讓你一上來就寫一些sequence,以及一些test。因此,sequence這一部分是很重要的。

Sequence、Sequencer、Driver大局觀

整個序列組件之間的數(shù)據(jù)傳輸可以如下描述:

? ? ? ? ① sequence 對象會產(chǎn)生目標(biāo)數(shù)量的sequence item對象。借助于SV的隨機(jī)化和sequence item對隨機(jī)化的支持,使得產(chǎn)生的每個sequence item對象中的數(shù)據(jù)內(nèi)容都不相同。產(chǎn)生的sequence item會經(jīng)過sequencer再流向driver。

? ? ? ? ② driver陸續(xù)得到每一個sequence item,經(jīng)過數(shù)據(jù)解析,將數(shù)據(jù)按照與DUT的物理接口協(xié)議寫入到接口上,對DUT形成有效激勵。

? ? ? ? ③ 如果需要,driver在解析完一個sequence item后,它可以將最后的狀態(tài)信息歇寫回sequence item對象再返回給sequencer,最終抵達(dá)sequence對象一側(cè)。這樣就可以讓sequence知道driver和DUT互動的狀態(tài)(如果有需要的話)。

? ? ? ? sequence item是driver與DUT每一次互動的最小粒度內(nèi)容。例如DUT如果是一個slave端,driver扮演一個master去訪問DUT的寄存器,那么sequence item需要定義的數(shù)據(jù)信息至少包括訪問地址、命令碼、數(shù)據(jù)和狀態(tài)值,這樣的信息在driver取得后,會通過時序方式在interface一側(cè)發(fā)起激勵送至DUT。? ? ? ??

? ? ? ? 用戶除了可以在聲明sequence item時添加必要的成員變量,也可以添加對這些成員變量進(jìn)行操作的成員方法。這些添加了的成員變量,需要充分考慮在通過sequence傳遞到driver前是否需要隨機(jī)化。

? ? ? ? 對于一個sequence而言,它會產(chǎn)生多個sequence item,也可以產(chǎn)生多個sequence。從產(chǎn)生層次上來看,sequence item是最小粒度,它可以由sequence生成,而相關(guān)sequence也可以進(jìn)一步組織繼而實現(xiàn)層次化,最終由更上層的sequence進(jìn)行調(diào)度。

? ? ? ? sequence與driver之間起到橋梁作用的是sequence。由于sequence和driver均是component組件,它們之間的通信也是通過TLM端口實現(xiàn)的。TLM端口是實現(xiàn)組件和組件之間的通信,driver和sequencer之間的TLM通信參數(shù)是sequence item類。由于這一限制,使得sequencer到driver的傳輸數(shù)據(jù)類型不能改變,同時與sequencer連接的sequence創(chuàng)建的sequence item類型也應(yīng)該為指定類型。?也就是說,sequencer從sequence拿到的item的類型,和sequencer發(fā)送給drver,以及driver接收到的數(shù)據(jù)類型,必須是嚴(yán)格一致的。

? ? ? ? driver不應(yīng)該輕易修改item中的值,它會把item中的數(shù)據(jù)按照與DUT的物理協(xié)議時序關(guān)系驅(qū)動到接口上面。

? ? ? ? ?uvm_component_item和uvm_sequence都是基于uvm_object,它們不同于uvm_component只應(yīng)當(dāng)在build階段作為UVM環(huán)境進(jìn)行創(chuàng)建和配置,而是可以在任何階段創(chuàng)建。

? ? ? ? 由于無法判定環(huán)境在run階段什么時間點會創(chuàng)建sequence和將其產(chǎn)生的sequence item 掛載(attach)到sequencer上面,所以無法通過UVM環(huán)境結(jié)構(gòu)或者phase機(jī)制來識別sequence的運行階段。也正是因為uvm_object是獨立于build階段之外的,所以用戶可以有選擇地、動態(tài)地在合適時間點掛載所需要的sequence和item

? ? ? ? uvm_sequence和uvm_sequence_item不是組件,所以無法通過config_db按照層次關(guān)系對其進(jìn)行配置。因此要用一個trick:sequence一旦活動起來,它必須掛載到一個sequencer上(發(fā)送item),也就是sequence能夠獲取sequencer的句柄,通過句柄來訪問sequencer中的成員變量或等信息,那么這樣sequence可以依賴于sequencer的結(jié)構(gòu)關(guān)系,間接通過sequencer來獲取頂層的配置和更多信息。

????????明確劃分模塊職責(zé)的話,sequence應(yīng)該只負(fù)責(zé)生成item的內(nèi)容, 而不應(yīng)該控制item的時序,而驅(qū)動激勵時序的任務(wù)應(yīng)當(dāng)由driver完成。

sequencer之所以作為一個組件,設(shè)立在sequence和driver之間,主要有兩個原因:

? ? ? ? ① sequencer作為一個組件,它可以通過TLM端口與driver傳送driver對象。

? ? ? ? ② sequencer在面向多個并行sequence時,它有充分的仲裁機(jī)制來合理分配和傳送item,繼而實現(xiàn)并行item數(shù)據(jù)傳送至driver的測試場景。

數(shù)據(jù)傳送機(jī)制:(數(shù)據(jù)傳輸,get還是put)

? ? ? ? 數(shù)據(jù)傳送采用的是get模式不是put模式。如果是put模式,那么應(yīng)該是sequence將數(shù)據(jù)put至driver,而如果是get模式,那么應(yīng)該是driver從sequencer獲取item。

選擇get模式的原因:

? ? ? ? ① 如果是get模式,當(dāng)item從sequence產(chǎn)生,穿過sequencer到達(dá)driver時,我們就可以結(jié)束該傳輸。如果是put模式,則必須是sequencer將item傳送至driver,同時必須收到返回值才可以發(fā)起下一次傳輸,從效率上看,兩者具有差別。

? ? ? ? ② 如果需要讓sequencer具有仲裁特性,可以使得多個sequence同時掛載到sequencer上面,那么get模式更符合設(shè)計。這是因為driver作為initiator,一旦發(fā)出get請求,它會先通過sequencer,然后獲得仲裁后的item

Sequence和item

? ? ? ? sequence指的是uvm_sequence類,而item指的是uvm_sequence_item類,簡稱為sequence和item。item是基于uvm_object類,這表明了它具備UVM核心基類所必要的數(shù)據(jù)操作方法,例如copy()、clone()、compare()、record()等。

item通常應(yīng)該具備一下數(shù)據(jù)成員:

? ? ? ? ① 控制類:總線協(xié)議上的讀寫類型、數(shù)據(jù)長度、傳送模式等。

? ? ? ? ② 負(fù)載類:一般指數(shù)據(jù)總線上的數(shù)據(jù)包。

? ? ? ? ③ 配置類:用來控制driver的驅(qū)動行為,例如命令driver的發(fā)送間隔或者有無錯誤插入。

? ? ? ? ④ 調(diào)試類:用來標(biāo)記一些額外信息方便調(diào)試,例如對象的實例序號,創(chuàng)建時間等。

item使用注意事項:

? ? ? ? ※ 如果數(shù)據(jù)域?qū)儆谛枰脕碜鲵?qū)動,那么用戶應(yīng)考慮定義為rand類型,同時按照驅(qū)動協(xié)議給出合適的constraint。

? ? ? ? ※ 由于item本身的數(shù)據(jù)屬性,為了充分利用UVM域聲明的特性,建議將必要的數(shù)據(jù)成員都通過`uvm_field_automation機(jī)制來聲明,以便后續(xù)uvm_object基本數(shù)據(jù)方法的自動實現(xiàn)。

? ? ? ? ※ UVM要求item的創(chuàng)建和隨機(jī)化都應(yīng)該發(fā)生在sequence的body()任務(wù)中,而不是在sequencer和driver中。

? ? ? ? ※ 按照item的周期來說,它應(yīng)該始于sequence的body()方法,而后經(jīng)過隨機(jī)化,穿越sequencer到達(dá)driver,直到被driver吸收,到此就結(jié)束了。如果要對item進(jìn)行修改數(shù)據(jù),不應(yīng)當(dāng)直接進(jìn)行修改,這會無形的增加item的壽命,正確做法是利用copy或者clone函數(shù)來復(fù)制一份再做處理。

item與sequence的關(guān)系

? ? ? ? 一個sequence可以包含一些有序組織起來的item實例,考慮到item在創(chuàng)建后需要被隨機(jī)化,sequence在聲明時也需要預(yù)留一些可供外部隨機(jī)化的變量。

sequence可以被區(qū)分為常見的三類:

? ? ? ? 扁平類(flat sequence):這一類往往只用來組織更小的粒度,即item實例構(gòu)成的組織。

? ? ? ? 層次類(hierarchical sequence):這一類往往是由更高層的sequence用來組織底層的sequence,進(jìn)而讓這些sequence或者按照順序方式,或者按照并行方式,掛載到同一個sequencer上。

? ? ? ? 虛擬類(virtual sequence):這個類是最重要的,它是最終控制整個測試場景的方式,由于整個環(huán)境中往往存在不用種類的sequencer和其對應(yīng)的sequence,我們需要一個虛擬的sequence來協(xié)調(diào)頂層的測試場景。之所以稱這個方式為virtual sequence,是因為該序列本身并不會固定掛載于某一種sequencer類型上,而是將其內(nèi)部不同類型的sequence最終掛載到不同的目標(biāo)sequencer上面。

flat sequence

一般對于flat sequence而言,它包含的信息有:

? ? ? ? ※ sequence item以及相關(guān)的constraint用來關(guān)聯(lián)生成的item之間的關(guān)系,從而完善出一個flat sequence的時序形態(tài)。

? ? ? ? ※ 除了限制sequence item的內(nèi)容,各個item之間的時序信息也需要由flat sequence給定,例如何時生成下一個item并且發(fā)送至driver。

? ? ? ? ※ 對于需要與driver握手的情況(讀寫操作),或者等待monitor事件從而做出反應(yīng)。都需要相應(yīng)具體事件,從而創(chuàng)建對應(yīng)的item并且發(fā)送出去。

? ? ? ? 在uvm_sequence中寫的task body,當(dāng)sequence掛載到sequencer之后,body任務(wù)會自動運行,就像組件里面的run一樣。

? ? ? ? 上面的代碼,是在flat_sequence中,不斷去new一個bus_trans,然后給他賦值data、addr、write和delay,事實上這樣做的話,flat_sequence不僅要考慮數(shù)據(jù)包的長度和地址,還要考慮數(shù)據(jù)包的內(nèi)容,要做的事情太多了。?

? ? ? ? 我們可以將一段完整發(fā)生在數(shù)據(jù)傳輸中的、更長的數(shù)據(jù)都“收編”在一個bus_trans類中(item 中),提高這個item粒度的抽象層次,一旦有了更成熟的、更合適切割的item,上層的flat sequence在使用過程中也更加方便。

hierarchical sequence

? ? ? ? Hierarchical sequence區(qū)別于flat sequence的地方在于,它可以使用其他sequence,還有item,這么做是為了創(chuàng)建更豐富的激勵場景。

? ? ? ? 通過層次嵌套關(guān)系,可以讓hierarchical sequence使用其他hierarchical sequence、flat sequence和sequence item,如果底層的sequence和item粒度合適,那么就可以充分復(fù)用他們,來實現(xiàn)更為豐富的激勵場景。

? ? ? ? 這里用了uvm_do_with宏,這個宏定義出來,主要做了三件事:① 創(chuàng)建sequence或者item;② 對里面的成員變量進(jìn)行隨機(jī)化; ③ 傳送數(shù)據(jù)到sequencer上。

sequence與driver的關(guān)系

為了便于item傳輸,UVM專門定義了匹配的TLM端口供sequencer和driver使用:

? ? ? ? ※ uvm_seq_item_pull_port #(type REQ=int, type RSP = REQ)

????????※ uvm_seq_item_pull_export #(type REQ=int, type RSP = REQ)

????????※ uvm_seq_item_pull_imp?#(type REQ=int, type RSP = REQ, type imp=int)

由于driver是請求發(fā)起端,所以在driver一側(cè)例化了兩種端口:

? ? ? ? ※ uvm_seq_item_pull_port #(REP, RSP ) seq_item_port

? ? ? ? ※ uvm_analysis_port #(RSP) rsp_port? ?// 專門廣播response的,一對多端口

而sequencer一側(cè)則為請求的響應(yīng)端,在sequencer一側(cè)例化了對應(yīng)的兩種端口:

? ? ? ? ※ uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export

? ? ? ? ※ uvm_analysis_export #(RSP) rsp_export

????????對于第三種sequence部分的端口需要詳解一下,雖然sequence_item_export叫做export,但是它是被定義為imp,也就是TLM傳輸?shù)慕K點。而sequence作為TLM通信數(shù)據(jù)傳輸?shù)慕K點,為什么要給uvm_analysis端口定義為export呢?因為在我們的理解中,export是TLM通信數(shù)據(jù)傳輸?shù)闹虚g節(jié)點而不是終點。這是因為uvm_analysis端口內(nèi)置了一個存儲RSP的FIFO,而FIFO上是有imp端口的,因此uvm_analysis端口的export接到內(nèi)置的FIFO的imp端口上就形成了終點。這也是為什么我們成sequencer就是TLM通信傳輸?shù)慕K點的原因。

? ? ? ? 顯然,從上面我們可以看到,sequence和driver的各自的兩個端口其實是和對方的端口成對的。uvm_seq_item_pull_port #(REP, RSP ) seq_item_port 和?uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export成對;uvm_analysis_port #(RSP) rsp_port 和?uvm_analysis_export #(RSP) rsp_export成對。因此需要在connect_phase中將端口進(jìn)行連接。

????????通常情況下,只需要連接 driver::seq_item_portsequence::seq_item_export 就行了。即在connect_phase中通過:driver::seq_item_port.connect(sequencer::seq_item_export) 完成。這一對端口功能主要用來實現(xiàn)driver與sequence的request獲取和response返回。

seq_item_port可以調(diào)用很多方法:

? ? ? ? ※ task get_next_item(output REQ req_arg): 采取blocking的方式等待從sequenne獲取下一個item。

? ? ? ? ※ task try_next_item(output REQ reg_arg): 采取nonblocking的方式從sequence獲取item,如果立即返回的結(jié)果req_arg為null,則表示sequence還沒有準(zhǔn)備好。

? ? ? ? ※ function void item_done(input RSP rsp_arg=null): 用來通知sequence當(dāng)前的sequence item已經(jīng)消化完畢,可以選擇性的傳遞RSP參數(shù),返回狀態(tài)值。

? ? ? ? ※ task wait_for_sequence(): 等待當(dāng)前的sequence直到產(chǎn)生下一個有效的item。此任務(wù)往往和try_next_item一起使用。

? ? ? ? ※ function bit has_do_available(): 如果當(dāng)前的sequence準(zhǔn)備好而且可以獲取下一個有效的item,則返回1,否則返回0。

? ? ? ? ※ function void put_response(input RSP rsp_arg): 采取nonblocking方式發(fā)送response,如果成功則返回1,否則返回0。

????????平時用的比較多的任務(wù)和方法,就是上面加粗的任務(wù)和方法。

????????driver消化完當(dāng)前的request后,可以通過item_done(input RSP rsp_arg=null)方法來告知sequence 此次傳輸已經(jīng)結(jié)束,參數(shù)中的RSP可以選擇填入,返回相應(yīng)的狀態(tài)值。

事務(wù)傳輸實例

實例

? ? ? ? 在sequence發(fā)送item的時候,就會給item記錄一個sequence_id,表示該item是由哪個sequence發(fā)送的,這樣在一個sequencer同時收到兩個不同的sequence發(fā)送的item,然后發(fā)送給driver,driver再返回這兩個item的response給sequencer,讓sequencer把對應(yīng)的response送給對應(yīng)的sequence,就需要利用這個sequence_id。rsp.set_sequence_id(req.get_sequence_id())這個就是通過獲取request的id,給response,來保證發(fā)送對應(yīng)request的sequence能得到對應(yīng)自己的response。

? ? ? ? sequence_id不做域的自動化的話,在使用clone函數(shù)的時候是不會進(jìn)行clone的,默認(rèn)為0。

注意一下,在聲明drvier和sequence時,沒有給他們下類型的定義,所以默認(rèn)是sequence_item類型,屬于父類的句柄,因此在get_next_item之后,需要將父類的句柄轉(zhuǎn)換成子類的句柄,這步可以通過在聲明class時,定義類型#(RSP)來改變。但是req.clone()獲得的句柄默認(rèn)是uvm_object類型,因此必須通過父類到子類的轉(zhuǎn)換。

flat_seq

flat_seq作為動態(tài)創(chuàng)建的數(shù)據(jù)生成載體,它的主任務(wù)flat_seq::body()做了如下的幾件事情:

? ? ? ? ※ 通過方法create_item()創(chuàng)建了request item對象;

? ? ? ? ※ 調(diào)用start_item()準(zhǔn)備發(fā)送item;

? ? ? ? ※ 在完成發(fā)送item之前對item進(jìn)行隨機(jī)處理;

? ? ? ? ※ 調(diào)用finish_item()完成item發(fā)送;

? ? ? ? ※ 有必要的情況下,可以從driver處獲得response item。

事務(wù)傳輸過程分析

在定義driver時,它的主任務(wù)driver::run_phase()需要做如下處理:

? ? ? ? ① 通過seq_item_port.get_next_item(REQ)從sequencer獲取有效的request item。

? ? ? ? ② 從request item中獲取數(shù)據(jù),進(jìn)而產(chǎn)生數(shù)據(jù)激勵。

? ? ? ? ③ 對request item進(jìn)行克隆生成新的對象response item。

? ? ? ? ④ 修改response item中的數(shù)據(jù)成員,最終通過seq_item_port.item_done(RSP)將response item對象返回給sequence

????????對于uvm_sequence::get_response(RSP)和uvm_driver::item_done(RSP)這種成對的操作,是可選的,可以選擇獲取或者不獲取,但是要成對出現(xiàn)。

????????在高層環(huán)境中,應(yīng)該在connect_phase中完成driver到sequencer的TLM端口連接,比如上面代碼中env::connect_phase()中通過drv.seq_item_port.connect(sqr.seq_item_export)完成了driver與sequencer之間的連接。

? ? ? ? 在完成了flat_seq、sequencer、driver、env的定義之后,到了test1層,需要考慮掛起objection防止仿真在run_phase的時候提前退出。

? ? ? ? 使用uvm_sequence::start(SEQUENCER)來完成sequence到sequencer的掛載操作。當(dāng)多個sequence試圖掛載到同一個sequencer時,需要在sequencer上添加仲裁功能

? ? ? ? 在sequence創(chuàng)建item之前,首先需要將sequence掛載到sequencer上,上面整個sequence從create_item到最后和driver握手成功的get_response的運作都在sequence的body()中。Driver的get_next_item到item_done都在driver的run_phase()中。

? ? ? ? sequencer做仲裁,是在driver發(fā)起get_next_item()時,才開始仲裁選擇哪個item。如果只有一個sequence掛載到sequencer上,那直接用就行了。在sequencer將通過的權(quán)限交給某一個底層的sequence之前,目標(biāo)sequence中的item應(yīng)該完成隨機(jī)化,繼而在獲取sequencer的通過權(quán)限后,執(zhí)行finish_item()。

? ? ? ? finish_item()會等到driver發(fā)揮item_done()才會結(jié)束。

對每個item而言,它起始于create_item(),繼而通過start_item()嘗試從sequencer獲取可以通過的權(quán)限。如果driver沒有了item可用,將調(diào)用get_next_item()來嘗試從sequencer一側(cè)獲取item。

? ? ? ? 為了統(tǒng)一起見,用戶可以不在定義sequencer或者driver時指定sequence item類型, 使用默認(rèn)的REQ = uvm_sequence_item,但是用戶需要注意在driver一側(cè)的類型轉(zhuǎn)換,例如對get_next_item(REQ)的返回值REQ句柄做出動態(tài)類型轉(zhuǎn)換,等到正確類型之后再進(jìn)行接下來的操作。


UVM基礎(chǔ)-Sequence、Sequencer(一)的評論 (共 條)

分享到微博請遵守國家法律
永吉县| 阿巴嘎旗| 大田县| 会泽县| 海淀区| 大姚县| 南川市| 肥乡县| 筠连县| 阿尔山市| 宿迁市| 西安市| 庆云县| 习水县| 德阳市| 新宁县| 全州县| 会同县| 常州市| 乌鲁木齐市| 甘洛县| 永修县| 阿克苏市| 监利县| 昌黎县| 合江县| 宁强县| 即墨市| 曲周县| 长春市| 剑川县| 潼关县| 夏河县| 普安县| 斗六市| 北流市| 齐齐哈尔市| 遵义县| 胶州市| 峨边| 黄陵县|