[CU]config_db機制3-uvm_config_db使用注意事項


注1:該篇文章側重於config_db機制的使用;

1. config機制成對出現

1.1 簡單示例

如在某個case(派生自uvm_test)的build_phase中可以做如下設置: 

1 uvm_config_db#(int)::set(this,"env.agent.driver","pre_num_max",100);

那么在driver的build_phase中需要:

1 uvm_config_db#(int)::get(this,"","pre_num_max",pre_num_max);

1.2 示例解釋

(1) uvm_config_db中set和get都是靜態函數,可用雙冒號形式調用.

1   static function void set(uvm_component cntxt,
2                            string inst_name,
3                            string field_name,
4                            T value);
5   static function bit get(uvm_component cntxt,
6                           string inst_name,
7                           string field_name,
8                           inout T value);

(2) uvm_config_db::set的參數解釋:

1 initial begin
2     uvm_config_db#(virtual my_if)::set(null,"uvm_test_top.env.i_agt.drv","vif",input_if);
3 end
4 
5 initial begin
6     uvm_config_db#(virtual my_if)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","vif",input_if);
7 end

注1:在top module中通過config_db機制的set函數設置virtual interface時,set的第一個參數為null; 在這種情況下,UVM會自動把第一個參數替換為uvm_root::get(),即uvm_top;

(2.1) set的第一個參數用以說明是哪個component對pre_num_max進行設置,通常是一個uvm_component的指針,一般使用填寫this; 

(2.2) set的第二個參數表示從調用uvm_config_db::set的地方看下去,要設置的變量所在的component的路徑; set的前兩個參數聯合起來組成路徑;

(2.3) set的第三個參數表示一個記號,用於說明這個值是傳給driver中的哪個變量的; 

(2.4) set的第四個參數是要設置的值;

(3) uvm_config_db::get的參數解釋:

(3.1) get的第一個參數一般是this即可;

(3.2) get的第二個參數填寫一個空的字符串;

(3.3) get的第三個參數就是set中的第三個參數,二者必須一致;

(3.4) get的第四個參數則是要設置的變量;

1 uvm_config_db#(int)::set(this,"env.i_agt.drv","p_num",100);
2 uvm_config_db#(int)::get(this,"","p_num",pre_num);

注1:get函數中第三個參數可以與get函數中第四個參數不一樣(但是最好一樣,這種情況下,如果再滿足其他條件,可以省略get語句);

2. 省略get的config

(1) 雖然通常要求set與get成對出現,但是在某些特定情況下,get是可以省略的.

(2) 實現原理: build_phase內的super.build_phase(phase)在滿足以下特定條件的情況下,可以完成get的功能(super.build_phase中實現的自動get,uvm_component的apply_config_settings實現自動get);

特定條件1:將正常情況下需要執行get操作的類注冊到factory;

特定條件2:使用field_automation機制把要get的變量注冊;

特定條件3:set的第三個參數必須與要get的變量的名字相一致;

(3) 示例

 1 class mac_driver extends uvm_driver#(mca_transaction);
 2     ...
 3     int pre_num;
 4     int pre_num_min;
 5     int pre_num_max;
 6 
 7     `uvm_component_utils_begin(mac_driver)
 8         `uvm_field_int(pre_num_min,UVM_ALL_ON)
 9         `uvm_field_int(pre_num_max,UVM_ALL_ON)
10     `uvm_component_utils_end
11 
12     function void build_phase(uvm_phase phase);
13         super.build(phase);
14         //uvm_config_db#(int)::get(this,"","pre_num_max",pre_num_max);
15         //uvm_config_db#(int)::get(this,"","pre_num_min",pre_num_min);
16     endfunction
17 
18 endclass

3. 跨層次的多重set(build_phase的set)

注1:后面需要補充非build_phase的set相關內容,可參考公眾號-芯片學堂;

假如set多次,get一次,那么最終get到的是哪個set值呢?

(1) 首先看set的優先級(層次越高,set的優先級越高);

(2) 其次看時間先后;

比如,在uvm_test_top和env中分別有以下set語句:

1 uvm_config_db#(int)::set(this,"env.agent.driver","pre_num_max",100);
2 uvm_config_db#(int)::set(this,"agent.driver","pre_num_max",999);

uvm_test_top的層次高於env,所以uvm_test_top中的set優先級高.因為越往上,越接近用戶,方便用戶控制.

4. 同一層次的多重set(build_phase的set)

當跨層次看待問題時,高層次的set優先; 當處於同一層次時,則是時間優先.

1 uvm_config_db#(int)::set(this,"env.agent.driver","pre_num_max",100);
2 uvm_config_db#(int)::set(this,"env.agent.driver","pre_num_max",109);

driver最終get的值會是109.

5. 非直線的設置與獲取

(1) 如在scoreboard中,對driver的某些變量使用config_db機制進行設置,則稱為非直線設置;

 1 //my_scoreboard.sv
 2 function void my_scoreboard::build_phase(uvm_phase phase);
 3     ...
 4   uvm_config_db#(int)::set(this.m_parent,"i_agt.drv","pre_num",200);
 5     ...
 6 endfunction
 7 
 8 //my_scoreboard.sv
 9 function void my_scoreboard::build_phase(uvm_phase phase);
10     ...
11     uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",200);
12     ...
13 endfunction

(2) 存在的問題: UVM沒有明文指出同一級別的build_phase的執行順序,所以當my_driver在獲取參數值時,my_scoreboard的build_phase可能已經執行了,也可能沒有執行;所以,這種非直線的設置,存在一定風險;

6. config機制對通配符的支持

(1) 在config_db::set操作時,其第二個參數可以提供完整的路徑,也可以不提供完整的路徑;

注1:可以將config_db的set放到一個module的initial begin...end塊內,並通過bind的方式將該module在top module內例化;

注2:下圖中使用通配符的code中,i_agt是否能看到該資源?需要確認下(可以!);

 1 //top_tb.sv
 2 //不使用通配符
 3 initial begin
 4     uvm_config_db#(virtual my_if)::set(null,"uvm_test_top.env.i_agt.drv","vif",input_if);
 5     uvm_config_db#(virtual my_if)::set(null,"uvm_test_top.env.i_agt.mon","vif",input_if);
 6     uvm_config_db#(virtual my_if)::set(null,"uvm_test_top.env.o_agt.mon","vif",output_if);
 7 end
 8 
 9 //使用通配符
10 initial begin
11     uvm_config_db#(virtual my_if)::set(null,"uvm_test_top.env.i_agt*","vif",input_if);
12     uvm_config_db#(virtual my_if)::set(null,"uvm_test_top.env.o_agt*","vif",output_if);
13 end
14 
15 //使用通配符
16 initial begin
17     uvm_config_db#(virtual my_if)::set(null,"*i_agt*","vif",input_if);
18     uvm_config_db#(virtual my_if)::set(null,"*o_agt*","vif",output_if);
19 end

7. config_db與變量的變化

注:以下是仿真得出的結論;

(1) 如果通過config_db進行int變量的set/get,發現一次set后, int變量接着發生了變化,這種變化無法通過config_db::get得到; 只能在每次變化后,重新set,並且重新get;

(2) 如果通過config_db進行類變量/virtual interface的set/get,發現一次set后,類變量/virtual interface的內部成員變量值發生了變化,不需要重復get,可以直接通過已經get過一次的句柄/virtual interface發現其內部成員變量的變化;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM