UVMC学习笔记二

--- 跨语言作用域的config操作

前言:UVMC引入了特定的内存共享方法,可以在UVM/SystemVerilog与SystemC模块之间传递记名的半全局变量,在使用方式上类似UVM build-in提供的config_db方法,可以传递字符串,整形数据(byte/int/bit-- char/int/long)和对象结构,在传递对象时需要对packet 结构打包成字符流。

一 . config api函数

在UVM layer的config函数与惯例一致,需要通过泛型指定传递的数据类型,对于UVMC 所在的SystemC layer,有set/get 各3个传递函数,用于传递字符串,整型数据 及对象结构。

1.1 UVMC 的set 方法用于在指定层次的上下文中创建或更新字段配置,主要通过三种函数来实现

uvmc_set_config_object("uvm_tlm_generic_payload","e.prod","","trans", tr);
uvmc_set_config_string ("e.prod", "", "message", "Hello from SystemC!");
uvmc_set_config_int ("e.prod", "", "start_addr", 0x1234);

这些函数建立配置设置,将它们存储为资源数据库中的资源条目,以便以后通过get_config调用进行查找。它们不会直接影响目标字段的值。当组件层次结构在UVM的构建阶段构建时,组件就会出现并建立它们的上下文。一旦知道了它的上下文,每个组件就可以调用get_config来检索应用于它的任何配置设置。配置参数的名称由field_name参数指定。

当UVM处于build_phase时,与任何其他阶段相比,set方法的语义是不同的。如果在构建阶段进行了set调用,则上下文确定数据库中的优先级。来自层次结构中较高级别(例如,mytop.test1)的set调用优先于来自较低级别(例如,mytop.test1.env.agent)的对同一字段的set调用。在相同层次结构级别上进行的Set调用具有相同的优先级,因此每个Set调用都会覆盖前一个Set调用的字段值。

在build_phase之后,所有set调用都具有相同的优先级,而与它们的层次上下文无关。每个set调用都会覆盖前一个调用的值。

  • set函数的参数说明
以使用uvmc_set_config_object传递对象为例,共有5个参数:
(1)type_name:UVM Connect将利用factory来分配这种类型的对象,并将序列化的值解包到其中。不支持参数化类
(2)context:组件的层次结构路径,或指定uvm_top的空字符串。可以使用通配符(*和?)指定多个组件,例如“top.env.*.driver”。
还可以通过将contxt括在前斜杠中来指定POSIX扩展正则表达式,例如“hp/b/”。默认值:(uvm_top)
(3)inst_name:相对于指定的上下文,配置的对象的实例路径。可以包含通配符还是正则表达式, 即目的层次,可以留空,视为全局
空间参数的广播。
(4)filed_name:配置参数的名称。通常此名称与用于保存目标上下文中配置的值的变量相同或类似
(5)value:值必须具有为其定义的uvmc_convert<object_type专门化。使用转换器方便宏是可以接受的,以满足这一要求
  • 对于uvmc_set_config_stringuvmc_set_config_int 已经指明传参类型的函数,则只需要四个参数,省略type_name。

1.2 UVMC 的get 方法用于获取指定层次上下文的配置字段值

如果成功,则返回true;如果无法在给定上下文中找到配置设置,则返回false。如果为假,则值引用未修改。get方法主要通过三种函数来实现:

uvmc_get_config_object("uvm_tlm_generic_payload","e","prod","trans", tr2);
uvmc_get_config_string ("e", "prod", "message", str);
uvmc_get_config_int ("e.prod", "", "start_addr", saddr);

上下文指定搜索在该层次结构级别或更高级别上创建的字段的配置设置作为起始点,即get config可以搜索指定层次更高的级别。inst_name是相对于上下文的显式实例名,如果上下文是配置设置应用于的完整上下文,则可能是空字符串,上下文和inst_name字符串必须是简单字符串——没有通配符或正则表达式。

  • get函数的参数
