uvm_config_db——半个全局变量
module tb_top
initial begin
uvm_config_db #(virtual spi_if)::set(null, "", "vif", vif)
end
endmodule
classs spi_drv extend uvm_driver;
virtual spi_if vif;
uvm_config_db #(virtual spi_if)::get(this, "", "vif", vif);
endclass
//----------------------------------------------------------------------
// class: uvm_config_db
//
// All of the functions in uvm_config_db#(T) are static, so they
// must be called using the :: operator. For example:
//
//| uvm_config_db#(int)::set(this, "*", "A");
//
// The parameter value "int" identifies the configuration type as
// an int property.
//
// The <set> and <get> methods provide the same API and
// semantics as the set/get_config_* functions in <uvm_component>.
//----------------------------------------------------------------------
class uvm_config_db#(type T=int) extends uvm_resource_db#(T); // Internal lookup of config settings so they can be reused
// The context has a pool that is keyed by the inst/field name.
static uvm_pool#(string,uvm_resource#(T)) m_rsc[uvm_component]; // Internal waiter list for wait_modified
static local uvm_queue#(m_uvm_waiter) m_waiters[string]; // function: get
//
// Get the value for ~field_name~ in ~inst_name~, using component ~cntxt~ as
// the starting search point. ~inst_name~ is an explicit instance name
// relative to ~cntxt~ and may be an empty string if the ~cntxt~ is the
// instance that the configuration object applies to. ~field_name~
// is the specific field in the scope that is being searched for.
//
// The basic ~get_config_*~ methods from <uvm_component> are mapped to
// this function as:
//
//| get_config_int(...) => uvm_config_db#(uvm_bitstream_t)::get(cntxt,...)
//| get_config_string(...) => uvm_config_db#(string)::get(cntxt,...)
//| get_config_object(...) => uvm_config_db#(uvm_object)::get(cntxt,...) static function bit get(uvm_component cntxt,
string inst_name,
string field_name,
inout T value);
//TBD: add file/line
int unsigned p;
uvm_resource#(T) r, rt;
uvm_resource_pool rp = uvm_resource_pool::get();
uvm_resource_types::rsrc_q_t rq;
uvm_coreservice_t cs = uvm_coreservice_t::get(); if(cntxt == null)
cntxt = cs.get_root();
if(inst_name == "")
inst_name = cntxt.get_full_name();
else if(cntxt.get_full_name() != "")
inst_name = {cntxt.get_full_name(), ".", inst_name}; rq = rp.lookup_regex_names(inst_name, field_name, uvm_resource#(T)::get_type());
r = uvm_resource#(T)::get_highest_precedence(rq); if(uvm_config_db_options::is_tracing())
m_show_msg("CFGDB/GET", "Configuration","read", inst_name, field_name, cntxt, r); if(r == null)
return ; value = r.read(cntxt); return ;
endfunction // function: set
//
// Create a new or update an existing configuration setting for
// ~field_name~ in ~inst_name~ from ~cntxt~.
// The setting is made at ~cntxt~, with the full scope of the set
// being {~cntxt~,".",~inst_name~}. If ~cntxt~ is ~null~ then ~inst_name~
// provides the complete scope information of the setting.
// ~field_name~ is the target field. Both ~inst_name~ and ~field_name~
// may be glob style or regular expression style expressions.
//
// If a setting is made at build time, the ~cntxt~ hierarchy is
// used to determine the setting's precedence in the database.
// Settings from hierarchically higher levels have higher
// precedence. Settings from the same level of hierarchy have
// a last setting wins semantic. A precedence setting of
// <uvm_resource_base::default_precedence> is used for uvm_top, and
// each hierarchical level below the top is decremented by 1.
//
// After build time, all settings use the default precedence and thus
// have a last wins semantic. So, if at run time, a low level
// component makes a runtime setting of some field, that setting
// will have precedence over a setting from the test level that was
// made earlier in the simulation.
//
// The basic ~set_config_*~ methods from <uvm_component> are mapped to
// this function as:
//
//| set_config_int(...) => uvm_config_db#(uvm_bitstream_t)::set(cntxt,...)
//| set_config_string(...) => uvm_config_db#(string)::set(cntxt,...)
//| set_config_object(...) => uvm_config_db#(uvm_object)::set(cntxt,...) static function void set(uvm_component cntxt,
string inst_name,
string field_name,
T value); uvm_root top;
uvm_phase curr_phase;
uvm_resource#(T) r;
bit exists;
string lookup;
uvm_pool#(string,uvm_resource#(T)) pool;
string rstate;
uvm_coreservice_t cs = uvm_coreservice_t::get(); //take care of random stability during allocation
process p = process::self();
if(p != null)
rstate = p.get_randstate(); top = cs.get_root(); curr_phase = top.m_current_phase; if(cntxt == null)
cntxt = top;
if(inst_name == "")
inst_name = cntxt.get_full_name();
else if(cntxt.get_full_name() != "")
inst_name = {cntxt.get_full_name(), ".", inst_name}; if(!m_rsc.exists(cntxt)) begin
m_rsc[cntxt] = new;
end
pool = m_rsc[cntxt]; // Insert the token in the middle to prevent cache
// oddities like i=foobar,f=xyz and i=foo,f=barxyz.
// Can't just use '.', because '.' isn't illegal
// in field names
lookup = {inst_name, "__M_UVM__", field_name}; if(!pool.exists(lookup)) begin
r = new(field_name, inst_name);
pool.add(lookup, r);
end
else begin
r = pool.get(lookup);
exists = ;
end if(curr_phase != null && curr_phase.get_name() == "build")
r.precedence = uvm_resource_base::default_precedence - (cntxt.get_depth());
else
r.precedence = uvm_resource_base::default_precedence; r.write(value, cntxt); if(exists) begin
uvm_resource_pool rp = uvm_resource_pool::get();
rp.set_priority_name(r, uvm_resource_types::PRI_HIGH);
end
else begin
//Doesn't exist yet, so put it in resource db at the head.
r.set_override();
end //trigger any waiters
if(m_waiters.exists(field_name)) begin
m_uvm_waiter w;
for(int i=; i<m_waiters[field_name].size(); ++i) begin
w = m_waiters[field_name].get(i);
if(uvm_re_match(uvm_glob_to_re(inst_name),w.inst_name) == )
->w.trigger;
end
end if(p != null)
p.set_randstate(rstate); if(uvm_config_db_options::is_tracing())
m_show_msg("CFGDB/SET", "Configuration","set", inst_name, field_name, cntxt, r);
endfunction // function: exists
//
// Check if a value for ~field_name~ is available in ~inst_name~, using
// component ~cntxt~ as the starting search point. ~inst_name~ is an explicit
// instance name relative to ~cntxt~ and may be an empty string if the
// ~cntxt~ is the instance that the configuration object applies to.
// ~field_name~ is the specific field in the scope that is being searched for.
// The ~spell_chk~ arg can be set to 1 to turn spell checking on if it
// is expected that the field should exist in the database. The function
// returns 1 if a config parameter exists and 0 if it doesn't exist.
// static function bit exists(uvm_component cntxt, string inst_name,
string field_name, bit spell_chk=);
uvm_coreservice_t cs = uvm_coreservice_t::get(); if(cntxt == null)
cntxt = cs.get_root();
if(inst_name == "")
inst_name = cntxt.get_full_name();
else if(cntxt.get_full_name() != "")
inst_name = {cntxt.get_full_name(), ".", inst_name}; return (uvm_resource_db#(T)::get_by_name(inst_name,field_name,spell_chk) != null);
endfunction // Function: wait_modified
//
// Wait for a configuration setting to be set for ~field_name~
// in ~cntxt~ and ~inst_name~. The task blocks until a new configuration
// setting is applied that effects the specified field. static task wait_modified(uvm_component cntxt, string inst_name,
string field_name);
process p = process::self();
string rstate = p.get_randstate();
m_uvm_waiter waiter;
uvm_coreservice_t cs = uvm_coreservice_t::get(); if(cntxt == null)
cntxt = cs.get_root();
if(cntxt != cs.get_root()) begin
if(inst_name != "")
inst_name = {cntxt.get_full_name(),".",inst_name};
else
inst_name = cntxt.get_full_name();
end waiter = new(inst_name, field_name); if(!m_waiters.exists(field_name))
m_waiters[field_name] = new;
m_waiters[field_name].push_back(waiter); p.set_randstate(rstate); // wait on the waiter to trigger
@waiter.trigger; // Remove the waiter from the waiter list
for(int i=; i<m_waiters[field_name].size(); ++i) begin
if(m_waiters[field_name].get(i) == waiter) begin
m_waiters[field_name].delete(i);
break;
end
end
endtask endclass
从上面可以看uvm_config_db#(type T=int) extends uvm_resource_db#(T),也是说uvm_config_db 只是对uvm_resource_db 重新封装了一次。对uvm_resource_db
的一些功能进行了扩展,在写入操作上重载了uvm_resource_db的set 函数,在读操作上新建了一个get 函数。
uvm_config_db——半个全局变量的更多相关文章
- node.js相关
node node最大的特点是单线程,因此一个只能有一个任务运行,大量采用异步操作. 某一个任务的后续操作一般采用回调函数的形式 var callback = function (error, val ...
- JavaScript模块化开发的那些事
模块化开发在编程开发中是一个非常重要的概念,一个优秀的模块化项目的后期维护成本可以大大降低.本文主要介绍了JavaScript模块化开发的那些事,文中通过一个小故事比较直观地阐述了模块化开发的过程. ...
- 008--VS2013 C++ 位图半透明化(另一种显示)
注:主要变化是在下面这张位图上的操作 //全局变量HBITMAP bg, girl;HDC mdc;//起始坐标const int xstart = 50;const int ystart = 20; ...
- 007--VS2013 C++ 显示位图半透明化
以后所有图片都放在根目录下: 如有另放,会特别注明 //全局变量HBITMAP bg,girl;HDC mdc; //起始坐标const int xstart = 50;const int ystar ...
- 深入MySQL复制(三):半同步复制
1.半同步复制 半同步复制官方手册:https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html 默认情况下,MySQL的复制是异 ...
- [转]java nio解决半包 粘包问题
java nio解决半包 粘包问题 NIO socket是非阻塞的通讯模式,与IO阻塞式的通讯不同点在于NIO的数据要通过channel放到一个缓存池ByteBuffer中,然后再从这个缓存池中读出数 ...
- uvm_config_db在UVM验证环境中的应用
如何在有效的使用uvm_config_db来搭建uvm验证环境对于许多验证团队来说仍然是一个挑战.一些验证团队完全避免使用它,这样就不能够有效利用它带来的好处:另一些验证团队却过多的使用它,这让验证环 ...
- 搭建MySQL的主从、半同步、主主复制架构
复制其最终目的是让一台服务器的数据和另外的服务器的数据保持同步,已达到数据冗余或者服务的负载均衡.一台主服务器可以连接多台从服务器,并且从服务器也可以反过来作为主服务器.主从服务器可以位于不同的网络拓 ...
- 分布式缓存系统 Memcached 半同步/半异步模式
在前面工作线程初始化的分析中讲到Memcached采用典型的Master_Worker模式,也即半同步/半异步的高效网络并发模式.其中主线程(异步线程)负责接收客户端连接,然后分发给工作线程,具体由工 ...
随机推荐
- bzoj4066
KD-tree 强制在线就不能愉快的做这道题了. 我们用KD-tree维护平面上的点,这样建出来的树高大概是log,复杂度过得去,但是插入过多会使树深很深,这样就能卡死,那么我们每个10000次插入就 ...
- 安装ubuntu+Windows双系统, Windows启动项消失
这里主要介绍grub分区损坏的问题: 首先介绍最简单的方法, 不确定能不能成功, 但是最好先用此方法, 毕竟最简单如果解决就不用下一个方法了. 1. (1)用U盘做一个ubuntu的镜像, 开机进入U ...
- 爬虫库之BeautifulSoup学习(一)
Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据. 官方解释如下: Beautiful Soup提供一些简单的.pytho ...
- tomcat+mysql+javaweb+docker
1.安装好docker 2.docker pull tomcat docker pull mysql 3.docker run -it -p 8080:8080 --rm tomcat:7.0 #-i ...
- 【Data Structure & Algorithm】在排序数组中查找和为定值的两个数
在排序数组中查找和为定值的两个数 题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字,要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出 ...
- as3杂记
一.内存回收方式: 1.引用计数[没有互相引用] 2.标记清除[fp自己检测是否引用,没有引用的清除] 二.通信方式: 1.http:小型页游[charles抓包查看] 2.socket:大型页游[W ...
- HDU - 1016 Prime Ring Problem 经典素数环
Prime Ring Problem A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., ...
- C#中var关键字用法分析
原文连接 本文实例分析了C#中var关键字用法.分享给大家供大家参考.具体方法如下: C#关键字是伴随着.NET 3.5以后,伴随着匿名函数.LINQ而来, 由编译器帮我们推断具体的类型.总体来说,当 ...
- HDU2222【AC自动机(基础·模板)】
Frist AC zi dong ji(Aho-Corasick Automation) of life #include <bits/stdc++.h> using namespace ...
- Lightoj1122 【数位DP】
题意: 给你m个数,让你在里面挑n个组合,保证位数相差不超过2,求能够组合多少种情况: 思路: dp[i][j]代表第i个结尾为j的方案数. #include<bits/stdc++.h> ...