(二)UVM_RAL 寄存器模型之基础夯实

目录

一,为何应用寄存器模型

二,寄存器模型基础概念

2.1  uvm_reg_field

2.2  uvm_reg

2.3  uvm_reg_block

2.4  uvm_reg_map

2.5  uvm_reg_file

2.6  uvm_mem

三,一个完备的寄存器模型

三, 如何instance到UVM验证环境


RAL(Register Abstract Layer,寄存器抽象层),也被称之为寄存器模型,顾名思义就是对寄存器这个部件的建模。本文主要内容包括:为何应用寄存器模型,UVM寄存器模型基础概念,如何构建寄存器模型,如何将寄存器模型实例到验证环境中。

一,为何应用寄存器模型

前面,我们提到,寄存器的使用,在如今的design 中十分普遍。对于实际的DUT, 我们可以选择不同的配置组合,达到DUT 实现不同的功能,比如配置不同的寄存器功能,实现不同的状态机跳转,进而实现不同的功能。有些人把这种design 方式,称之为 基于寄存器的设计。我们身为DV人员,当然着重关注我们验证人员该关注的事情。

寄存器设计,作为DUT 设计的一部分,当然在整个design Verification 过程中,也是验证人员必须面对和打交道的一部分。对REG 的读写配置,包括验证覆盖率的统计,都是值得验证人员该花功夫考虑的问题,也是项目signoff 阶段,项目验收的环节之一。

大部分DUT设计,对于内部寄存器的access, 大部分公司都会选择当今比较流行总线方式。一方面,选取标准的寄存器配置总线协议,可以加速项目迭代;另一方面,选取标准的协议,一般都会购买第三方IP,可以保证很好的quality。比如:I2C,SPI,AXI,AHB 、APB等总线 ,复杂到PCIE、SATA、GMI 等复杂协议。

实际激励中,不仅包括接口正常transaction,还有寄存器的读写激励,所以有必要针对寄存器的access , 构建寄存器访问机制,方便验证环境的搭建和集成,加速项目的验收。

为什么要对寄存器建模,可能是初学者问得较多的问题。简单地说,寄存器建模要做的事情,就是在软件的世界里面,复刻RTL中的寄存器。既然是面向软件世界做的事情,自然就是为软件所用要么方便软件观测,要么方便软件使用。这里的软件,指的是整个验证环境所构造出来的面向对象的世界。有了寄存器模型,软件世界中的参考模型(reference model)可以很方便的获取到当前RTL的功能配置和状态,也可以很方便的收集到对寄存器各个域段甚至位的测试覆盖情况等。

二,寄存器模型基础概念

2.1  uvm_reg_field

这是寄存器模型中的最小单位。什么是reg_field?假如有一个状态寄存器,

 如上的状态寄存器共有四个域,分别是empty、full、overflow、underflow。这四个域对应寄存器模型中的uvm_reg_field。名字reserved”的并不是一个域。

uvm_reg_field 源码分析: 

1)属性声明

2)方法声明

2.2  uvm_reg

它比uvm_reg_field高一个级别,依然是比较小的单位。一个寄存器中至少包一个uvm_reg_field。

uvm_reg源码概览: 

1)属性声明