(1)type_name : 仅供uvmc_get_config_object。指定要检索的等效对象的类型名SV。UVM Connect将检查从配置数据库检索到的对象是否与此类型名匹配。
如果匹配,对象将被序列化(打包)并跨语言边界返回。
(2)context : 正在代表其检索指定配置的组件的层次结构路径。不允许通配符或正则表达式。上下文必须与现有组件的层次结构名称完全匹配,
或者是指定uvm_top的空字符串 ,对象区域
(3)inst_name : 相对于指定的上下文,正在配置的对象的实例路径,目标域
(4)filed_name : 配置参数的名称。通常,此名称与用于保存目标上下文中配置的值的变量名称一致
(5)value : 配置参数的值。整数值目前不能超过64位。对象值必须具有为其定义的uvmc_convert<object_type>专门化。
使用转换器方便宏是可以接受的,以满足这一要求。SV中的等价类必须基于uvm_object并在UVM工厂

二、UVM 打包器与转换器说明:

在uvm systemVerilog testbench 一侧可用于传递的对象必须派生自uvm_object 类,并实现其中的do_packdo_unpack回调函数,由于序列化需要使用factory方法,所以封包类必须使用uvm_object_utils注册。

class prod_cfg extends uvm_object;`uvm_object_utils(prod_cfg);function new(string name="producer_config_inst");super.new(name);endfunctionint min_addr = 'h00;int max_addr = 'hff;int min_data_len = 10;int max_data_len = 80;int max_trans = 5;virtual function void do_pack(uvm_packer packer);`uvm_pack_int(min_addr)`uvm_pack_int(max_addr)`uvm_pack_int(min_data_len)`uvm_pack_int(max_data_len)`uvm_pack_int(max_trans)endfunctionvirtual function void do_unpack(uvm_packer packer);`uvm_unpack_int(min_addr)`uvm_unpack_int(max_addr)`uvm_unpack_int(min_data_len)`uvm_unpack_int(max_data_len)`uvm_unpack_int(max_trans)endfunctionfunction string convert2string();return $sformatf("min_addr:%h max_addr:%h min_data_len:%0d max_data_len:%0d max_trans:%0d",min_addr, max_addr, min_data_len, max_data_len,max_trans);endfunctionendclass
  • do_packdo_unpack 的的序列化打包,注意使用uvm_packer 作为形参接口,注意在打包中需要使用uvm_pack/unpakc_int , uvm_pack/unpack_enum将成员变量做封装处理
  • 在示例中,congvet2string属于非强制必须实现函数

在systemC layer中,为了准确讲从sv传递而来的packet做反序列化,需要构造一个成员类型与sv object一致的对象类作为反序列化转换的标准类型,实例如下:

class prod_cfg {public:int min_addr;int max_addr;int min_data_len;int max_data_len;int max_trans;
};UVMC_UTILS_5(prod_cfg, min_addr, max_addr, min_data_len, max_data_len, max_trans);

需要注意的是,UVMC_UTILS_N 这个标准宏,其为给定的对象类型生成专用的打包,解包,打印功能。主要有如下两种宏:

UVMC_UTILS_<N> (TYPE, <list of N variables> )
UVMC_UTILS_EXT_<N> (TYPE, BASE, <list of N variables> )

  • 第一种宏中N 代表将要打包的对象中的变量数量,TYPE为对象类型,后面变量为需要打包的变量,
  • 第二种宏则表示为增量打包,其中TYPE为对象原型,BASE为已有对象,后续为增量打包的变量,其中N为增量打包的变量数量

三、完整的UVMC和UVM之间通过config传递变量和对象的实例

#include "uvmc.h"
#include "uvmc_macros.h"
using namespace uvmc;class prod_cfg {public:int min_addr;int max_addr;int min_data_len;int max_data_len;int max_trans;
};UVMC_UTILS_5(prod_cfg,min_addr,max_addr,min_data_len,max_data_len,max_trans)// (end inline source)#include <string>
#include <iostream>
#include "systemc.h"
#include "tlm.h"
#include "uvmc.h"using namespace std;
using namespace sc_core;
using namespace tlm;
using namespace uvmc;#include "consumer.cpp"SC_MODULE(top)
{consumer cons;SC_CTOR(top) : cons("consumer") {SC_THREAD(show_uvm_config);uvmc_connect(cons.in,"foo");uvmc_connect(cons.analysis_out,"bar");}void show_uvm_config();};
// (end inline source)void top::show_uvm_config()
{string s = "Greetings from SystemC";uint64 i = 2;prod_cfg cfg;cfg.min_addr=0x100;cfg.max_addr=0x10f;cfg.min_data_len=1;cfg.max_data_len=8;cfg.max_trans=2;wait(SC_ZERO_TIME);UVMC_INFO("TOP/SET_CFG","Calling set_config_* to SV-side instance 'e.prod'",UVM_MEDIUM,"");uvmc_set_config_int    ("e.prod", "", "some_int", i);uvmc_set_config_string ("", "e.prod", "some_string", s.c_str());uvmc_set_config_object ("prod_cfg", "e", "prod", "config", cfg);// Wait until the build phase. The SV side will have used get_config// to retreive our settingsuvmc_wait_for_phase("build", UVM_PHASE_ENDED);i=0;s="";cfg.min_addr=0;cfg.max_addr=0;UVMC_INFO("TOP/GET_CFG", \"Calling get_config_* from SV-side context 'e.prod'", \UVM_MEDIUM,"");// Get and check our int, string, and object configuration if (uvmc_get_config_int ("e.prod", "", "some_int", i))cout << "get_config_int : some_int=" << hex << i << endl;elseUVMC_ERROR("GET_CFG_INT_FAIL", "get_config_int failed",name());if (uvmc_get_config_string ("e.prod", "", "some_string", s))cout << "get_config_string: some_string=" << s << endl;elseUVMC_ERROR("GET_CFG_STR_FAIL", "get_config_string failed",name());if (uvmc_get_config_object ("prod_cfg", "e.prod", "", "config", cfg))cout << "get_config_object: config = " << cfg << endl;elseUVMC_ERROR("GET_CFG_OBJ_FAIL", "get_config_object failed",name());
}int sc_main(int argc, char* argv[])
{  top t("t");sc_start();return 0;
}
  • 在UVM 层的打包操作为:
function void check_config();int i;string str;uvm_object obj;if (!uvm_config_db #(uvm_bitstream_t)::get(this,"","some_int",i))`uvm_error("NO_INT_CONFIG",{"No configuration for field 'some_int'"," found at context '",get_full_name(),"'"})else`uvm_info("INT_CONFIG",$sformatf("Config for field 'some_int' at context '%s' has value %0h",get_full_name(),i),UVM_NONE)if (!uvm_config_db #(string)::get(this,"","some_string",str))`uvm_error("NO_STRING_CONFIG",{"No configuration for field 'some_string'"," found at context '",get_full_name(),"'"})else`uvm_info("STRING_CONFIG",{"Config for field 'message' at context '", get_full_name(),"' has value '", str,"'"},UVM_NONE)if (!uvm_config_db #(uvm_object)::get(this,"","config",obj))`uvm_error("NO_OBJECT_CONFIG",{"No configuration for field 'config'"," found at context '",get_full_name(),"'"})else beginprod_cfg c;if (!$cast(c,obj))`uvm_error("BAD_CONFIG_TYPE", {"Object set for configuration field 'config' at context '",get_full_name(),"' is not a prod_cfg type"})else begincfg = c;`uvm_info("OBJECT_CONFIG",{"Config for field 'config' at context '",get_full_name(),"' has value '", cfg.convert2string(),"'"},UVM_NONE)endendendfunction

