一、m_sequencer
1、什么是m_sequencer
m_sequencer是定義在uvm_sequencer_item中的,uvm_sequencer_base型別的句柄,也就是說
- m_sequencer是uvm_sequencer_item的成員變數
- m_sequencer是指向uvm_sequencer_base的句柄
- 任何派生于uvm_sequencer_item的類都會擁有一個m_sequencer
m_sequencer原始碼如下:
class uvm_sequence_item extends uvm_transaction;
...
protected uvm_sequencer_base m_sequencer;
...
endclass
m_sequencer在類別庫中的關系如下圖紫色箭頭所示:

2、為什么要有m_sequencer
sequence屬于object,sequencer屬于component,
正常來說,sequence無法與sequencer進行互動,也不可能通過component的結構層次獲得頂層配置及其他資訊,因此需要一個能溝通sequence和sequencer的橋梁,m_sequencer就是這個橋梁,
3、怎么使用m_sequencer
通常呼叫uvm_do系列宏時,uvm能夠自動根據傳入的sequence或sequence_item呼叫對應的方法,使m_sequencer由指向uvm_sequencer_base,變為指向用戶指定的sequencer,(例如類別庫中的your_sequencer),如下圖藍色虛線將變為紫色實線,

由此搭建了sequence和sequencer的橋梁,呼叫其他方法同理(不管是什么方法,沒有改變m_sequencer指向給定的sequencer這一本質),
因此使用者只需要呼叫所需方法,有關于m_sequencer的使用由uvm自動完成了,
值得注意的一點是用戶指定的sequencer是uvm_sequencer_base的子類,對于m_sequencer而言,此時是父類句柄指向了子類物件,這也為下面的動態轉換打下了基礎,
二、p_sequencer
1、什么是p_sequencer
p_sequencer是由`uvm_decalre_p_sequencer宏,定義在用戶指定的sequence(例如類別庫中的your_sequence)中的,用戶指定的型別的句柄(例如類別庫中的your_sequencer),也就是說
- p_sequencer是由uvm_decalre_p_sequencer宏產生的
- p_sequencer是用戶指定的sequence的成員變數(這里是your_sequence的成員變數,因為`uvm_decalre_p_sequencer宏是在your_sequence中使用的)
- p_sequencer是指向用戶指定的型別的句柄(這里是your_sequencer的成員變數)
p_sequencer源代碼如下:
`define uvm_declare_p_sequencer(SEQUENCER)
SEQUENCER p_sequencer; //SEQUENCER是由用戶指定的型別
virtual function void m_set_p_sequencer();
super.m_set_p_sequencer(); //父類的m_set_p_sequencer是空函式
if (!$cast(p_sequencer, m_sequencer))
`uvm_fatal("DCLPSQ", $sformatf("%m %s Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer", get_full_name()))
endfunction
可能到這里還是有些抽象,接下來我們進行一個更為形象的說明,
2、為什么需要p_sequencer
在sequence機制中,sequence就像是一個快遞,它可以裝入商品(sequence_itm),也可以裝入另一個快遞(sequence);sequencer就像是商家,他把快遞交給物流公司(driver),物流公司再把快遞交給用戶(DUT),
當有很多個快遞時,物流公司怎么知道把哪個快遞交給哪個用戶呢,這就需要商家給快遞上注明識訓人和發貨人的資訊(your_sequencer中的dmac和smac等),
也就是說your_sequence要訪問your_sequencer中的成員變數dmac和smac,雖然這是your_sequence中的m_sequencer經過呼叫`uvm_do后已經指向了your_sequencer,但此時他的型別還是uvm_sequencer_base,而uvm_sequencer_base是your_sequencer的父類,父類句柄直接訪問子類物件是不允許的,
因此我們需要將m_sequencer的型別轉換成子型別別(也就是your_sequencer),
首先我們在your_sequencer中宣告了一個your_sequencer型別的句柄x_sequencer,再將m_sequencer動態轉換成子類句柄,這樣your_sequence就可以訪問your_sequencer的成員變數了,
代碼如下:
class your_sequence extends uvm_sequence #(your_transaction);
your_trasaction your_trans;
`uvm_object_utils(your_squence)
...
virtual task body();
your_sequencer x_sequencer;//宣告x_sequencer
...
$cast(x_sequencer,m_sequencer);//動態轉換
...
repeat(10)
begin
`uvm_do_with(m_trans,{your_trans.dmac==x_sequencer.dmac;
your_trans.smac==x_sequencer.smac;})//訪問your_sequencer中的變數
end
...
endclass
如此一來,快遞(your_sequence)上就有了一個標明了識訓發貨資訊(dmac和smac)的快遞面單,物流公司(driver)就可以按照快遞單來派送了,
但是每次都需要通過宣告x_sequencer,再動態轉換就像人工手寫快遞面單一樣繁瑣,因此uvm將上述程序封裝成立宏`uvm_declare_p_sequencer,以后就可以自動列印快遞面單了
3、怎么使用p_sequencer
只需要在你需要的sequence中呼叫宏uvm_declare_p_sequencer(SEQUENCER) ,uvm將自動做以下事情:
- 宣告一個x_sequencer,指向SEQUENCER(這里your_sequencer),
- 將m_sequencer動態轉換成子類句柄,
你所需要做的只是考慮需要把哪些資訊列印到快遞面單上了,
參考資料
1.《UVM實戰 卷Ⅰ》 張強著
2.《芯片驗證漫游指南——從系統理論到UVM的驗證全視界》劉斌著
3. 芯片驗證面試必考題:m_sequencer?與p_sequencer的區別是什么?https://zhuanlan.zhihu.com/p/436911218
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/545104.html
標籤:其他
上一篇:python--高級語法