2)方法声明

   extern virtual function void set_offset (uvm_reg_map    map,
   /*local*/ extern virtual function void set_parent (uvm_reg_block blk_parent,
   /*local*/ extern virtual function void add_field  (uvm_reg_field field);
   /*local*/ extern virtual function void add_map    (uvm_reg_map map);
   extern virtual function string get_full_name();
   extern virtual function uvm_reg_block get_parent ();
   extern virtual function uvm_reg_block get_block  ();
   extern virtual function uvm_reg_file get_regfile ();
   extern virtual function int get_n_maps ();
   extern virtual function void get_maps (ref uvm_reg_map maps[$]);
   /*local*/ extern virtual function uvm_reg_map get_local_map   (uvm_reg_map map,
   /*local*/ extern virtual function uvm_reg_map get_default_map (string caller = "");
   extern virtual function string get_rights (uvm_reg_map map = null);
   extern virtual function int unsigned get_n_bits ();
   extern virtual function int unsigned get_n_bytes();
   extern virtual function void get_fields (ref uvm_reg_field fields[$]);
   extern virtual function uvm_reg_field get_field_by_name(string name);
   extern virtual function uvm_reg_addr_t get_offset (uvm_reg_map map = null);
   extern virtual function uvm_reg_addr_t get_address (uvm_reg_map map = null);
   extern virtual function int get_addresses (uvm_reg_map map = null,
   extern virtual function void set (uvm_reg_data_t  value,
   extern virtual function uvm_reg_data_t  get(string  fname = "",
   extern virtual function uvm_reg_data_t  get_mirrored_value(string  fname = "",
   extern virtual function bit needs_update(); 
   extern virtual function void reset(string kind = "HARD");
   extern virtual function uvm_reg_data_t
   extern virtual function bit has_reset(string kind = "HARD",
   extern virtual function void
   extern virtual task write(output uvm_status_e      status,
   extern virtual task read(output uvm_status_e      status,
   extern virtual task poke(output uvm_status_e      status,
   extern virtual task peek(output uvm_status_e      status,
   extern virtual task update(output uvm_status_e      status,
   extern virtual task mirror(output uvm_status_e      status,
   extern virtual function bit predict (uvm_reg_data_t    value,
   /*local*/ extern virtual function bit Xcheck_accessX
   extern virtual function bit do_check(uvm_reg_data_t expected,
   extern virtual task do_write(uvm_reg_item rw);
   extern virtual task do_read(uvm_reg_item rw);
   extern virtual function void do_predict
   extern virtual task backdoor_read(uvm_reg_item rw);
   extern virtual task backdoor_write(uvm_reg_item rw);
   extern virtual function uvm_status_e backdoor_read_func(uvm_reg_item rw);
   extern virtual protected function void add_coverage(uvm_reg_cvr_t models);
   extern virtual function bit has_coverage(uvm_reg_cvr_t models);
   extern virtual function uvm_reg_cvr_t set_coverage(uvm_reg_cvr_t is_on);
   extern virtual function bit get_coverage(uvm_reg_cvr_t is_on);
   extern virtual function void            do_print (uvm_printer printer);
   extern virtual function string          convert2string();
   extern virtual function uvm_object      clone      ();
   extern virtual function void            do_copy    (uvm_object rhs);
   extern virtual function bit             do_compare (uvm_object  rhs,
   extern virtual function void            do_pack    (uvm_packer packer);
   extern virtual function void            do_unpack  (uvm_packer packer);

2.3  uvm_reg_block

它是一个比较大的单位,在其中可以加入许多的uvm_reg,也可以加入其他的uvm_reg_block。一个寄存器模型中至少包含一个uvm_reg_block。

同uvm_reg派生的类一样,每一个由uvm_reg_block派生的类也要定义一个build函数,一般在此函数中实现所有寄存器的实例化。

一个uvm_reg_block中一定要对应一个uvm_reg_map,系统已经有一个声明好的default_map,只需要在build中将其实例化。这个实例化的过程并不是直接调用uvm_reg_map的new函数,而是通过调用uvm_reg_block的create_map来实现,create_map有众多的参数,其中第一个参数是名字,第二个参数是基地址,第三个参数则是系统总线的宽度,这里的单位是byte而不是bit,第四个参数是大小端,最后一个参数表示是否能够按照byte寻址

随后实例化invert并调用invert.configure函数。这个函数的主要功能是指定寄存器进行后门访问操作时的路径。其第一个参数是此寄存器所在uvm_reg_block的指针,这里填写this,第二个参数是reg_file的指针(7.4.2节将会介绍reg_file的概念)这里暂时填写null,第三个参数是此寄存器的后门访问路径,关于这点请参考7.3节,这里暂且为空。当调用完configure时,需要手动调用
invert的build函数,将invert中的域实例化。
 

最后一步则是将此寄存器加入default_map中。uvm_reg_map的作用是存储所有寄存器的地址,因此必须将实例化的寄存器加入default_map中,否则无法进行前门访问操作。add_reg函数的第一个参数是要加入的寄存器,第二个参数是寄存器的地址,这里是16’h9,第三个参数是此寄存器的存取方式。

uvm_reg_block 源码概览:

1)属性声明

2)方法声明

   extern virtual function uvm_reg_map create_map(string name,
   extern virtual function void set_parent(uvm_reg_block parent);
   extern virtual function void lock_model();
   extern virtual function string get_full_name();
   extern virtual function uvm_reg_block get_parent();
   extern virtual function void get_blocks (ref uvm_reg_block  blks[$],
   extern virtual function void get_maps (ref uvm_reg_map maps[$]);
   extern virtual function void get_registers (ref uvm_reg regs[$],
   extern virtual function void get_fields (ref uvm_reg_field  fields[$],
   extern virtual function void get_memories (ref uvm_mem mems[$],
   extern virtual function void get_virtual_registers(ref uvm_vreg regs[$],
   extern virtual function void get_virtual_fields (ref uvm_vreg_field fields[$],
   extern virtual function uvm_reg_block get_block_by_name (string name);  
   extern virtual function uvm_reg_map get_map_by_name (string name);
   extern virtual function uvm_reg get_reg_by_name (string name);
   extern virtual function uvm_reg_field get_field_by_name (string name);
   extern virtual function uvm_mem get_mem_by_name (string name);
   extern virtual function uvm_vreg get_vreg_by_name (string name);
   extern virtual function uvm_vreg_field get_vfield_by_name (string name);
   extern virtual protected function void add_coverage(uvm_reg_cvr_t models);
   extern virtual function bit has_coverage(uvm_reg_cvr_t models);
   extern virtual function uvm_reg_cvr_t set_coverage(uvm_reg_cvr_t is_on);
   extern virtual function bit get_coverage(uvm_reg_cvr_t is_on = UVM_CVR_ALL);
   extern virtual function void sample_values();
   extern virtual function uvm_path_e get_default_path();
   extern virtual function void reset(string kind = "HARD");
   extern virtual function bit needs_update();
   extern virtual task update(output uvm_status_e       status,
   extern virtual task mirror(output uvm_status_e       status,
   extern virtual task write_reg_by_name(
   extern virtual task read_reg_by_name(
   extern virtual task write_mem_by_name(
   extern virtual task read_mem_by_name(
   extern virtual task readmemh(string filename);
   extern virtual task writememh(string filename);
   extern virtual function void   do_print      (uvm_printer printer);
   extern virtual function void   do_copy       (uvm_object rhs);
   extern virtual function bit    do_compare    (uvm_object  rhs,
   extern virtual function void   do_pack       (uvm_packer packer);
   extern virtual function void   do_unpack     (uvm_packer packer);
   extern virtual function string convert2string ();
   extern virtual function uvm_object clone();

2.4  uvm_reg_map

每个寄存器在加入寄存器模型时都有其地址,uvm_reg_map就是存储这些地址,并将其转换成可以访问的物理地址(因为加入寄存器模型中的寄存器地址一般都是偏移地址,而不是绝对地址)。当寄存器模型使用前门访问方式来实现读或写操作时,uvm_reg_map就会将地址转换成绝对地址,启动一个读或写的sequence,并将读或写的结果返回。在每个reg_block内部,至少有一个(通常也只有一个)uvm_reg_map。

   extern virtual function void add_reg (uvm_reg           rg,
   extern virtual function void add_mem (uvm_mem        mem,
   extern virtual function void add_submap (uvm_reg_map    child_map,
   extern virtual function void set_sequencer (uvm_sequencer_base sequencer,
   extern virtual function void set_submap_offset (uvm_reg_map submap,
   extern virtual function uvm_reg_addr_t get_submap_offset (uvm_reg_map submap);
   extern virtual function void   set_base_addr (uvm_reg_addr_t  offset);
   extern virtual function void reset(string kind = "SOFT");
   /*local*/ extern virtual function void add_parent_map(uvm_reg_map  parent_map,
   /*local*/ extern virtual function void Xverify_map_configX();
   /*local*/ extern virtual function void m_set_reg_offset(uvm_reg   rg,
   /*local*/ extern virtual function void m_set_mem_offset(uvm_mem mem,
   extern virtual function string get_full_name();
   extern virtual function uvm_reg_map get_root_map();
   extern virtual function uvm_reg_block get_parent();
   extern virtual function uvm_reg_map           get_parent_map();
   extern virtual function uvm_reg_addr_t get_base_addr (uvm_hier_e hier=UVM_HIER);
   extern virtual function int unsigned get_n_bytes (uvm_hier_e hier=UVM_HIER);
   extern virtual function int unsigned get_addr_unit_bytes();
   extern virtual function uvm_endianness_e get_endian (uvm_hier_e hier=UVM_HIER);
   extern virtual function uvm_sequencer_base get_sequencer (uvm_hier_e hier=UVM_HIER);
   extern virtual function uvm_reg_adapter get_adapter (uvm_hier_e hier=UVM_HIER);
   extern virtual function void  get_submaps (ref uvm_reg_map maps[$],
   extern virtual function void  get_registers (ref uvm_reg regs[$],
   extern virtual function void  get_fields (ref uvm_reg_field fields[$],
   extern virtual function void  get_memories (ref uvm_mem mems[$],
   extern virtual function void  get_virtual_registers (ref uvm_vreg regs[$],
   extern virtual function void  get_virtual_fields (ref uvm_vreg_field fields[$],
   extern virtual function uvm_reg_map_info get_reg_map_info(uvm_reg rg,  bit error=1);
   extern virtual function uvm_reg_map_info get_mem_map_info(uvm_mem mem, bit error=1);
   extern virtual function int unsigned get_size();
   extern virtual function int get_physical_addresses(uvm_reg_addr_t        base_addr,
   extern virtual function uvm_reg get_reg_by_offset(uvm_reg_addr_t offset,
   extern virtual function uvm_mem    get_mem_by_offset(uvm_reg_addr_t offset);
   extern virtual task do_bus_write (uvm_reg_item rw,
   extern virtual task do_bus_read (uvm_reg_item rw,
   extern virtual task do_write(uvm_reg_item rw);
   extern virtual task do_read(uvm_reg_item rw);
   extern virtual function string      convert2string();
   extern virtual function uvm_object  clone();
   extern virtual function void        do_print (uvm_printer printer);
   extern virtual function void        do_copy   (uvm_object rhs);
   //extern virtual function bit       do_compare (uvm_object rhs, uvm_comparer comparer);
   //extern virtual function void      do_pack (uvm_packer packer);
   //extern virtual function void      do_unpack (uvm_packer packer);

2.5  uvm_reg_file

UVM还提供了uvm_reg_file类。这个类更像是一个对象容器,可以用来装载多个寄存器(uvm_reg)和其他uvm_reg_file,以便对相同规格的寄存器进行多次例化。

   extern virtual function string        get_full_name();
   extern virtual function uvm_reg_block get_parent ();
   extern virtual function uvm_reg_block get_block  ();
   extern virtual function uvm_reg_file  get_regfile     ();
   extern virtual function void          do_print (uvm_printer printer);
   extern virtual function string        convert2string();
   extern virtual function uvm_object    clone      ();
   extern virtual function void          do_copy    (uvm_object rhs);
   extern virtual function bit           do_compare (uvm_object  rhs,
   extern virtual function void          do_pack    (uvm_packer packer);
   extern virtual function void          do_unpack  (uvm_packer packer);

2.6  uvm_mem

在同一类族中,UVM还提供了uvm_mem类,用于对连续地址存储空间的建模。uvm_mem对象也可以被集成到uvm_reg_block中,并通过uvm_reg_map做地址映射,

  extern virtual function void set_offset (uvm_reg_map    map,
   /*local*/ extern virtual function void set_parent(uvm_reg_block parent);
   extern virtual function string get_full_name();
   extern virtual function uvm_reg_block get_parent ();
   extern virtual function uvm_reg_block get_block  ();
   extern virtual function int get_n_maps ();
   extern virtual function void get_maps (ref uvm_reg_map maps[$]);
   extern virtual function string get_rights (uvm_reg_map map = null);
   extern virtual function string get_access(uvm_reg_map map = null);
   extern virtual function void get_virtual_registers(ref uvm_vreg regs[$]);
   extern virtual function void get_virtual_fields(ref uvm_vreg_field fields[$]);
   extern virtual function uvm_vreg get_vreg_by_name(string name);
   extern virtual function uvm_vreg_field  get_vfield_by_name(string name);
   extern virtual function uvm_vreg get_vreg_by_offset(uvm_reg_addr_t offset,
   extern virtual function uvm_reg_addr_t  get_offset (uvm_reg_addr_t offset = 0,
   extern virtual function uvm_reg_addr_t  get_address(uvm_reg_addr_t  offset = 0,
   extern virtual function int get_addresses(uvm_reg_addr_t     offset = 0,
   extern virtual task write(output uvm_status_e       status,
   extern virtual task read(output uvm_status_e        status,
   extern virtual task burst_write(output uvm_status_e      status,
   extern virtual task burst_read(output uvm_status_e      status,
   extern virtual task poke(output uvm_status_e       status,
   extern virtual task peek(output uvm_status_e       status,
   extern virtual task do_write (uvm_reg_item rw);
   extern virtual task do_read  (uvm_reg_item rw);
   extern virtual protected task backdoor_read(uvm_reg_item rw);
   extern virtual task backdoor_write(uvm_reg_item rw);
   extern virtual function uvm_status_e backdoor_read_func(uvm_reg_item rw);
   extern virtual protected function void add_coverage(uvm_reg_cvr_t models);
   extern virtual function bit has_coverage(uvm_reg_cvr_t models);
   extern virtual function uvm_reg_cvr_t set_coverage(uvm_reg_cvr_t is_on);
   extern virtual function bit get_coverage(uvm_reg_cvr_t is_on);
   extern virtual function void do_print (uvm_printer printer);
   extern virtual function string convert2string();
   extern virtual function uvm_object clone();
   extern virtual function void do_copy   (uvm_object rhs);
   extern virtual function bit do_compare (uvm_object  rhs,
   extern virtual function void do_pack (uvm_packer packer);
   extern virtual function void do_unpack (uvm_packer packer);

三,一个完备的寄存器模型

注意:多个寄存器及其访问译码表最终构成寄存器组。在同个数字系统不同总线视角下,寄存器组可以映射到不同的基地址(base)。因此,一个寄存器组除了可以包含多个寄存器,还可以有多个译码表。 

三, 如何instance到UVM验证环境

试想,如果仅仅是简单把寄存器模型集成到验证环境,那么只要例化寄存器模型就可以了。

现在主要的问题是,建立怎样的机制才可以让寄存器模型“实时”复刻RTL寄存器的值。

 为了解决这个问题,UVM引入Prediction机制,而且用到了两个新的组件:Adapter和Predictor。请看下节内容。

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
UVM (Universal Verification Methodology) provides a set of classes and macros to facilitate verification of hardware designs. One of the key components in UVM is the register model, which represents the registers and memories in the design. UVM provides a callback mechanism called UVM Callbacks (uvm_callbacks) to handle events and actions during the register access process. UVM register callbacks (uvm_reg_cbs) are a specific type of callback used for registering certain events related to register accesses. UVM register callbacks allow users to customize and extend the behavior of UVM register operations. These callbacks can be used to perform additional tasks before or after register read/write operations, such as logging, synchronization, or checking certain conditions. To use UVM register callbacks, you need to define a class derived from uvm_reg_callback and implement the desired callback methods. These methods will be called by UVM framework when corresponding events occur during register access. Here's an example of using UVM register callbacks: ```systemverilog class my_reg_callback extends uvm_reg_cbs; function new(string name = "my_reg_callback"); super.new(name); endfunction virtual function void pre_read(uvm_reg rg); // Perform pre-read tasks endfunction virtual function void post_read(uvm_reg rg); // Perform post-read tasks endfunction virtual function void pre_write(uvm_reg rg); // Perform pre-write tasks endfunction virtual function void post_write(uvm_reg rg); // Perform post-write tasks endfunction endclass // Register the callback with the desired register block my_reg_callback reg_cb = new(); my_register_block.my_register.add_callback(reg_cb); ``` In this example, `my_reg_callback` is a user-defined class derived from `uvm_reg_cbs`. It defines the callback methods `pre_read`, `post_read`, `pre_write`, and `post_write` which will be called by UVM framework at corresponding events. The callback object `reg_cb` is created and added to the desired register block using the `add_callback` method. This will enable the callback functionality for the specific register block. Please note that this is just a basic example, and there are more advanced features and options available for UVM register callbacks. The UVM User Guide provides detailed information on using and customizing register callbacks.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那么菜

你的鼓励和批评是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值