0. 引言

  在UVM支持的寄存器操作中,有get、update、mirror、write等等一些方法,在这里整理一下他们的用法。

  寄存器模型中的寄存器值应该与DUT保持同步,但是由于DUT的值是实时更新的,所以寄存器模型并不能实时知道这种更新,在寄存器模型中专门有个值来尽可能与DUT中寄存器的值保持一致,叫镜像值(mirrorred value)。寄存器模型中还有一个值叫期望值(respected value),这个值保存我们希望写入寄存器的值。比如希望向DUT某个寄存器写入'h1,用set函数设置期望值,然后用update任务(update会比较镜像值和期望值,如果不一样,将期望值写入DUT,并更新镜像值)。

1.  函数

1.1 set

virtual function void set (	uvm_reg_data_t 	value,	 string 	fname	 = 	"",int 	lineno	 = 	0	)

  设置模型中寄存器的期望值,不会改变DUT中这个寄存器的值。

1.2 get

virtual function uvm_reg_data_t get(	string 	fname	 = 	"", int 	lineno	 = 	0	)

  返回模型中寄存器的期望值,而不是DUT中的寄存器值

1.3 get_mirrored_value

virtual function uvm_reg_data_t get_mirrored_value(	string 	fname	 = 	"", int 	lineno	 = 	0	)

  返回模型中寄存器的镜像值。

1.4 get_reset

virtual function uvm_reg_data_t get_reset(	string 	kind	 = 	"HARD"	)

  返回寄存器的复位值。

1.5 predict

virtual function bit predict (	uvm_reg_data_t 	value,
  uvm_reg_byte_en_t be = -1,
  uvm_predict_e kind = UVM_PREDICT_DIRECT,
  uvm_path_e path = UVM_FRONTDOOR,
  uvm_reg_map map = null,
  string fname = "",
  int lineno = 0 )

  更新模型中的镜像值。新的镜像值通过value参数传入。

  当在DUT中实现一个计数器的时候,模型中的计数器是静止的。如果想在模型中得到DUT的技术值,这就需要手动更新镜像值,又不能对DUT进行操作,这可以通过predict函数。

第三个参数是uvm_predict_e枚举类型,他有如下三个元素:

UVM_PREDICT_DIRECT Predicted value is as-is
UVM_PREDICT_READ Predict based on the specified value having been read
UVM_PREDICT_WRITE Predict based on the specified value having been written

如果想要更新镜像值又不对DUT进行操作,要用UVM_PREDICT_DIRECT。

  write、read、peek和poke在完成对DUT的读写之后也会调用这个函数,更新镜像值。

1.6 randomize

  无论是uvm_reg,还是uvm_field、uvm_block,都是支持randomize()。

assert(rm.invert.reg_data.randomize());
assert(rm.invert.randomize());
assert(rm.randomize()):

  

  当寄存器随机化后,期望值会被随机,但是镜像值不变,之后调用update任务,可以更新DUT中的寄存器值。

  但是一个field能够被随机化,需要:

    1. 在filed的configure第八个参数设为1.

    2. filed为rand类型。

    3. filed的读写类型为可写的。

2. 任务

2.1  update

virtual task update(	output 	uvm_status_e 	status,
  input uvm_path_e path = UVM_DEFAULT_PATH,
  input uvm_reg_map map = null,
  input uvm_sequence_base parent = null,
  input int prior = -1,
  input uvm_object extension = null,
  input string fname = "",
  input int lineno = 0 )

  将模型中的期望值更新到DUT中。改变DUT中的寄存器。update会检查模型中的期望值和镜像值,如果两者不相等,那么将期望值更新到DUT中,并且更新镜像值。update与mirror操作相反。

  如果镜像值和期望值相同,那么不会写DUT寄存器,也就不会产生总线transaction。

2.2 mirror

