config机制
一、概述
- 在验证环境的创建过程build phase中,除了组件的实例化,配置也是必不可少的。
- 为了验证环境的复用性,通过外部的参数配置,使得环境在创建时可以根据不同参数来选择创建的组件类型、组件实例数目、组件之间的连接以及组件的运行模式等。
- 在更细致的环境调节(environment tuning)中有更多的变量需要配置,例如for-loop的阈值、字符串名称、随机变量的生成比重等。
- 比起重新编译来调节变量,如果在仿真中可以通过变量设置来修改环境,那么就更灵活了,而UVM config机制正提供了这样的便捷。
- 配置的部分必须发生在底层组件创建之前,这在SV中是做不到的。因为SV中必须顶层组件创建之后,通过句柄来索引。
- 在UVM提供了uvm_config_db配置类以及几种方便的变量设置方法来实现仿真时的环境控制,常见的uvm_config_db类的使用方式包括:
- 传递virtual interface到环境中
- 设置单一变量值,例如int、string、enum等
- 传递配置对象(config object)到环境
uvm_config_db #(T)::set(uvm_component cntxt,string inst_name,string field_name,T value);
uvm_config_db #(T)::get(uvm_component cntxt,string inst_name,string field_name,inout T value);
二、interface传递
- interface传递可以很好地解决连接硬件世界和软件世界。
- 而在之前SV验证模块中,虽然SV可以通过层次化的interface的索引来完成传递,但是这种方式不利于软件环境的封装和复用。
- UVM的uvm_config_db使得接口的传递和获取彻底分离开来。
- 在实现接口传递的过程中需要注意:
- 接口传递应该发生在run_test()之前。这保证了在进入build phase之前,virtual interface已经被传递到uvm_config_db中。
- 用户应当把interface与virtual interface的声明区分开来,在传递过程中的类型应当为virtual interface,即实际接口的句柄。
三、变量设置
在各个test中,可以在build phase对底层组件的变量加以配置,进而在环境例化之前完成配置,使得环境可以按照预期运行。
四、object传递
- 在test配置中,需要配置的参数不只是数量多,而且可能还分属于不同的组件。
- 如果对许多层次中的变量做出变量设置,那么会需要很多代码,容易出错还不易于服用,甚至底层组件的变量被删除后,也无法通过uvm_config_db::set()得知配置是否成功。
- 然而如果将每个组件中的变量加以整合,首先放置到一个uvm_object中,再对中心化的配置对象进行传递,那么将会更有利于整个环境的修改维护。
五、实例
interface uvm_config_if;
logic [31:0] addr;
logic [31:0] data;
logic [ 1:0] op;
endinterface
package uvm_config_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
class config_obj extends uvm_object;
int comp1_var;
int comp2_var;
`uvm_object_utils(config_obj)
function new(string name = "config_obj");
super.new(name);
`uvm_info("CREATE", $sformatf("config_obj type [%s] created", name), UVM_LOW)
endfunction
endclass
class comp2 extends uvm_component;
int var2;
virtual uvm_config_if vif;
config_obj cfg;
`uvm_component_utils(comp2)
function new(string name