uvm_config_db的用途大概有如下三種:
傳遞virtual interface到環境中。
設置單一變量值,如int.string.enum等。
傳遞配置對象(config object)到環境中
在使用uvm_config_db的配置方法時,下面給出一些建議:
· 在使用set/get方法時,傳遞的參數類型應當上下保持一致。對於uvm_object等實例的傳遞,如果get類型與set類型不一致,應當首先通過$cast()完成類型轉換,再對類型轉換后的對象進行操作。
· set/get方法傳遞的參數可以使用通配符“*”來表示任意的層次,類似於正則表達式的用法。同時,用戶需要懂得“*.comp1”與“*comp1”的區別,前者表示在目前層次之下所有名字為“comp1”的組件,而后者表示包括當前層次及當前層次以下的所有名為“comp1”的組件。
· 在module環境中如果要使用uvm_config_db::set,則傳遞的第一個參數uvm_component cntxt用來表示當前的層次,由於當前層次為最高層,所以用戶可以設置為null,也可以設置為uvm_root::get()來表示uvm_root的全局實例。
· 在使用被配置變量時,應當確保先進行了uvm_config_db::get的操作,獲得了正確的值以后再使用。
· 應當盡量確保uvm_config_db::set方法在其相關配置組件創建前調用。這是因為只有先進行了配置,其相關組件在例化時進入build phase,可以得到期望的值。
· 對於同一實例組件的同一個變量,如果有多個上層組件對該變量進行設置時,更上層組件的配置會覆蓋低層的配置;但是如果是同一個層次組件對該變量進行多次配置時,應該遵循后面的配置會覆蓋前面的配置。
· 用戶應該在使用uvm_config_db::get()方法時,添加便於調試的語句,來通過UVM信息打印得知get方法的變量是否從uvm_config_db獲取,如果沒有獲取,是否需要采取其它的措施。
從上面這個例子可以看到,接口的傳遞從硬件世界到UVM環境中的傳遞可以通過uvm_config_db來實現。在實現過程中需要注意幾點:
· 接口的傳遞應該發生在run_test()之前。這保證了在進入build phase之前,virtual interface已經傳遞進入uvm_config_db中。
· 用戶應當把interface與virtual interface的聲明區分開來。在傳遞過程中的類型應當為virtual interface,即實際接口的句柄。
在使用uvm_config_db API set/get時,實際發生了如下的后台操作:
1. uvm_config_db::set通過層次和變量名,將這些信息放置到uvm_pkg唯一的全局變量uvm_pkg::uvm_resources。
2. 全局變量uvm_resources用來存儲和釋放配置資源信息(resource information)。uvm_resources是uvm_resource_pool類的全局唯一實例,該實例中有兩個resource數組用來存放配置信息,這兩個數組中一個由層次名字索引,一個由類型索引,通過這兩個關聯數組可以存放任意個通過層次配置的信息。同時,底層的組件也可以通過層次或者類型來取得高層的配置信息。這種方式也完成了信息配置與信息獲取的剝離,便於調試和復用。
3. 在使用uvm_config_db::get方法時,通過傳遞的參數構成索引的層次,然后在uvm_resource已有的配置信息池中索引該配置,如果索引到,方法返回1,否則為0。
如何使用?
uvm_config_db#(int)::set(this, “env.i_agt.drv”, “pre_num”, 100);
四個參數,set寄信,get收信。
第一個和第二個參數聯合起來組成目標路徑,與此路徑符合的目標才能收信。第一個參數必須是一個uvm_component實例的指針,第二個參數是相對此實例的路徑。第三個參數表示一個記號,用以說明這個值是傳給目標中的哪個成員的,第四個參數是要設置的值。
uvm_config_db#(int)::get(this, “”, “pre_num”, pre_num);
四個參數中,第一個參數,通常可以為 "this", "null"等實例的指針。
第二個參數,可以為空“”, 也可以用通配符,如截圖中的例子,”*yy_agent" "yy_agent.drv"
set 與get的第一個到第三個參數“寄信”與“收信”要符合兩個條件:時間的匹配,一定是先寄信再收信,為了避免出錯,一般get前最好加判斷,2 標記一致,也就是郵件目的地是匹配的。
第三個,往往是個參數值,或者說句柄。