virtual task mirror(	output 	uvm_status_e 	status,
  input uvm_check_e check = UVM_NO_CHECK,
  input uvm_path_e path = UVM_DEFAULT_PATH,
  input uvm_reg_map map = null,
  input uvm_sequence_base parent = null,
  input int prior = -1,
  input uvm_object extension = null,
  input string fname = "",
  input int lineno = 0 )

  读DUT中寄存器的值,与update操作相反。如果第二个参数check为UVM_CHECK,那么会检查读取的值与镜像值是否一样,如果不一样报错。通过mirror读取DUT的寄存器值之后,会调用predict函数,更新镜像值。

  mirror有两种应用场景:一是在仿真中不断调用,但此时是UVM_NO_CHECK,保证镜像值与DUT中的值相等;二是在仿真结束的时候调用,这时是UVM_CHECK检查模型中的镜像值与DUT中的寄存器值是否一致。

2.3 write

virtual task write(	output 	uvm_status_e 	status,
  input uvm_reg_data_t value,
  input uvm_path_e path = UVM_DEFAULT_PATH,
  input uvm_reg_map map = null,
  input uvm_sequence_base parent = null,
  input int prior = -1,
  input uvm_object extension = null,
  input string fname = "",
  input int lineno = 0 )

  模仿DUT的行为,通过前门或者后门方式向DUT中写入寄存器值,会产生总线transaction。并且调用predict更新镜像值。

  uvm_path_e定义寄存器操作类型,如下:

UVM_FRONTDOOR Use the front door
UVM_BACKDOOR Use the back door
UVM_PREDICT Operation derived from observations by a bus monitor via the uvm_reg_predictor class.
UVM_DEFAULT_PATH Operation specified by the context

  我在使用中,如果用set_auto_predict(1)——采取自动更行镜像值的方式,write之后,调用get和get_mirrored_value都能得到新写入的值。  

  如果关闭auto_predict,用uvm_reg_predict来更新镜像值,我在在使用中write之后,调用get和get_mirrored_value得到0

  如果是read任务,那么无论是auto_predict还是uvm_reg_predict都会自动更新镜像值和期望值。

  链接:https://github.com/east1203/uvm_codes/tree/master/tb1_wd/a.uvm_reg_predict

2.4 read

virtual task read(	output 	uvm_status_e 	status,
  output uvm_reg_data_t value,
  input uvm_path_e path = UVM_DEFAULT_PATH,
  input uvm_reg_map map = null,
  input uvm_sequence_base parent = null,
  input int prior = -1,
  input uvm_object extension = null,
  input string fname = "",
  input int lineno = 0 )

  模仿DUT的行为,通过前门或者后门方式读取DUT中寄存器的值,并更新镜像值,会产生总线transaction

2.5 peek

virtual task poke(	output 	uvm_status_e 	status,
  input uvm_reg_data_t value,
  input string kind = "",
  input uvm_sequence_base parent = null,
  input uvm_object extension = null,
  input string fname = "",
  input int lineno = 0 )

  通过后门访问方式读取寄存器的值,不关心DUT的行为,即使寄存器的读写类型是不能读,也可以将值读出来

  对于read clear类型的field,peek读操作不会clear。所以有的时候peek和read操作结果不一样

2.6 poke

virtual task peek(	output 	uvm_status_e 	status,
  output uvm_reg_data_t value,
  input string kind = "",
  input uvm_sequence_base parent = null,
  input uvm_object extension = null,
  input string fname = "",
  input int lineno = 0 )

  通过后门访问方式写入寄存器的值,不关心DUT的行为,即使寄存器的读写类型是不能写,也可以将值写进去

  对于write clear类型的filed,poke操作不会clear,所以有的时候poke和write操作结果不一样。