需要注意的是,由于在打包传递的过程中,存在序列化和反序列化的过程,因此对于在uvm sv中get到该变量需要首先用uvm_object 类型的句柄指向传递而来的反序列化对象,并使用动态cast将其转化为目标对象类型,以防止内存共享过程中数据流传递的错误。

[UVMC]UVMC学习笔记之跨语言作用域的config操作相关推荐

  1. 【学习笔记】C++语言程序设计(郑莉):数据的共享与保护

    [学习笔记]C++语言程序设计(郑莉):数据的共享与保护 1. 标识符的作用域与可见性 1.1 作用域 1.1.1 函数原型作用域 1.1.2 局部作用域 1.1.3 类作用域 1.1.4 命名空间作 ...

  2. 【学习笔记】C++语言程序设计(郑莉):继承与派生

    [学习笔记]C++语言程序设计(郑莉):继承与派生 1. 类的继承与派生 1.1 派生类的定义 1.2 派生类生成过程 2. 访问控制 3. 类型兼容规则 4. 派生类的构造和析构函数 4.1 构造函 ...

  3. 23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter

    23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter 2016-07-22 (www.cnblogs.com/icmzn) 模式理解 1. Adapter 定义 ...

  4. Java快速入门学习笔记9 | Java语言中的方法

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  5. Java快速入门学习笔记8 | Java语言中的数组

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  6. Java快速入门学习笔记7 | Java语言中的类与对象

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  7. Java快速入门学习笔记3 | Java语言中的表达式与操作符

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  8. Java快速入门学习笔记2 | Java语言中的基本类型

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  9. [编译原理学习笔记2-2] 程序语言的语法描述

    [编译原理学习笔记2-2] 程序语言的语法描述 文章目录 [编译原理学习笔记2-2] 程序语言的语法描述 [2.3.1] 上下文无关文法 [2.3.2] 语法分析树与二义性 [2.3.3] 形式语言鸟 ...

