(UVM验证学习21) apb timer的参考模型和覆盖率模型实现

本文介绍了如何实现APB Timer的参考模型和覆盖率模型。在timer_subscriber中,实现了与APB monitor的分析端口连接,并通过分析imp和write函数处理传输数据。在timer_scoreboard的实现中,除了处理父类遗留的逻辑,还模拟了timer的行为,包括计数器和标志变量。此外,详细阐述了覆盖率模型的实现,包括CTRL、counter、RELOAD寄存器等的采样覆盖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

timer_subscriber实现

思路也是首先实现父类timer_subscriber,实现计分板和覆盖率模型的公用部分逻辑。
timer_subscriber需要实现的逻辑和内容:

  • scb和cgm都是与apb的monitor通过analysis port连接,因此需要analysis imp和实现write函数
  • 通过monitor发送到管道上的是一次传输的地址数据和读写类型,需要拿一个暂时变量存储这些信息。信息的暂存和初始事件 (timer_regacc_e) 的触发加在一起就构成了write函数
uvm_analysis_imp #(apb_transfer, timer_subscriber) apb_trans_observed_imp;
uvm_reg_bus_op rop; // 暂存信息的结构
virtual function write(apb transfer tr);
   uvm_reg r;
   r = rgm.map.get_reg_by_offset(tr.addr);
   if(r!=null)begin
       timer_regacc_e.trigger(r); // 初始事件的触发
       
       // 信息的暂存
       rop.addr = tr.addr;
       rop.kind = tr.trans_kind == apb_pkg::WRITE ? UVM_WRITE : UVM_READ;
       rop.data = tr.data;
       rop.status = tr.trans_status == apb_pkg::OK ? UVM_IS_OK : UVM_NOT_OK;
       rop.n_bits = 32;
       rop.byte_en = 4'b1111;
   end
endfunction
  • 基本的思路是定义一些事件,每次从analysis port接收到信息后,通过解析信息,判断总线上产生了什么样的事件,进行相应事件的定义和触发。
// 事件定义
uvm_event timer_regacc_e; // 寄存器访问
uvm_event timer_enable_e; // timer被使能
uvm_event timer_intren_e; // 中断被使能
uvm_event timer_reload_e; // 对RELOAD寄存器进行访问
uvm_event timer_value_e; // 对VALUE寄存器进行访问
uvm_event timer_intrclr_e; // 对INTSTAT寄存器进行访问

// timer倒计时到0后加载reload寄存器中的值
// 这里使用static是因为这个事件会由scb监测到timer出现特定行为时触发
// 但cgm会等待这个事件以进行相关的覆盖率采样,只有定义为静态事件变量
// 才能保证scb触发的事件和cgm等待的事件是同一个事件
static uvm_event timer_counter_take_reload_e;

// 事件池
protected uvm_event_pool _ep;
// 其中do_listen_events()由子类实现,subsciber仅实现do_event_trigger()
task run_phase(uvm_phase pphase);
	super.run_phase(phase);
	fork
		do_event_trigger();
		do_listen_events();
	join
endtask


virtual task do_event_trigger();
    uvm_object tmp;
    uvm_reg r;
    forever begin
        // 等待timer_regacc_e事件被触发,只有apb monitor调用analyisis port的write方法时会触发
        timer_regacc_e.wait_trigger_data(tmp);
        void'($cast(r, tmp));

        #1ps;
        // 判断访问的是什么寄存器,并触发相应的事件
        case(r.get_name())
            "CTRL":begin
                if(rgm.CTRL.ENABLE.get() == 1'b1) timer_enable_e.trigger();
                if(rgm.CTRL.INTREN.get() == 1'b1) timer_intren_e.trigger();
            end
            "VALUE":begin
                if(rgm.VALUE.get() != 0) timer_value_e.trigger();
            end
            "RELOAD":begin
                if(rgm.RELOAD.get() !=0) timer_reload_e.trigger();
            end
            "INTSTAT":begin
                if(rgm.INTSTAT.get == 1'b1) timer_intrclr_e.trigger();
            end
        endcase
    end
endtask

timer scoreboad的实现(参考模型的实现)

  • 作为计分板和参考模型,scb首先要做的就是实现父类遗留下来的do_listen_events(),接收各种事件传递过来的消息并进行相应的模拟和处理。
task do_listen_events();
    fork
        listen_counter_reset();
        listen_counter_enable();
        listen_counter_intren();
        listen_counter_reload();
        listen_counter_value();
        listen_counter_intrclr();
    join_none
endtask
  • 另外作为一个简陋的参考模型,我们必须要记录一些数据以进行基本的timer行为模拟,比如需要一个32位的counter记录当前value,比如指示timer和中断是否被使能的flag变量等
    bit [31:0] counter; // 计数值
    bit [31:0] reload; // reload值
    bit intrrupt; // 中断标志
    bit timer_enable;
    bit timer_intren;
  • 有了这些模拟变量,就可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值