UVM——寄存器模型相关的一些函数的更多相关文章

  1. UVM RAL模型和内置seq

    转载:UVM RAL模型:用法和应用_寄存器 (sohu.com) 在系统设计中通常会面临两大挑战:缩小技术节点的规模和上市时间(TTM,Time to Market).为了适应激烈的市场竞争,大多数 ...

  2. posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

    posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属 ...

  3. (笔记)Linux内核中内存相关的操作函数

    linux内核中内存相关的操作函数 1.kmalloc()/kfree() static __always_inline void *kmalloc(size_t size, gfp_t flags) ...

  4. uvm_reg_sequence——寄存器模型(六)

    寄存器模型 uvm_reg_sequence是UVM自带所有register sequence 的基类. 该类包含model, adapter, reg_seqr(uvm_sequencer). 感觉 ...

  5. uvm_reg_model——寄存器模型(一)

    对于一个复杂设计,寄存器模型要能够模拟任意数量的寄存器域操作.UVM提供标准的基类库,UVM的寄存器模型来自于继承自VMM的RAL(Register Abstract Layer),现在可以先将寄存器 ...

  6. [炼丹术]UNet图像分割模型相关总结

    UNet图像分割模型相关总结 1.制作图像分割数据集 1.1使用labelme进行标注 (注:labelme与labelImg类似,都属于对图像数据集进行标注的软件.但不同的是,labelme更关心对 ...

  7. Entity Framework 6 Recipes 2nd Edition(10-5)译 -> 在存储模型中使用自定义函数

    10-5. 在存储模型中使用自定义函数 问题 想在模型中使用自定义函数,而不是存储过程. 解决方案 假设我们数据库里有成员(members)和他们已经发送的信息(messages) 关系数据表,如Fi ...

  8. OVERLAPPED相关的socket函数介绍

    OVERLAPPED相关的socket函数介绍 上一篇文章介绍了<Windows核心编程>OVERLAPPED结构与内核对象IOCompletionPort相关概念,见http://www ...

  9. Mariadb MySQL逻辑条件判断相关语句、函数使用举例介绍

    MySQL逻辑条件判断相关语句.函数使用举例介绍 By:授客 QQ:1033553122 1.  IFNULL函数介绍 IFNULL(expr1, expr2) 说明:假如expr1 不为NULL,则 ...

随机推荐

  1. Redis的常用命令与Java整合及高级应用篇

    一,redis是什么? ​ 首先数据库分为关系型数据库和非关系型数据库,关系型数据库是采用关系模型来组织数据的数据库,简单来说就是二维表格模型,同时保证事务的一致性. ​ 相反非关系型数据库采用key ...

  2. Kibana 管理界面使用教程

    使用浏览器访问 ip:5601 默认端口,进入首页 Discover:日志管理视图 Visualize:统计视图 Dashboard:仪表视图 Timelion:时间轴视图 APM:性能管理视图 De ...

  3. antd模糊搜索和远程数据的结合

    //用到此方法的情景  先根据input框中的姓名模糊搜索出客户名称,当选中客户名称之后,获取ID ,根据客户的ID,去搜索数据列表. 防抖方法 let timeout; let currentVal ...

  4. 17_defer(延迟调用)关键字的使用

    1.defer是延迟调用关键字,只能在函数内部使用 2.总是在main函数结束前调用(和init用法相对) 3.如果有多个defer 遵循先进后出的原则 4.和匿名函数同时使用时,如果匿名函数带有参数 ...

  5. 第二篇 特征点匹配以及openvslam中的相关实现详解

    配置文件 在进入正题之前先做一些铺垫,在openvslam中,配置文件是必须要正确的以.yaml格式提供,通常需要指明使用的相机模型,ORB特征检测参数,跟踪参数等. #==============# ...

  6. Java深层复制方式

    为什么需要深层复制 Object 的 clone() 方法是浅层复制(但是 native 很高效).另外,Java 提供了数组和集合的复制方法,分别是 Arrays.copy() 和 Collecti ...

  7. 【qt】【QString的诸多操作】

    前言: qt的数据处理莫过于QString,QString对于字符串的操作多的数不胜数.下面博主就将常用的罗列出来,一起分享. 正文: 下面的操作具体为:追加,查找,删除,提取,分割,各种转换等等. ...

  8. 2019 Multi-University Training Contest 9

    A. Rikka with Quicksort 题意 求 EX 快速排序复杂度. 做法 根据线性期望可加性,独立考虑长度为 \(m\) 的区段对答案的贡献.进行简单的公式推导,对 \(s(x)=\su ...

  9. HDU-6333 Problem B. Harvest of Apples 莫队

    HDU-6333 题意: 有n个不同的苹果,你最多可以拿m个,问有多少种取法,多组数据,组数和n,m都是1e5,所以打表也打不了. 思路: 这道题要用到组合数的性质,记S(n,m)为从n中最多取m个的 ...

  10. CF - 652 D Nested Segments

    题目传送门 题解: 可以将所有线段按照左端点优先小,其次右端点优先大进行排序. 然后对于第 i 条线段来说, 那么第 i+1 ---- n 的线段左端点都一定在第i条线段的右边, 接下来就需要知道 i ...