最新文章

  1. 通过修改软链接升高 gcc 版本、降低 gcc 版本
  2. 戴尔服务器重装系统优盘启动不了怎么办,U盘重装系统,开机按F12选择USB启动项无法进入PE系统怎么办?...
  3. javascript定时器及Date对象
  4. Linux的性能故障的含义,Linux排查性能故障的方法
  5. Linux进程全解10——守护进程
  6. python任务栏显示网速_win10状态栏显示网速小工具_超好用
  7. VNC实现Windows远程访问Ubuntu 16.04(无需安装第三方桌面)
  8. 5G时代的Android App开发入门与项目实战
  9. CTF-实验吧-天下武功唯快不破
  10. 写在2019年的最后一天,有感而发
  11. 读论文《Toward Controlled Generation of Text》
  12. Java发送附件到邮箱
  13. 计算机网络图片大全,心情图片大全
  14. 批量创建工作表并以本月日期命名——《超级处理器》应用
  15. IP地址 、域名、 URL、 端口
  16. 推荐 macwk 的替代品: minorpatch.com
  17. [转]Google Linux Cluster的系统结构分析(余一娇)
  18. DataPipeline亮相“2021科技助力湾区数字金融发展峰会”,解锁“实时数据管理”密码
  19. 分布式架构实现概述(大型网站技术架构-读后感)
  20. Android input 系统InputReader,InputDispatcher线程实例--UI死掉

热门文章

  1. 叔本华论艺术和科学的一段话
  2. Java调用OpenCV来识别面部或眼睛
  3. Jmeter的Response Body中返回乱码/问号,当所有的方法都试了还是不行,可以尝试下面的方法
  4. 车联网基础知识之SOW、NRE费用、license费用
  5. 02《需求模式——软件建模与分析》
  6. 【CodeForces 626E】Simple Skewness
  7. javascript opener 用法
  8. Java使用google身份验证器实现动态口令验证
  9. UML-数据流图心得总结
  10. html中字体的单位,CSS中字体单位:px、em、rem和%