UVM学习整理——UVM结构(component派生类)
目錄
二、UVM結構
2.1UVM組件
2.1.1uvm_driver
2.1.2uvm_monitor
2.1.3uvm_sequencer
2.1.4uvm_agent
2.1.5uvm_scoreboard
2.1.6reference model
2.1.7uvm_env
2.1.8uvm_test
2.1.9uvm_component相關宏
2.2UVM驗證平臺的樹形結構
二、UVM結構
2.1UVM組件
UVM的組件(uvm_component類)繼承于UVM的核心基類中一個核心分支,均可構成驗證環境,這是因為它們都從uvm_component類繼承了phase機制(必須在build_phase中實例化),都會經歷各個phase階段。主要介紹構成環境的常見組件類:uvm_driver、uvm_monitor、uvm_sequencer、uvm_agent、uvm_scoreboard、uvm_env和uvm_test等。
圖 5uvm_component類和子類
2.1.1uvm_driver
所有driver派生自uvm_driver。Driver的功能主要就是向sequencer索要sequence_item(transaction),并通過虛擬接口把sequence_item里的信息驅動到DUT的接口上。相當于完成了transaction級別到DUT能夠接受的端口級別信息的轉變。
drive使用工廠機制注冊類通常需要三步:聲明,注冊,調用new()函數。
class my_driver extends uvm_driver#(my_transaction);? ? //my_transaction是sequence item類型virtual my_if vif; //virtual interface`uvm_component_utils(my_driver) //在factory中注冊my_driverfunction new(string name = "my_driver", uvm_component parent = null);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))`uvm_fatal("my_driver", "virtual interface must be set for vif!!!")endfunctionextern task main_phase(uvm_phase phase);extern task drive_one_pkt(my_transaction tr); endclassuvm_driver在uvm_component基礎上沒有擴展新的函數/任務,而只是擴展了一些用來通信的端口seq_item_port和rsp_port。在構建環境組件時,派生uvm_driver和uvm_sequencer的類,可以直接使用這些成員變量。
如果不想使用自帶的成員變量,想加入改動,也可以由uvm_component來派生Driver等組件,然后自行定義uvm_seq_item_pull_port #(REQ, RSP)等類型的變量,名字可以不再是seq_item_port等(源碼見附錄一)。
注:uvm_driver和子類都是參數化類,定義新driver類時,應聲明獲取的事務參數REQ類型(事務參數)。
2.1.2uvm_monitor
monitor通過虛擬接口收集總線信息,并將數據轉換成transation級別的sequence_item,再通過端口將數據發送至其他驗證組件。收集的數據可用于簡單的功能和時序檢查。
所有用戶自定義數據監測行為的monitor都繼承自uvm_monitor,uvm_monitor繼承自uvm_component,從源代碼來看并沒有增添新的成員和方法,但將monitor類都繼承于uvm_monitor有助于實現父類monitor的方法和特性。(源碼見附錄一)
monitor使用工廠機制注冊類通常也需要三步:聲明uvm_monitor,向工廠注冊并調用new()函數。
class my_monitor extends uvm_monitor;virtual my_if vif;uvm_analysis_port #(my_transaction) ap;`uvm_component_utils(my_monitor) 在factory中注冊my_monitorfunction new(string name = "my_monitor", uvm_component parent = null);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))`uvm_fatal("my_monitor", "virtual interface must be set for vif!!!")ap = new("ap", this);endfunctionextern task main_phase(uvm_phase phase);extern task collect_one_pkt(my_transaction tr); endclass2.1.3uvm_sequencer
所有的sequencer都要派生自uvm_sequencer。功能是組織管理sequence,當driver要求數據時,他就把sequence生成sequence_item轉發給driver。同時若需要的話,uvm_sequencer也可以從uvm_driver那里獲取隨后的RSP對象來得知數據通信是否正常(源碼見附錄一)。
sequencer使用工廠機制注冊:
class my_sequencer extends uvm_sequencer #(my_transaction); //my_transaction為sequence_item類型function new(string name, uvm_component parent);super.new(name, parent);endfunction `uvm_component_utils(my_sequencer) //在factory中注冊my_sequencer endclass一個Sequencer可以掛載多個不同的sequence,sequencer可以通過內置的方法來選擇需要發送的sequence,針對不同的測試條件發送不同的transaction。
2.1.4uvm_agent
將driver,monitor,sequencer封裝成一個agent模塊,方便復用。uvm_agent與uvm_component相比最大的改動在于引入了一個變量is_active,缺省值是UVM_ACTIVE。處在active模式的agent需要例化driver、monitor和sequencer;而如果is_active的值是UVM_PASSIVE,這表示agent是passive模式,只可以例化monitor。
通過is_active變量,agent需要在build_phase()和connect_phase()等函數中通過選擇語句來對driver和sequencer進行有條件的例化和連接(源碼見附錄一)。
class my_agent extends uvm_agent ;my_sequencer sqr;my_driver drv;my_monitor mon;uvm_analysis_port #(my_transaction) ap;function new(string name, uvm_component parent);super.new(name, parent);endfunction extern virtual function void build_phase(uvm_phase phase);extern virtual function void connect_phase(uvm_phase phase);`uvm_component_utils(my_agent) //在factory中注冊my_agent endclass function void my_agent::build_phase(uvm_phase phase);super.build_phase(phase);if (is_active == UVM_ACTIVE) begin //通過選擇語句來對driver和sequencer進行有條件的例化。sqr = my_sequencer::type_id::create("sqr", this);drv = my_driver::type_id::create("drv", this);endmon = my_monitor::type_id::create("mon", this); endfunction function void my_agent::connect_phase(uvm_phase phase);super.connect_phase(phase);if (is_active == UVM_ACTIVE) begin //通過選擇語句來對driver和sequencer進行有條件的連接。drv.seq_item_port.connect(sqr.seq_item_export);endap = mon.ap; endfunction2.1.5uvm_scoreboard
一般的scoreboard都要派生自uvm_scoreboard。其功能就是比較reference model和monitor分別發送來的數據,根據比較結果判斷DUT是否正確。與uvm_component相比uvm_scoreboard也沒有額外的成員變量和方法,但UVM建議用戶將檢查比較類都繼承于uvm_scoreboard,這也便于日后的子類可以自動繼承于可能被擴充到uvm_scoreboard中的成員(源碼見附錄一)。
在scoreboard中通常會聲明TLM端口供monitor傳輸數據。
class my_scoreboard extends uvm_scoreboard;my_transaction expect_queue[$];uvm_blocking_get_port #(my_transaction) exp_port;uvm_blocking_get_port #(my_transaction) act_port;`uvm_component_utils(my_scoreboard) //在factory中注冊my_scoreboardextern function new(string name, uvm_component parent = null);extern virtual function void build_phase(uvm_phase phase);extern virtual task main_phase(uvm_phase phase); endclass2.1.6reference model
reference model是直接派生自uvm_component。其作用就是模仿DUT,完成與DUT相同的功能,可以直接使用systemverilog的特性,或者可以通過DPI等接口調用其它語言來完成與DUT相同功能,將產生的結果輸出到scoreboard進行比較。
2.1.7uvm_env
所有env都要派生自uvm_env,屬于uvm_component類,相對于uvm_component類沒有做過多擴展。env把驗證平臺固定不變的component(如agent、reference model、scoreboard和底層env等)封裝在一起,并配置各個組件間的通信端口。這樣在要運行不同case時,只要在case中實例化此env即可(源碼見附錄一)。
class my_env extends uvm_env;my_agent i_agt;my_agent o_agt;my_model mdl;my_scoreboard scb;uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo;uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo;function new(string name = "my_env", uvm_component parent);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase); //在build_phase中實例化組件以及通信管道FIFOsuper.build_phase(phase);i_agt = my_agent::type_id::create("i_agt", this);o_agt = my_agent::type_id::create("o_agt", this);i_agt.is_active = UVM_ACTIVE;o_agt.is_active = UVM_PASSIVE;mdl = my_model::type_id::create("mdl", this);scb = my_scoreboard::type_id::create("scb", this);agt_scb_fifo = new("agt_scb_fifo", this);agt_mdl_fifo = new("agt_mdl_fifo", this);mdl_scb_fifo = new("mdl_scb_fifo", this);endfunctionextern virtual function void connect_phase(uvm_phase phase);`uvm_component_utils(my_env) //在factory注冊my_env endclass2.1.8uvm_test
所有的測試用例都要派生自uvm_test或派生類,屬于uvm_component類,相對于uvm_component類也沒有做過多擴展。不同的case之間差異很大,所以從uvm_test派生出來的類各不同。任何一個派生的case都要實例化env,只有這樣才能正常傳數(源碼見附錄一)。
class base_test extends uvm_test;my_env env;function new(string name = "base_test", uvm_component parent = null);super.new(name,parent);endfunctionextern virtual function void build_phase(uvm_phase phase);extern virtual function void report_phase(uvm_phase phase);`uvm_component_utils(base_test) //在factory中注冊base_test endclass2.1.9uvm_component相關宏
1.`uvm_component_utils:把一個直接或間接派生自uvm_component的類注冊到factory中。
2.`uvm_component_param_utils:把一個直接或間接派生自uvm_component的參數化的類注冊到factory中。
3.`uvm_component_utils_begin:用于同時需要factory和field_automation機制注冊的類,與uvm_object_utils_begin相似。最大的意義在于可以自動使用config_db得到某些變量的值。
4.`uvm_component_param_utils_begin:用于參數化class實現某些變量field_automation機制。
5.`uvm_component_utils_end:總是與uvm_component_*_begin成對出現,作為factory注冊結束的標志。
2.2UVM驗證平臺的樹形結構
UVM通過uvm_component實現驗證平臺的樹形結構,uvm_component在new()時,需要指定一個類型為uvm_component、名字是parent的變量。
仿真過程中,會先執行build_phase()。該phase用于構建uvm-tree的結構,注:uvm_component組件類必須在build_phase中實例化,build_phase()的主要用途就是實例化組件類,創建和配置測試平臺的結構,構建tree,典型的UVM樹如下圖:
一般來說,對組件實例化時,會向parent參數傳遞指定的父類(如this指針),若傳遞null,此component的父類將被設置成uvm_top;
env = my_env::type_id::create("env", this);
env = my_env::type_id::create("env", null);
uvm_top是一個全局變量,它是uvm_root的一個實例(也是唯一的一個實例),而uvm_root本質上是一個uvm_component派生自uvm_component,它是UVM樹的根。uvm_test_top的parent是uvm_top,而uvm_top的parent是null。
uvm_root的存在可以保證整個驗證平臺中只有一棵樹,所有結點都是uvm_top的子結點。在導入uvm_pkg文件包(import uvm_pkg::*;)時,會自動創建一個頂層類uvm_root所例化的對象uvm_top。
UVM提供了一系列的接口函數用于訪問UVM樹中的結點,主要的包括:
源碼:extern function uvm_component get_child (string name);
源碼:extern function void get_children(ref uvm_component children[$]);
源碼:?????extern function int get_first_child (ref string name);
????????????????extern function int get_next_child (ref string name);
總結
以上是生活随笔為你收集整理的UVM学习整理——UVM结构(component派生类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【LLC原理】适用于高压大功率场合的三相
- 下一篇: 用Excel制作一个漂亮的分类散点图