APB_timer中的寄存器模型集成——代码理解

本文详细介绍了在UVM环境下建立寄存器模型的步骤,包括寄存器声明、Adapter的实现与集成,以及如何通过Adapter进行寄存器访问、复位和测试。重点讲述了Adapter在数据映射和总线交互中的作用以及如何与环境中的其他组件连接以确保验证流程的正确性。
摘要由CSDN通过智能技术生成

目录

一、建立寄存器模型步骤

1、在文件timer_regmodel.sv中:

首先声明寄存器(只举两个寄存器为例):

声明寄存器块:

2、Adapter的实现:

Adapter桥接器的作用:

timer_reg_adapter中:

3、Adapter等的集成

timer_env中:

(1)、声明:

​编辑

(2)、例化:

(3)、连接:

4、寄存器模型访问

timer_base_virtual_sequence中

寄存器模型的复位:

timer_integration_virt_seq中

寄存器访问和检查:

read和write任务:

mirror操作:

5、timer_base_test中


一、建立寄存器模型步骤

1、在文件timer_regmodel.sv中:
首先声明寄存器(只举两个寄存器为例):

声明寄存器块:

  • 在这里可以设置覆盖率收集,也可以不设置,我们不设置,因为会生成一些不需要不期望的相关值,后续会从APB总线上来监测覆盖率并收集;
  • 寄存器模型 build()函数最后以 lock_model()结尾,该函数的功能是结束地址映射关系, 并且保证模型不会被其他用户修改

uvm_reg_map:

        用于存储寄存器映射的实例,用于在寄存器块中访问寄存器映射。

2、Adapter的实现:
Adapter桥接器的作用:
  • 在adapter中主要进行 uvm_reg_bus_op与总线transaction中各自的数据映射;
  • 实现reg2bus()和bus2reg()两个函数,这两个函数实现了两种transaction的数据映射;
  • 如果总线支持 byte 访问,可以使能 supports_byte_enable;如果总线 UVC 要返回 response 数据,则应当使能 provides_responses。
  • 在本例中,mcdf_bus_driver 在读数时 会将读回的数据填入到 RSP 并返回至 sequencer,因此需要在 adapter 中使能 provides_responses。由此使得 bus2reg()函数调用时得到的数据是总线返回时的 transaction ,但读者需要注意如果总线 UVC 不支持返回 RSP (没有调用 put_response(RSP)或 item_done(RSP)),那么不应该置此位,否则 adapter 将会使得验证环境挂起。默认情况下,上述的两个成员的复位值都是 0。
  • 如下所示,uvm_reg_bus_op 类的成员包含 6 个域。
timer_reg_adapter中:

3、Adapter等的集成
  • 在具备了寄存器模型 rgm、总线 UVC (总线通用验证组件)和桥接 adapter 后,就需要考虑如何将 adapter 集成到验证环境中去了
  •  对于 mcdf_rgm 的集成,我们倾向于顶层传递的方式,即最终从 test 层传入寄存器模型句柄。这种方式有利于验证环境env 的闭合性,在后期不同 test 对 rgm 做不同的配置时可以在顶层例化,而后通过 uvm_config_db 来传递。
  • 寄存器模型在创建之后要显式调用 build()函数。需要注意 uvm_reg_block 是 uvm_object 类型,因此其预定义的 build()函数并不自动执行,还需要单独调用。
  • 在顶层环境的 connect 阶段中,需要将寄存器模型的 map 组件与 bus sequencer 和 adapter 连接。这么做的必要性在于将 map(寄存器信息)、sequencer(总线侧激励驱动)和 adapter(寄存器级别和硬件总线级别的桥接)关联在一起。也只有通过这一 步,adapter 的桥接功能才可以工作。
timer_env中:
(1)、声明:
(2)、例化:

调用build()函数才能创建uvm_reg,调用uvm_reg里的field等的例化配置

(3)、连接:

  • set_sequencer的作用:

        adapter、squencer、map三者的关系,首先需要在环境(一般在env层次时)需要连接三者通过map.set_sequencer(squencer,adapter);因为本身rgm充当sequence,adapter充当转换的桥梁,而rgm中因为有lock_model只有map能访问内部reg的field,而对于传到bus上也需要用bus的sequencer进行和drv的传递,所以三者是要关联的,这样adapter才能工作。

  • 关于predictor的作用:

        这里使用了predictor的显式预测,如下:

        只用声明例化preditor,并且将map和adapter的句柄给它内部的map和adapter,monitor上要是analysis port然后连接到它的bus_in端口。//预定义好的bus_in  analysis port

