APB_Timer模块解读

目录

APB_Timer模块解读

APB_Timer定时器cmsdk_apb_timer.v是一个32位的下行计数器,具有以下能力:
1.当计数器达到0时,你可以生成一个中断请求信号TIMERINT。中断请求被保持,直到它被写入INTCLEAR寄存器。
2.你可以使用外部输入信号的0到1转换,EXTIN,作为定时器启用
3.如果APB定时器计数达到0,同时软件清除之前的一个中断状态,则中断状态设置为1
4.外部时钟EXTIN必须慢于外部时钟的一半,因为它由双触发器采样,然后在外部输入作为时钟时通过边缘检测逻辑。参见4-6页的程序员模型。
5.一个单独的时钟引脚,PCLKG,用于APB寄存器的读或写逻辑,当没有APB活动时,允许时钟到外设寄存器逻辑停止。(应该再注意一下时钟的使用,对CTRL和RELOAD寄存器的写入用的时钟是PCLKG,然后对寄存器读使用的时钟也是PCLKG。除此之外都用的是PCLK,好处是当没有提供PCLK信号,也就是计数器没法工作时,仍然可以配置寄存器和读取寄存器信息,将计数器的功能与配置寄存器的操作解耦,使可以先配置寄存器,然后提供PCLK信号控制计数器。)
而APB_Timer的几大特性是:生成中断,中断清除,引入外部控制信号和外部时钟等特性。
在这里插入图片描述
在这里插入图片描述
首先是寄存器信息,RELOAD寄存器和Current VALUE寄存器和一个各个位对应不同控制信号的CTRL控制寄存器,一个中断寄存器。
在这里插入图片描述

APB协议

APB主要用于低带宽的周边外设之间的连接,例如UART、1284等,它的总线架构不像AHB支持多个主模块,在APB里面唯一的主模块就是APB 桥。其特性包括:两个时钟周期传输;无需等待周期和回应信号;控制逻辑简单,只有四个控制信号。在APB_Timer中:
1、PCLK(总线时钟);
2、PRESETn(APB复位);
3、PSEL(选择从设备);
4、PADDR/PWRITE/PWDATA/PRDATA(地址和控制信号,读写数据);PREADY/PENABLE(APB 传输控制);PSLVERR(PSLVERR是表示当前传输的数据是否有误)。

AHB_Timer验证结构图

在这里插入图片描述
tb中主要包括APB_Timer模块的例化、模块与验证平台接口的连接,config_db机制将ahb_interface传递于env的agent里,将ahbram_interface传递到base_test层里面例化的config里。
在base_test中例化了enviroment, config,与寄存器模型,在顶层test中配置config组件,通过config_db机制将config组件set到底层的env组件中,config组件中的rgm句柄指向寄存器模型实例,这样底层的组件通过调用cfg.rgm就可以索引到寄存器模型,方便后期代码修改。
验证环境env中例化了ahb_mst_agent, virtual_sequencer, scorboard, coverage, adapter和predictor, ahb_mst_agent包括driver, sequencer, monitor,同時將monitor的uvm_analysis_port连接到scoreboard和coverage_model的uvm_analysis_imp中。

测试序列

(1)base_virtual_sequence :
定义了compare()一些基本方法,其他的virtual_sequence继承于base_virtual_sequence;
(2)integration_virt_seq:写入数据在读取数据,比较;
(3) counter_boundary_and_recount_virt_seq:
1.32bit的边界检查;2.一旦重新把数写入VALUE寄存器中,计数器会重新计时;3.RELOAD 寄存器写入数据,等到计数为0的时候,才开始下一次计时;
(4)reload_and_interrupt_virt_seq:检验interrupt拉起后是否能够被清除;
(5)external_source_as_clock_virt_seq/external_source_as_enable_virt_seq;外部信号和时钟能否控制计时。

覆盖率收集

定义了6个covergroup,分别关心”CTRL”的四个小寄存器域,“RELOAD”,”INSTSTAT”采样,对中断信号timerint以及计数的数据counter采样。在这里插入图片描述

覆盖率收集

定义6个covergroup,分别关心RELOAD寄存器、VALUE寄存器、CTRL控制寄存器,中断信号,计数:
在这里插入图片描述
使用shell脚本,固定种子seed,随机种子跑完以上测试,可以得到合并后的代码覆盖率情况如下:
Shell 脚本:
在这里插入图片描述

分析覆盖率收集情况:
功能覆盖率:
在这里插入图片描述
CTRL.ENABLE翻转没覆盖,
在这里插入图片描述在这里插入图片描述
reloadd的边界值没覆盖,
在这里插入图片描述
在这里插入图片描述
代码覆盖率:PRDATA的翻转,PREADY,PSLVERR
在这里插入图片描述
在这里插入图片描述
添加新的测试用例:

class rkv_timer_start_end_virt_seq extends rkv_timer_base_virtual_sequence;

  `uvm_object_utils(rkv_timer_start_end_virt_seq)

  function new (string name = "rkv_timer_base_virtual_sequence");
    super.new(name);
  endfunction

  task body();
    super.body();
    `uvm_info("SEQ", "test g continue to take count once reached 0", UVM_MEDIUM)
    rgm.CTRL.mirror(status);
    // enable timer
    rgm.CTRL.ENABLE.set(1);
    rgm.CTRL.update(status);
    //enable 0
    rgm.CTRL.ENABLE.set(0);
    rgm.CTRL.update(status);
    // enable timer
    rgm.CTRL.ENABLE.set(1);
    rgm.CTRL.update(status);

    // enable interrupt CTRL[3] = 1
    rgm.CTRL.INTREN.set(1);
    rgm.CTRL.update(status);
    // enable interrupt CTRL[3] = 0
    rgm.CTRL.INTREN.set(0);
    rgm.CTRL.update(status);
    // enable interrupt CTRL[3] = 1
    rgm.CTRL.INTREN.set(1);
    rgm.CTRL.update(status);

    // set reload count
    wr_val = 32'hFFFF_FFFF;
    rgm.RELOAD.write(status, wr_val);
    rgm.RELOAD.read(status, wr_val);
    wait_apb_cycles(100);
    wr_val = 32'h0000_0000;
    rgm.RELOAD.write(status, wr_val);
    rgm.RELOAD.read(status, wr_val);
    wait_apb_cycles(100);
    
    rgm.INTSTAT.read(status, rd_val);
       // clear interrupt
    rgm.INTSTAT.write(status, 1'b1);
    `uvm_info("SEQ", "Clear the interrupt status register", UVM_MEDIUM)
    // check interrupt status reg and pin
    rgm.INTSTAT.read(status, rd_val);


     endtask

endclass

加入新的定向测试后的覆盖率:
功能覆盖率:CTRL.ENABLE翻转覆盖,RELOAD边界值覆盖,在这里插入图片描述
代码覆盖率:PRDATA的翻转已覆盖
在这里插入图片描述
在这里插入图片描述
覆盖率分析:
功能覆盖率分析:APB_timer Single传输,功能覆盖率部分可以exclude
在这里插入图片描述
断言覆盖率分析:APB_timer Single传输,覆盖率部分可以exclude
在这里插入图片描述
代码覆盖率:PREADY为1,PSLVERR是表示当前传输的数据是否有误,代码覆盖率部分也可先exclude:
在这里插入图片描述

最终覆盖率:
在这里插入图片描述
在这里插入图片描述

项目难点

验证的难点是要保证验证的完备性和正确性;
在这里插入图片描述
在这里插入图片描述
完备性是指设计规格中的所有功能覆盖率都必须是100%,这个就需要熟悉设计spec与RTL代码制定相应的验证计划与测试案例,并且要保证功能点划分清晰;所以你的covermodel怎么去正确的收集数据就很重要,在timer中,covermodel要收集counter的数据,在covergroup_new (vif.countert) 的时候收集vif.counter的数据,但是问题是,function_new还没有拿到vif,所以会报错。

在这里插入图片描述
在这里插入图片描述

比如验证的正确性是指测试案例能否正确反映RTL的功能是否正常,它要通过波形检查、模型比较的方式。在timer中,subscriber中通过monitor的监听传递了transaction tr,利用rgm.map.get_reg_by_offset(tr.addr)得到了寄存器的信息,在task中的do_event_trigger()中case语句获知哪一个寄存器被拉起,通过uvm_event把信息传递给scoreboard后,获知dut的信息,比如counter(随时计数的信息),我们会把它和vif.counter比较,用diff = counter >= vif.counter ? counter - vif.counter : vif.counter - counter;因为我们用的是foever begin,在开始我们将reload value的值写入dut的时候,此时monitor会监测reload的值,发给scoreboard, scoreboard的counter的值会马上更新,dut的值(vif.counter的值)的更新会比scoreboard的值慢,diff就会很大,所以 if(!(diff <= cfg.counter_diff_max || (reload - diff) <= cfg.counter_diff_max)),保证开始的时候是正确的;

2.rkv_timer_external_source_as_enable_virt_seq
如果extin为0,scoreboard的counter一直在计数,而实际上硬件的counter并没有计数:
在这里插入图片描述
在这里插入图片描述
比较报错:
在这里插入图片描述
修改subscriber和scoreboard:
subscriber中,添加两个uvm_evevt,
在这里插入图片描述
在这里插入图片描述
在scoreboard中添加变量count_enable控制计数的开始, 运行rkv_timer_external_source_as_enable_test, extin_as_enable=1,一开始scoreboard的count_enable=1, 如果vif.extin=0,所以count_enable=0,do_counting不计数;如果vif.extin=1,count_enable=1,do_counting开始计数;
如果运行其他test,extin_as_enable=0,vif.extin=0,所以count_enable=1,开始计数,
scoreboard中:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
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是一种功能强大的定时器模块,常用于嵌入式系统的计时和定时任务设计。通过与处理器进行通信,提供精确的时间测量和控制功能,可以满足不同系统对计时器的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值