[转]UVM的config机制

一、概述

在验证环境的创建过程build_phase中,除了组件的实例化,配置也是必不可少的。为了验证环境的复用性,通过外部的参数配置,使得环境在创建时可以根据不同参数来选择创建的组件类型、组件实例数目、组件之间的连接以及组件的运行模式等。在更细致的环境调节中有更多的变量需要配置,例如for-loop的阈值、字符串名称、随机变量的生成比重等。比起重新编译来调节变量,如果在仿真中可以通过变量设置来修改环境,那么就更灵活了,而UVM的config机制正提供了这样的便利。

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, T value);

二、interface传递

interface传递可以很好地解决了连接硬件世界和软件世界。而在之前SV验证模块中,虽然SV可以通过层次化的interface的索引来完成了传递,但是这样不利于软件环境的封装和复用。UVM的uvm_comfig_db使得接口的传递和获取彻底分离开来。

在实现接口传递的过程中需要注意:

  • 接口传递应该发生在run_test()之前。保证了在进入build_phase之前,virtual interface已经被传递到uvm_config_db中。

  • 应该把interfacevirtual interface的声明区分开来,在传递过程中的类型应当为virtual interface,即实际接口的句柄。

    interface intf1;
    logic enable = 0;
    endinterface

    class comp1 extends uvm_component;
    uvm_component_utils(comp1) virtual intf1 vif; ... function void build_phase(uvm_phase phase); if(!uvm_config_db #(virtual intf1)::get(this, "", "vif", vif)) begin //this指代当前组件comp1,“vif”指的是comp1的一个变量uvm_error(“GETVIF”, “no virtual interface is assigned”)
    end
    uvm_info("SETVIF", $sformatf("vif.enable is %b before set", vif.enable), UVM_LOW) vif.enable = 1;uvm_info(“SETVIF”, $sformatf(“vif.enable is %b after set”, vif.enable), UVM_LOW)
    endfunction
    endclass

    class test1 extends uvm_test;
    `uvm_component_utils(test1)
    comp1 c1;

    endclass

    intf1 intf();

    initial begin
    //第一个参数时传递一个句柄,第二个参数时路径,第三个参数时c1.vif这个变量,第四个参数是那个例化的需要传递的intf
    uvm_config_db #(virtual intf1)::set(uvm_root::get(), “uvm_test_top.c1”, “vif”, intf);
    run_test(“test1”);
    end

uvm_config_db #(virtual intf1)::get(this, "", "vif", vif)的含义如下图所示在这里插入图片描述
uvm_config_db #(virtual intf1)::set(uvm_root::get(), "uvm_test_top.c1", "vif", intf)的含义如下图所示

在这里插入图片描述

三、变量设置

在各个test中,可以在build_phase对底层组件的变量加以配置,进而在环境例化之前完成配置,使得环境可以按照预期运行。

class comp1 extends uvm_component;
	`uvm_component_utils(comp1)
	int vall = 1;
	string str1 = "null";
	...
	function void build_phase(uvm_phase phase);
		`uvm_info("SETVIF", $sformatf("vall is %d before set", vall), UVM_LOW)
		`uvm_info("SETVIF", $sformatf("str1 is %s before set", str1), UVM_LOW)
		uvm_config_db#(int)::get(this, "", "vall", vall);
		uvm_config_db#(string)::get(this, "", "str1", str1);
		`uvm_info("SETVIF", $sformatf("vall is %d after set", vall), UVM_LOW)
		`uvm_info("SETVIF", $sformatf("str1 is %s after set", str1), UVM_LOW)
	endfunction
endclass

class test1 extends uvm_test;
	`uvm_component_utils(test1)
	comp1 c1;
	...
	function void build_phase(uvm_phase phase);
		uvm_config_db#(int)::set(this, "c1", "vall", 100);
		uvm_config_db#(string)::set(this, "c1", "str1", "comp1");
		c1 = comp1::type_id::create("c1", this);
	endfunction
endclass

四、object传递

在test配置中,需要配置的参数不只是数量多,而且可能还分属于不同的组件。那么如果对这么多层次中的变量做出类似上面的变量设置,那会需要更多的代码,容易出错还不易于复用,甚至底层组件的变量被删除后,也无法通过uvm_config_db::set()得知配置是否成功。然而如果将每个组件中的变量加以整合,首先放置到一个uvm_object中,再对中心化的配置对象进行传递,将会有利于整体环境的修改。

class comp1 extends uvm_component;
	`uvm_component_utils(comp1)
	config1 cfg;
	...
	function void build_phase(uvm_phase phase);
		uvm_object tmp;
		uvm_config_db#(uvm_object)::get(this, "", "cfg", tmp);
		void'($cast(cfg, tmp));
		`uvm_info("SETVIF", $sformatf("cfg.vall is %d after get", cfg.vall), UVM_LOW)
		`uvm_info("SETVIF", $sformatf("cfg.str1 is %s after get", cfg.str1), UVM_LOW)
	endfunction
endclass

class test1 extends uvm_test;
	`uvm_component_utils(test1)
	comp1 c1, c2;
	config1 cfg1, cfg2;
	...
	function void build_phase(uvm_phase phase);
		cfg1 = config1::type_id::create("cfg1");
		cfg2 = config1::type_id::create("cfg2");
		cfg1.vall = 30;
		cfg1.str1 = "c1";
		cfg2.vall = 50;
		cfg2.str1 = "c2";
		uvm_config_db#(uvm_object)::set(this, "c1", "cfg", cfg1);
		uvm_config_db#(uvm_object)::set(this, "c2", "cfg", cfg2);
		c1 = comp1::type_id::create("c1", this);
		c2 = comp1::type_id::create("c2", this);
	endfunction
endclass

五、总结

  • 在使用uvm_config_db::set()时,通过层次和变量名,将这些信息放置到uvm_pkg唯一的全局变量uvm_pkg::uvm_resources。全局变量uvm_resources用来储存和释放配置资源信息,uvm_resourcesuvm_resource_pool类的全局唯一实例,该实例中有两个resource数组用来存放配置信息,这两个数组中一个由层次名字所以,一个由类型索引,通过这两个关联数组可以存放通过层次配置的信息。同时,底层的组件也可以通过层次或者类型来取得来自高层的配置信息。而在使用uvm_config_db::get()方法时,通过传递的参数构成索引层次,然后在uvm_resources已有的配置信息池中索引该配置,如果索引到返回1,否则返回0。
  • 在使用set()get()方法时,传递的参数类型应当上下保持一致,对于uvm_object等实例的传递,如果类型不一致,应首先通过$cast()完成类型转换,再对类型转换后的对象进行操作。
  • set()get()方法传递的参数可以使用通配符*来表示任意的层次。
  • module环境中如果使用uvm_config_db::set(),则传递的第一个参数uvm_component cntxt参数一般用来表示当前的层次。如果当前层次为最高层,可以设置为null,也可以设置为uvm_root::get()来表示uvm_root的全局顶层实例。
  • 在使用配置变量时,应确保先进行uvm_config_db::get(),在获得了正确的配置值以后再使用。
  • 应该尽量确保uvm_config_db::set()方法在相关配置组件创建前调用,只有先完成配置,相关组件在例化前才可以得到配置值继而正确地例化。
  • uvm_config_db::set()方法第一个参数使用当前层次的前提下,对于同一个组件的同一个变量,如果有多个高层组件对该变量进行设置,那么较高层组件的配置会覆盖较低层的配置,但是如果是同一层次组件对该变量进行多次配置时,后面的配置会覆盖前面的配置。
  • 在使用uvm_config_db::get()方法时,添加便于调试的语句,例如通过UVM报告信息得知uvm_config_db::get()方法中的配置变量是否从uvm_config_db获取到。

---------------------
作者:煎丶包
来源:CSDN
原文:https://blog.csdn.net/qq_39794062/article/details/113902716
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UVM中的config_db机制是一种方便的配置管理机制,可以在测试用例中动态地配置不同组件之间的参数。它允许用户将配置信息存储在单个数据库中,并在需要时从中检索。 config_db机制的核心是一个名为uvm_config_db的类,它提供了一些静态方法,用于将配置信息存储在数据库中、从数据库中检索配置信息和删除配置信息。每个配置信息都有一个名称和一个通用的数据类型,可以是任意类型的数据结构,包括简单的整数和字符串,以及更复杂的对象和指针。 config_db机制可以用于多种情况,例如: 1. 在测试用例中配置测试环境中的组件; 2. 在测试用例中配置测试用例本身; 3. 在测试用例中配置测试运行时环境(如时钟周期)。 下面是一个例子,展示如何使用config_db机制来配置两个组件之间的参数: ```systemverilog // 存储配置信息 uvm_config_db#(int)::set(null, "env.agent1.config", "data", 100); uvm_config_db#(string)::set(null, "env.agent2.config", "data", "hello"); // 从数据库中检索配置信息 int my_int; string my_string; uvm_config_db#(int)::get(null, "env.agent1.config", "data", my_int); uvm_config_db#(string)::get(null, "env.agent2.config", "data", my_string); ``` 在上面的例子中,我们使用uvm_config_db类的set方法将一个整数值和一个字符串值存储在了数据库中,并使用get方法从数据库中检索这些值。注意,我们使用了不同的名称("env.agent1.config"和"env.agent2.config")来区分不同的配置信息。这些名称应该在测试用例中被定义为常量或宏,以便在整个测试用例中使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值