4、寄存器模型访问
timer_base_virtual_sequence中

声明了rgm句柄和一个变量uvm_status_e(详细看看用法)

寄存器模型的复位:
  • 在task body()中进行
task body();
    fork
        wait_reset_asserted();      //复位函数
    join_none
endtask

task wait_reset_asserted();
    forever begin
        @(negedge vif.apb_rstn);
        rgm.reset();
    end
endtask
  • uvm_status_e status是前面uvm_reg_bus_op类的成员变量,有三种值UVM_IS_OK、UVM_IS_X、UVM_NOT_OK。
timer_integration_virt_seq中
寄存器访问和检查:

read和write任务:

        read任务的原型为:

extern 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);
  • 它有多个参数,常用的是其前三个参数。其中第一个是uvm_status_e型的变量,这是一个输出,用于表明读操作是否成功; 第二个是读取的数值,也是一个输出;第三个是读取的方式,可选UVM_FRONTDOOR和UVM_BACKDOOR。

        write任务的原型为:

extern 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);
  • 它的参数也有很多个,但是与read类似,常用的也只有前三个。其中第一个为uvm_status_e型的变量,这是一个输出,用于表 明写操作是否成功。第二个要写的值,是一个输入,第三个是写操作的方式,可选UVM_FRONTDOOR和UVM_BACKDOOR。
  • 寄存器模型对sequence的transaction类型没有任何要求。因此,可以在一个发送my_transaction的sequence中使用寄存器模型对寄存器进行读写操作。
mirror操作:
  • UVM提供mirror操作,用于读取DUT中寄存器的值并将它们更新到寄存器模型中。它的函数原型为:
task uvm_reg::mirror(output uvm_status_e status,
                    input uvm_check_e check = UVM_NO_CHECK,
                    input uvm_path_e path = UVM_DEFAULT_PATH,
…);
  • 它有多个参数,但是常用的只有前三个。其中第二个参数指的是如果发现DUT中寄存器的值与寄存器模型中的镜像值不一 致,那么在更新寄存器模型之前是否给出错误提示。其可选的值为UVM_CHECK和UVM_NO_CHECK。
  • 它有两种应用场景,一是在仿真中不断地调用它,使得到整个寄存器模型的值与DUT中寄存器的值保持一致,此时check选项 是关闭的。二是在仿真即将结束时,检查DUT中寄存器的值与寄存器模型中寄存器的镜像值是否一致,这种情况下,check选项是打开的。
  • mirror操作会更新期望值和镜像值。同update操作类似,mirror操作既可以在uvm_reg级别被调用,也可以在uvm_reg_block级别 被调用。当调用一个uvm_reg_block的mirror时,其实质是调用加入其中的所有寄存器的mirror。
5、timer_base_test中

主要进行寄存器块rgm句柄的顶层例化,并将句柄传递给下层environment

  • 33
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
dw_apb_timer是一种APB总线定时器模块,常用于系统计时和定时器功能的设计。该模块是用于处理器外围设备的接口,可以与ARM Cortex处理器进行通信。dw_apb_timer通常由以下部分组成: 1. APB接口:该接口用于与处理器进行通信,可以通过总线来读取和写入寄存器。 2. 时钟和计数器:dw_apb_timer包含一个内部时钟和计数器,可以提供精确的时间测量功能。通过读取计数器的值,可以获取经过的时间。 3. 计时模式:dw_apb_timer可以设置为计时模式,可以用于实现系统的延时和计时任务。通过配置寄存器,可以设置定时器的触发条件和计时时间。 4. 断功能:dw_apb_timer支持断功能,可以在特定条件下触发断,用于通知处理器定时器达到了预设的计时时间。断信号可以作为处理器断请求的一部分,用于实现定时任务的同步控制。 5. 预分频器:dw_apb_timer还包含一个预分频器,可以对时钟频率进行设置和调节,以适应不同的应用需求。 6. 寄存器:dw_apb_timer拥有一系列寄存器,用于配置和控制定时器的不同功能。通过读写这些寄存器,可以实现对定时器的各种设置和操作。 总之,dw_apb_timer是一种功能强大的定时器模块,常用于嵌入式系统的计时和定时任务设计。通过与处理器进行通信,提供精确的时间测量和控制功能,可以满足不同系统对计时器的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值