UVM——寄存器模型

寄存器模型概览

硬件中的各个功能模块可以由处理器来配置功能以及访问状态,而与处理器的对话即是通过寄存器的读写来实现的。
寄存器的硬件实现是通过触发器,而每一个比特位的触发器都对应着寄存器的功能描述(function specification)。一个寄存器一般由32个比特位构成,将单个寄存器拆分后,又可以分为多个域(field),不同的域往往代表着某一项独立的功能。单个的域可能由多个比特位构成,也可能有单一比特位构成,这取决于该域的功能模式可配置的数量。
而不同的域,对于外部的读写而言,又大致可以分为WO(write-only,只写),RO(read-only,只读), RW(read and write,读写),除了这些常见的操作属性以外,还有一些特殊行为(quirky)的寄存器,例如读后擦除模式(clean-on-read,RC),只写一次模式(write-one-to-set,W1S)。
在这里插入图片描述
MCDF的寄存器模块描述,将0x00功能寄存器和0x10状态寄存器位用图来表示。通常来讲,一个寄存器有32位宽,寄存器按照地址索引的关系式按字对其(word-align)的,上图中的寄存器有多个域,每个域的属性也可以不相同,reserved域表示的是该域所包含的比特位暂时保留以作日后功能的扩展使用,而对保留域的读写不起任何作用,即无法写入而且读出值也是它的复位值。
上面的这些寄存器按照地址排列,即可构成寄存器列表,我们称之为寄存器块(register block)。实际上寄存器模块除了包含寄存器,也可以包含存储器,因为它们的属性都近乎于读写功能,以及表示为同外界通信的接口。
将这些寄存器有机的组合在一起,MCDF的寄存器功能模块即可由这样一个register block来表示:
在这里插入图片描述
一个寄存器可以由多个域构成,而单个域可以包含多个比特位;一个功能模块中的多个寄存器可以组团构成一个寄存器模型(register model)。上图中除了包含DUT的寄存器模块(由硬件实现),还有属于验证环境的寄存器模型。
这两个模块包含的寄存器信息是高度一致的,属于验证环境的寄存器模型也可以抽象出一个层次化的寄存器列表,该列表所包含的地址、域、属性等信息都与硬件一侧的寄存器内容一致。
对于功能验证而言,可以将总线访问寄存器的方式抽象为寄存器模型访问的方式,这种方式使得寄存器后期的地址修改(例如基地址更改)或者域的添加都不会对已有的激励构成影响,从而提高已有的测试序列的复用性。

中心化管理方式

在这里插入图片描述
中心化管理的寄存器描述文件,可以使通过软件建立寄存器模型和硬件寄存器的内容属性保持一致,通常使用XML格式的寄存器描述文件,或Execl(CSV)和DOC格式。采用中心化管理的原因是单一源的管理方式可以尽量降低出现分歧或错误的可能。
寄存器描述文档使用了结构化的文档描述方式,通过数据结构化的存储方式,可以在硬件和软件开发过程中以不同的方式来使用寄存器描述文档:
- 系统工程师会撰写并维护寄存器描述文件,而后归置到中心化存储路径供其他的工程师使用。
- 硬件工程师会利用寄存器描述文档生成寄存器硬件模块(包含各个寄存器的硬件实现和总线访问模块)。
- 验证工程师会利用寄存器描述文档来生成UVM寄存器模型,一共验证过程中的激励使用、寄存器测试和功能覆盖率收集。
- 软件工程师会利用该文件生成用于软件开发的寄存器配置的头文件(header file),从而提高软件开发的可维护性。
- 寄存器描述文件也可以用来生成文档,实现更好的可读性。

uvm_reg相关概念

在构建UVM寄存器模型的过程中,需要了解与模型构建相关的类和他们的功能:

类名 功能
uvm_reg_field 用来针对寄存器功能域来构建对应的比特位
uvm_reg 与寄存器相匹配,其内部可以例化和配置多个uvm_reg_field对象
uvm_mem 匹配硬件存储模型
uvm_reg_map 用来指定寄存器列表中各个寄存器的偏移地址访问属性以及对应的总线
uvm_reg_block 可以容纳多个寄存器(uvm_reg)、存储器(uvm_mem),寄存器列表(uvm_reg_map)

MCDF寄存器模型实例

class ctrl_reg extends uvm_reg;
	`uvm_object_utils(ctrl_reg)
	uvm_reg_field reserved;
	rand uvm_reg_field pkt_len;	
	rand uvm_reg_field prio_level;
	rand uvm_reg_field chnl_en;
	function new(string name = "ctrl_reg");
		super.new(name, 32, UVM_NO_CONVERAGE);
	endfunction
	virtual function build();
		reserved = uvm_reg_field::type_id::create("reserved"
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
UVM提供了uvm_reg_backdoor类,用于在测试中访问寄存器的内部实现。这个类可以让我们在测试中使用不同的方式来访问寄存器,以验证寄存器的功能和性能。 uvm_reg_backdoor类主要有两个方法: - `void read(uvm_reg_item rw)`:读取寄存器的值,将结果存储在rw.value中。 - `void write(uvm_reg_item rw)`:写入寄存器的值,将值存储在rw.value中。 其中,`uvm_reg_item`是一个包含寄存器地址、写入/读取值等信息的uvm序列化对象。 要使用uvm_reg_backdoor类,我们需要创建一个新类,继承自uvm_reg_backdoor。在新类的构造函数中,我们需要调用基类的构造函数,并通过该函数将要访问的寄存器作为参数传递。 下面是一个使用uvm_reg_backdoor类的示例: ```systemverilog class my_reg_backdoor extends uvm_reg_backdoor; `uvm_object_utils(my_reg_backdoor) function new(string name = "my_reg_backdoor"); super.new(name); endfunction virtual function void read(uvm_reg_item rw); // 从寄存器中读取值 endfunction virtual function void write(uvm_reg_item rw); // 将值写入寄存器 endfunction endclass ``` 在测试中,我们可以使用uvm_reg_backdoor类的实例来访问寄存器。例如: ```systemverilog my_reg_backdoor my_bd = new; uvm_reg_item rw = new; rw.element = my_reg; rw.kind = UVM_REG; rw.path = UVM_FRONTDOOR; rw.offset = 0; rw.value[0] = 0x1234; my_bd.write(rw); // 从寄存器中读取值 my_bd.read(rw); $display("value = %h", rw.value[0]); ``` 使用uvm_reg_backdoor类可以方便地访问寄存器的内部实现,从而进行更全面和深入的验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值