根据mentor的推荐,尽量少用uvm_config_db,因为uvm_config_db是一个数据库,使用正则表达式匹配所有结果,如果数据库过大会影响验证平台性能。但是同时也提到性能与方法学乃至OOP有一个trade off.
这里几个减少uvm_config_db的方法:
(1) 数据结构粒度不要太小,如下代码:
uvm_config_db #(int)::set::(this, "*", "id", id);
uvm_config_db #(string)::set::(this, "*", "name", name);
如果id和name可以归为一类,那么最好:
class config;
int id;
string name;
endclass : config
uvm_config_db #(config)::set::(this, "*", "cfg", cfg);
(2) 使用直接传递
使用直接赋值语句代替set, get.这种方法很具有争议,因为直接赋值影响了重用性,违反了OOP中只能对数据成员进行method操作的原则。因此建议适当使用,例如比较好的方法是在agent内部使用直接赋值,其上结构使用config_db.原因是agent是最小功能单元,内部结构基本不会改变,复用粒度一般都在这一层。上一层可能会有env,也可能没有,env对agent的传递最好使用config_db.
(3) interface传递的考虑
这一部分可以算是上面两种方法的结合的考虑,目的是减少config_db中interface的传递数目。相对于第一种方法,将所有interface包含在一个对象中,只使用config_db传递该对象,各个package component只取自己需要的interface handle.而对应第二种方法,可以将interface独立做成一个package,所有interface包含在这个包中,需要使用时import这个package,然后使用赋值语句把interface handle传递给configuration.
其他改善uvm_config_db性能的方法有:
(1) 搜索路径少用正则通配,尽量精确,特别是直接使用*是一种不好的习惯,会给今后平台增加组件或者与其他模块配合时带来问题。
(2) 不要用config_db来传递大量变化的内容,这样的通信会没有效率,可以采用TLM通信或者引用handle
以上各条需要根据实际情况进行调整,针对性能和重用性进行适当的调整,偏向两个极端都是不好的选择。