转载:UVM RAL模型:用法和应用_寄存器 (sohu.com)
在系统设计中通常会面临两大挑战:缩小技术节点的规模和上市时间(TTM,Time to Market)。为了适应激烈的市场竞争,大多数系统都是以通用方式设计的,这意味着同一设计可以通过不同的配置实现不同的应用方式。配置数量越多,设计中的寄存器数量越多。最重要的是,由于当前市场对数据存储的大量需求,存储大小也越来越大。为了访问和验证大量寄存器和巨大的存储,需要一些创新的方法。因此,UVM提供了用于寄存器管理及访问的基类库,称为UVM RAL(Register Abstraction Layer,寄存器抽象层)。
顾名思义,UVM RAL是访问设计寄存器的高级面向对象抽象层。RAL模型模仿了设计寄存器,并且整个模型是完全可配置的。由于其抽象行为,RAL模型可以 轻松地从模块级别迁移到系统级别。
本文提供了有关UVM RAL的不同级别的相关内容,包括:如何将同一个RAL模型用于多个接口,RAL模型内部的存储实现及其访问方法,预测器模型的信息以及根据其操作预测寄存器值等。它还有一个现成的UVM寄存器序列列表。仅通过配置这些序列,用户就可以访问和验证所有设计寄存器和存储的功能。
介绍:
任何设计验证的首要步骤是其寄存器验证,即检查寄存器的可访问性及其功能。执行此寄存器验证,并不一定需要使用UVM RAL模型,但是在不使用它进行验证时,用户必须注意每个寄存器的属性和复位值。同样,用户必须确保使用所有可能的值来验证每个寄存器域。在整个寄存器范围内手动执行这些检查是一项很耗时的任务,因此使用UVM RAL模型是一种非常有效的方法。
UVM RAL是面向设计内部寄存器的模型。要访问这些设计寄存器,UVM RAL提供了现成的基类和API。RAL模型的一些特性包括:
- 就像寄存器的设计一样,它支持不同的寄存器属性,例如R / W,RO,WO,W1C等。
- 支持两种不同的寄存器访问路径,前门访问和后门访问。
- 同一模型可以通过多条总线访问。
- 它的抽象性质允许在模块级别以及系统级别使用相同的模型。
- 内置比较方法,可将寄存器值与其预测值进行比较。
每个RAL模型主要具有以下三个结构层次:
- uvm_reg_block是最顶层的层次结构,通常,uvm_reg_block具有所有寄存器(uvm_reg)的一个实例,或者可能具有其他uvm_reg_block的实例。
- uvm_reg模拟设计内部的寄存器。根据其定义,每个寄存器可以具有一个或多个uvm_reg_field。
- uvm_reg_field代表寄存器的域。
图1 RAL层次图解
RAL模型模仿设计寄存器,更新设计寄存器的值,同时更新RAL模型寄存器的值。为此,UVM具有通用的API,可以同时更新设计和RAL模型寄存器。除寄存器外,RAL模型也可以用来对存储建模,其优点之一是burst 操作。本文的后半部分中,给出了一个存储burst操作的示例,同时提供了有关预测器模型,寄存器覆盖率和UVM预定义寄存器序列的一些信息。
RAL寄存器映射和适配器
RAL模型集成的基本步骤之一是适配器(adapter)类的实现。此类具有两个基本的函数:bus2reg用于将总线sequence items转换为uvm_reg_bus_op(RAL模型中已知),和reg2bus实现相反的功能。用户定义的适配器类应通过扩展uvm_reg_adapter基类来实现。这意味着所有前门寄存器的读/写操作都通过此适配器类进行。由于适配器类的实现取决于总线,因此,每个总线都必须具有自己的适配器类。
每个前门寄存器的写/读操作都通过reg2bus和bus2reg API进行。对于不同的总线,例如APB和AXI,如果它们访问相同的RAL模型,则需要为每条总线创建适配器类。因此,对于每个寄存器映射,必须按如下所示设置RAL模型sequencer:
使用特定寄存器map访问RAL模型寄存器的示例:
UVM存储器
UVM RAL模型也可以用来对存储建模,称为uvm_mem。像uvm_reg一样,uvm_mem的目的在于模仿设计内部的存储器。下面的代码显示了如何在RAL模型中实现存储建模:
该存储器的优点之一是其burst读/写操作,如下所示:
像寄存器一样,存储器访问也可以通过前门和后门进行。uvm_mem没有空间来存储期望的数据,这意味着该uvm_mem的缺点之一是它不支持内置数据比较。
UVM预测器
如前所述,寄存器模型具有内置的自检机制。每当访问寄存器时,uvm_reg都会更新为相同的值,并且该值会变为其预测值。这种预测可以通过三种不同的方式进行:
- 隐式预测
- 显式预测
- 被动预测
隐式预测
隐式预测是最简单、最常见的预测方法。每当发生寄存器写/读操作时,UVMRAL模型基类都会调用该特定uvm_reg类的predict方法。要启用此功能,用户必须调用uvm_reg_map的set_auto_predict(1)方法,如下所示。默认情况下,该方法是禁用的。
图2 隐式预测流程
如上图所示,启用自动预测后,寄存器模型会在每次写/读操作时预测该值。在这里,期望用户必须通过调用uvm_reg的write或read方法来启动寄存器操作。
显式预测
使用显式预测,用户必须创建uvm_reg_predictor类的句柄,该类是RAL模型的基类。该预测器类需要与监视器类相连。监视器对发生在接口上的寄存器写/读操作进行采样,并将捕捉到的事务传递给预测器。Predictor类借助适配器将总线事务转换为寄存器事务,然后调用该寄存器的predict方法。
在编码方面,利用三个基本步骤可以实现显式预测:创建,配置和连接。
-
创建
-
配置
-
连接
这种预测方法的优势在于,因为预测是基于接口上驱动的数据进行的,所以寄存器模型总是与实际数据保持同步。
被动预测
当未通过寄存器模型进行寄存器读/写操作时,此方法很有用。被动预测根据在总线接口上观察到的操作来预测寄存器值,与显式预测非常相似。
寄存器覆盖率
UVM RAL提供了一个API来采样用户定义的覆盖组。为了对这些覆盖组进行采样,用户必须覆盖(override)uvm_reg/uvm_reg_block类的sample方法。对于RAL模型覆盖,用户必须使能寄存器预测。
以下代码显示了扩展uvm_reg_block内部的covergroup实现,其中涵盖了寄存器及其操作。
下面的uvm_reg类内部的covergroup实现示例显示,其意图是覆盖访问寄存器所用的不同值。
选择性覆盖组采样也是可能的,为此,用户必须提供适当的功能覆盖类型标识符。
UVM RAL预定义序列
UVM软件包提供了一组现成的序列,以测试寄存器的功能,例如其访问或复位值。所有这些序列在操作上都是唯一的,其中有几个寄存器序列的描述如下表所示:
序列名称 |
功能 |
uvm_reg_hw_reset_seq |
检查每个寄存器的复位值是否与硬件复位值匹配。 |
uvm_reg_bit_bash_seq |
检查所有支持读写访问的域,依次写入1和0,并读出后做比较,用于检查寄存器域属性的有效性。 |
uvm_reg_access_seq |
用前门访问方式写入每个寄存器,从后门读回数值进行比较。然后执行反向操作,即通过后门进行写操作,并通过前门进行检查。 |
uvm_mem_walk_seq |
在目标存储的指定地址范围的每个地址写入数据,并将其与读取值进行比较。 |
uvm_mem_access_seq |
对于存储器的每个位置,通过前门写入,从后门读回数值进行比较。然后,执行反向操作,即通过后门进行写操作,并通过前门进行验证。 |
uvm_reg_shared_access_seq |
通过每个地址映射写入所有寄存器,并通过读取所有地址映射来确认其写入值。 |
uvm_mem_shared_access_seq |
通过每个地址映射写入所有内存位置,并通过读取所有地址映射确定其写入值。 |
uvm_reg_mem_shared_access_seq |
执行uvm_reg_shared_access_seq,然后执行uvm_mem_shared_access_seq |
uvm_reg_mem_built_in_seq |
执行所选/所有上述预定义序列。 |
uvm_reg_mem_hdl_paths_seq |
检查指定的HDL路径是否可访问。 |
上述每个测试都有一个禁用属性,用户可以通过该属性跳过任何寄存器/存储器的特定测试。通过设置属性:“NO_REG_TEST”或“NO_MEM_TEST”,用户可以从上述所有测试中排除特定的寄存器/存储器。
总结
UVM RAL是访问和验证设计寄存器和存储器的简单方法。与实际设计一样,uvm_mem支持burst写入和读取操作。除了访问寄存器之外,UVM还有现成的API,可用于对寄存器覆盖率进行采样。此外,由于不同UVM寄存器预定义序列的多个场景,寄存器验证的任务也变得简单。由于其分层结构和大量可用的API,RAL模型具有足够的灵活性。除了以标准方式访问API外,用户还可以使用这些API进行其他一系列操作,例如,通过其地址访问寄存器或更新任何特定的寄存器域。总体而言,UVM RAL是功能强大的抽象层,它支持寄存器验证所需的所有功能,并且由于其组织结构,强烈建议在基于UVM的测试平台中利用RAL模型进行寄存器验证。
原文来自:
https://www.design-reuse.com/articles/46675/uvm-ral-model-usage-and-application.html