uvm Register Access Methods(16)
转载:
译文:https://blog.csdn.net/zhajio/article/details/80731435
原文:http://cluelogic.com/2013/02/uvm-tutorial-for-candy-lovers-register-access-methods/
UVM的寄存器抽象层(RAL)提供了几种访问寄存器的方法。 这篇文章将解释寄存器访问方法的工作原理。 在Register Abstraction中,我们介绍了RAL的概述并解释了如何定义寄存器。 在这篇文章中,我们将介绍如何访问寄存器。
uvm_reg_field的属性
在深入了解寄存器访问方法之前,让我们看看如何存储寄存器值。 如寄存器抽象中所示,uvm_reg_field是表示寄存器的位的最低寄存器抽象层。 uvm_reg_field使用多个属性来存储各种寄存器字段值:
- m_reset [“HARD”]存储硬重置值(hard reset)。 请注意,m_reset是一种带有一种重置键的关联数组。
- m_mirrored存储我们在待测试设计(DUT)中所认为应该存储的值。
- m_desired存储我们想要设置给DUT的值。
- value将要采样的值存储在功能覆盖率中,或者当该字段被随机化时将value约束。
请注意,在这些属性中,只有值属性是公共的。 其他属性是本地的,因此我们无法直接从类外访问它们。 稍后我们将向您介绍如何使用寄存器访问方法访问这些本地属性。
uvm_reg_field的属性
configure()
我们在创建uvm_reg_field后执行的第一件事是配置它。在寄存器抽象中,我们如下配置flavor字段。请注意,在Register Abstraction中,我们将flavor字段定义为“WO”(只写),但我们在此将其定义为“RW”(读/写),以使该字段更通用。
flavor = uvm_reg_field::type_id::create( "flavor" ); flavor.configure( .parent ( this ), .size ( 3 ), .lsb_pos ( 0 ), .access ( "RW" ), .volatile ( 0 ), .reset ( 0 ), .has_reset ( 1 ), .is_rand ( 1 ), .individually_accessible( 0 ) );
如果has_reset参数为1,则复位参数的值将被视为“HARD”复位值。如果has_reset值为0,则复位值将被忽略。复位值应与DUT的复位状态相匹配。如果您想在配置后修改复位值,可以使用set_reset()方法。
flavor.set_reset( .value( 0 ), .kind( "HARD" ) ); // kind == "HARD" by default
configure()和set_reset()方法如何工作
reset()
如果m_reset [kind]存在,reset()方法将重置寄存器字段的属性。默认类型是“HARD”。如果m_reset [kind]不存在,则reset()方法不执行任何操作。请注意,reset()方法不会复位DUT中的寄存器。它只复位寄存器字段对象的属性。
flavor.reset( .kind( "HARD" ) ); // kind == "HARD" by default
reset()方法如何工作
set()
set()方法设置寄存器字段的期望值。 set()方法不会将值设置为DUT中的寄存器的值。它只将值设置为m_desired和寄存器字段对象的值属性。要真正将值设置为DUT中的寄存器,请使用write()或update()方法。这些方法将在稍后解释。
flavor.set( .value( 1 ) );
get()
get()方法获取寄存器字段的期望值。 get()方法不会从DUT中的寄存器获取值。它只获取m_desired属性的值。要实际从DUT获取值,请使用read()或mirror()方法。这些方法将在稍后解释。与get()方法类似,还有两个getter访问本地属性。 get_reset()检索m_reset [kind]属性的值,而get_mirrored_value()方法检索m_mirrored属性的值。
uvm_reg_data_t desired_value = flavor.get(); uvm_reg_data_t reset_value = flavor.get_reset( .kind( "HARD" ) ); // kind == "HARD" by default uvm_reg_data_t mirrored_value = flavor.get_mirrored_value();
randomize()
randomize()方法是一个SystemVerilog方法。它随机化一个寄存器字段对象的值属性。随机化后,post_randomize()方法将value属性的值复制到m_desired属性。请注意,如果value属性的rand_mode为OFF,则pre_randomize()方法会将m_desired的值复制到value属性。
assert( flavor.randomize() );
write()
write()方法实际上向DUT写入一个值。
uvm_status_e status; flavor.write( .status( status ), .value( 1 ) );
write()方法涉及多个步骤。
- 创建与写入操作对应的uvm_reg_item对象。
- uvm_reg_adapter将写入操作转换为相应的总线事务。
- uvm_driver执行到DUT的总线事务。
- uvm_monitor捕获总线事务。
- uvm_reg_predictor要求uvm_reg_adapter将总线事务转换为相应的寄存器操作。
- 寄存器操作转换为uvm_reg_item。
- uvm_reg_item用于更新值,m_mirrored和m_desired属性。
请注意,如果在配置寄存器字段时个别可访问参数为0,则包含该字段的整个寄存器会被写入,因为该字段不可单独访问。在这种情况下,m_mirrored值将用作其他字段的写入值。
read()
read()方法实际上从DUT中读取一个寄存器值。
uvm_status_e status;
uvm_reg_data_t value;
flavor.read( .status( status ), .value( value ) );
与write()方法类似,read()方法涉及多个步骤。
- 创建与读操作对应的uvm_reg_item对象。
- uvm_reg_adapter将读取操作转换为相应的总线事务。
- uvm_driver执行到DUT的总线事务。
- uvm_reg_apapter将读取数据的总线事务转换为寄存器操作。
- read()方法将读取值返回给调用者。
- 同时,uvm_monitor捕获总线事务。
- uvm_reg_predictor要求uvm_reg_adapter将总线事务转换为相应的寄存器操作。
- 寄存器操作转换为uvm_reg_item。
- uvm_reg_item用于更新值,m_mirrored和m_desired属性。
请注意,如果在配置寄存器字段时individually_accessible
参数为0,则会读取包含字段的整个寄存器。在这种情况下,也会为其他字段更新m_mirrored值。
update()
update()方法实际上是向DUT写入一个寄存器值。 update()方法属于uvm_reg类。 uvm_reg_field类没有update()方法。
uvm_status_e status;
jb_recipe_reg.update( .status( status ) );
write()方法和update()方法之间的区别是:
- write()方法将一个值作为其参数,而update()方法使用m_desired属性的值作为要写入的值。
- 只有当m_mirrored和m_desired不相等时,update()方法才写入该值。
update()方法在内部调用write(.value(m_desired))。因此,更新后,m_mirrored的值也会更新。
mirror()
mirror()方法实际上是从DUT读取一个寄存器。
uvm_status_e status;
flavor.mirror( .status( status ), .check( UVM_CHECK ) );
read()方法和mirror()方法之间的区别是:
- read()方法返回寄存器值给调用者,而mirror()方法不返回寄存器值。 mirror()方法只更新m_mirrored属性的值。
- 如果check参数的值为UVM_CHECK,则mirror()方法将读取值与m_desired进行比较。
请注意,UVM类库文档指出,它将读取值与镜像值进行比较,但如果您查看uvm-1.1c代码库的uvm_reg.svh的第2,944行,它实际上会与所需的值进行比较,而不是针对镜像值。
2014年4月11日:uvm-1.1d代码库已纠正此问题。mirror()将读取值与镜像值进行比较。如果您对此修复感兴趣,请参阅uvm_reg.svh的第2,951行。)
关于检查的另一个警告是,如果在配置寄存器字段时将volatile参数设置为1,则即使将check参数设置为UVM_CHECK,也不会检查寄存器字段。这是因为我们无法确定性地预测寄存器字段的值,因为它可能在DUT中被更改(易失性)。
mirror()方法在内部调用do_read()方法。这是与read()方法内部调用的相同方法。因此,除m_mirrored属性外,mirror()方法还会更新值和m_desired属性。
predict()
predict()方法更新镜像值。
flavor.predict( .value( 1 ) );
predict()方法也会更新值和m_desired属性。
Summary
下表总结了每种方法如何更新寄存器字段对象的属性。
Method | m_reset | value | m_desired | m_mirrored | DUT |
---|---|---|---|---|---|
configure |
set the value of val |
||||
set_reset(val) |
set the value of val |
||||
reset() |
copy the value of m_reset |
copy the value of m_reset |
copy the value of m_reset |
||
set(val) |
set the value of val |
set the value of val |
|||
get_reset() |
return the value of m_reset |
||||
get() |
return the value of m_desired |
||||
get_mirrored_value() |
return the value of m_mirrored |
||||
randomize() |
randomize | copy the value of value |
|||
write(.value(val)) |
set the value of val |
set the value of val |
set the value of val |
write the value of val |
|
read(.value(val)) |
set the read value | set the read value | set the read value | read the register | |
update() |
set the value of m_desired |
set the value of m_desired |
set the value of m_desired |
write the value of m_desired |
|
mirror() |
set the read value | set the read value | set the read value | read the register | |
predict |
set the value of val |
set the value of val |
set the value of val |
在这篇文章中,我们只介绍了所谓的前门访问。我们将在单独的帖子中介绍后门访问。我希望本教程能帮助您理解寄存器的访问方法。
原文中有一些QA可以加深理解。
原文地址:https://www.cnblogs.com/zhiminyu/p/12706990.html
- 联发科将推出两款芯片,拥有AI和人脸识别技术,能和高通叫板吗?
- 谷歌AI黑科技曝光:合成语音与真人声音难以区分
- 小程序是什么?有什么用?
- Aibee融资1.65亿元 曾16.8万元秒下aibee.cn
- 小程序审核攻略
- js checkbox.checked=true在document.body.appendChild(checkbox)前与后赋值
- 吹得飞起的人工智能,2017都摔过哪些跟头?
- 排序还可以这样做
- 韩政府公布虚拟货币投机行为打击对策
- SqlServer2005数据库文件损坏的拯救过程
- 2017年,人类在自己设计的所有游戏中都败给了AI,无一幸免
- 测试组,请用VSS命令行获取最新版本
- 想起温习一下JS中的this apply call arguments
- 学习利用JSON 摆脱表单与业务对象双向转换的繁琐工作
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 他被导师半夜敲门叫醒:你得诺贝尔奖了!还曾为5G频谱拍卖设计方案,担任谷歌IPO咨询顾问
- C#实现——十大排序算法之选择排序
- CSS高级技巧 CSS用户界面样式
- 从零开始针对 .NET 应用的 DevOps 运营实践 - 运行环境搭建
- Sentinel断路器与熔断降级【源码笔记】
- 数据分析、数据挖掘基础:描述统计学基础知识分享!
- 前端开发必会的HTML/CSS硬知识
- 前端开发必会的HTML/CSS硬知识 (二)
- 移动web开发之rem布局
- less 基础
- 【淘宝】实现一个函数用来解析 URL 的 querystring
- 移动端WEB开发之响应式布局
- Scala学习二-面向对象
- kafka学习三-broker的入口
- Go开源ORM——GORM