一般UVM環境中的Driver組件,派生自uvm_driver。
uvm_dirver派生自uvm_component。
class uvm_driver #(type REQ = uvm_sequence_item, type RSP = REQ) extends uvm_component
其中定義了兩個Ports:seq_item_port,driver一般用這個接口向sequencer索要sequence。
rsp_port,driver向相應的sequencer發送response。
還有一個new函數,再無其他。
driver內部通過調用get函數來向sequencer索要transaction
相應的uvm_sequencer,派生自uvm_sequencer_param_base,繼而派生自uvm_sequencer_base。
class uvm_sequencer #(type REQ=uvm_sequence_item, RSP=REQ) extends uvm_sequencer_param_base (#REQ,RSP)
定義有一個seq_item_export。提供訪問這個sequencer的接口實現。
uvm_seq_item_pull_imp #(REQ,RSP,this_type) seq_item_export
其中接口的類型是uvm_sqr_if_base #(REQ,RSP)。
它實現的方法有:get_next_item/try_next_item,先在該sequencer中選擇優先級最高的sequence,然后該sequence wait_for_grant,
然后uvm_sequence_base::pre_do,randomized,post_do。
item_done,一旦上一個task被調用,那這個task也必須被調用。表示一個sequence結束,fifo可以移出。
Driver中在得到sequence后,需要將sequence變為DUT能夠接收的信號類型。
在agent中必須在connect_phase中,連接driver.seq_item_port.connect(sequencer.seq_item_export)。所以sequence在執行時
必須指定sequencer,而sequencer又與driver相連接在一起,最終完成向DUT發送transaction的目的。當然對於很簡單的
transaction也可以直接在sequence中就向DUT發送信號。
不過有一個疑惑的地方,sequence中的task body()與sequencer的seq_item_port的執行之間的關系是如何的。
答:sequence body主要完成transaction的create/random/send,之后的transaction才會發送給driver
sequencer會更根據poriority,phase,connect來調用正確的sequence給driver。