多通道整形器模块验证 V2.2_UVM寄存器模型2,常规方法,使用场景

多通道整形器模块验证 V2.2_UVM寄存器模型2,常规方法,使用场景 - 知乎

一、前门访问 & 后门访问

1、前门访问

  • 定义
    • 在寄存器模型上做的读写操作,通过总线UVC实现总线上的物理时序访问
    • 物理时序协议,耗时, 真实的物理操作
  • 寄存器前门访问的两种方式write, write_reg
    • 优先使用第一种方法。
/************************一:reg方法***************************/
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
)
/************************二:uvm_reg_sequence方法***************************/
virtual task write_reg(
   	input 	uvm_reg 	rg,	  	
   	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 	int 	prior	 = 	-1,
   	input 	uvm_object 	extension	 = 	null,
   	input 	string 	fname	 = 	"",
   	input 	int 	lineno	 = 	0
)

2、后门访问

  • 定义:
    • 通过仿真器提供的可直接访问信号的手段
    • UVM DPI,uvm_hdl_read(),uvm_hdl_deposit()
  • 功能
    • 读取信号路径中某个值的value
    • force某个值
    • 后门访问实现
  class mcdf_rgm extends uvm_reg_block;
    `uvm_object_utils(mcdf_rgm)
    rand ctrl_reg chnl0_ctrl_reg;
    rand ctrl_reg chnl1_ctrl_reg;


    uvm_reg_map map;

    function new(string name = "mcdf_rgm");
      super.new(name, UVM_NO_COVERAGE);
    endfunction
      ...
      // specify HDL path,②各个寄存器成员与HDL一侧的地址映射
      chnl0_ctrl_reg.add_hdl_path_slice($sformatf("mem[%0d]", `SLV0_RW_REG), 0, 32);
      chnl1_ctrl_reg.add_hdl_path_slice($sformatf("mem[%0d]", `SLV1_RW_REG), 0, 32);

//①将寄存器模型关联到DUT一端
      add_hdl_path("tb.dut.ctrl_regs_inst");
//③最后以lock_model()结尾,结束地址映射关系
      lock_model();
    endfunction
  endclass

  • 后门访问的相关方法_见下一节

3、前门访问和后门访问对比

要点:

  • 后门访问较前门访问更便捷更快,但不能只依赖后门,它不能访问物理通路是否工作正常
  • 前门,后门访问混合方式,对寄存器验证的完备性更由帮助

4、前门后门的混合应用场景

  • 大型寄存器测试方法:先前门验物理通路,后期节省时间后门访问
  • quiry 寄存器:只能写一次的寄存器,建议用物理方式去访问以确保反映真实的硬件行为
  • 寄存器值随机化模拟无法预期的硬件配置先后门,再前门
  • 排除地址映射错误,前门写,后门读
  • 状态寄存器的触发器延迟

二、寄存器模型常规方法

1、三个值

  • mirrored value:表示当前硬件的已知状态值
  • desired value:先利用寄存器模型修改软件对象值(set),而后利用该值更新硬件值(update)

通过update使三个值保持一样

  • actual value:硬件的真实数值

2、prediction分类

  • 自动预测
    • 定义:
      • 利用寄存器的操作来自动记录每一次寄存器的读写数值,并在后台自动调用predict()方法
    • 适用场景:
      • 验证环境的rgm中缺少mon or predictor
      • 使用后门访问时
    • 不适用场景
      • 出现其他一些sequence直接在总线层面上对寄存器进行操作(跳过寄存器级别的write()/read())

  • 显示预测
  • 定义
  • 依赖于monitor从物理总线上捕捉总线事务,并将捕捉到的事务传递给外部例化的predictor
  • 预测步骤
  • 拿到monitor从总线监测到的bus_trans,其内容与bus_seq_item内容完全一致
  • predictor能够拿到adapter的句柄,bus2reg函数将读取回来的bus_trans通过adapter转化为RGM可以识别的uvm_reg_item类型
  class mcdf_env extends uvm_env;
    ...
//UVC monitor能够监测,需要具备捕捉事务的功能和对应analysis port,并连接到predictor的bus_in ap端口
      reg_agt.monitor.mon_ana_port.connect(predictor.bus_in);
//predictor拿到adapter和map句柄
      predictor.map = rgm.map;
      predictor.adapter = adapter;
      virt_sqr.rgm = rgm;
    endfunction
  endclass: mcdf_env

  • 最后,结合map中的reg名称,转换后的数据更新到每个reg field内部的值
  • 显示预测实现前提
    • UVC monitor能够监测,需要具备捕捉事务的功能和对应analysis port,并连接到predictor的bus_in ap端口
    • predictor拿到adapter和map句柄

3、uvm_reg的访问方法

  • reset()/get_reset():_复位对象:寄存器模型
  • 复位值是否按照寄存器描述实现?
    • 读取寄存器模型的复位值
    • 前门访问获取的寄存器复位值
    • mirror
      • 可前门可后门,修改镜像值之前,还可以选择是否将读回的值与模型中的原镜像值进行比较。使act和mir一致
      rgm.chnl0_ctrl_reg.mirror(status, UVM_CHECK, UVM_BACKDOOR);
  • set()/update()_对象:寄存器模型
    • 通过该方法可以修改期望值,而在寄存器配置时先对其随机化,再配置个别域或者域。若寄存器的期望值与镜像值不同时,可以通过update()方法来将不同的(DUT)寄存器通过前门或后门访问的方式做全部修改。
  • 优点
    • 较write()和poke()的写寄存器方式更为灵活
    • 实现随机化寄存器配置值(随机值结合某些域的指定值写入到寄存器)
    • 模拟更多不可预知的寄存器应用场景
    • update()强大的批量操作
对某个域作操作
void'(rgm.chnl0_ctrl_reg.randomize());
rgm.chnl0_ctrl_reg.pkt_len.set('h3);
rgm.update(status, UVM_FRONTDOOR, .parent(this));

4、mem与reg的联系和差别

5、内建sequences

  • 寄存器模型(rgm)内建sequence
    • 禁止域名:uvm_resource_db :对状态寄存器的保留位禁止掉。

  • 内建sequences目的
    • 测试寄存器模型,寄存器的写入值可以准确地反映到硬件中地寄存器
  • 实现前提
  class mcdf_reg_builtin_virtual_sequence extends mcdf_base_virtual_sequence;
    `uvm_object_utils(mcdf_reg_builtin_virtual_sequence)
     ...
    task do_reg();
//  ① sequences创建
      uvm_reg_hw_reset_seq reg_rst_seq = new(); 
      uvm_reg_bit_bash_seq reg_bit_bash_seq = new();
      uvm_reg_access_seq reg_acc_seq = new();

      // wait reset asserted and release② 复位信号的声明与释放
      @(negedge p_sequencer.intf.rstn);
      @(posedge p_sequencer.intf.rstn);

      `uvm_info("BLTINSEQ", "register reset sequence started", UVM_LOW)
//③ 将寄存器模型复位
      rgm.reset();
//④ 将寄存器句柄与sequence内的model连接
      reg_rst_seq.model = rgm;
//⑤ 将seq挂载到virt_sqr内的reg_sqr上
      reg_rst_seq.start(p_sequencer.reg_sqr);
      `uvm_info("BLTINSEQ", "register reset sequence finished", UVM_LOW)

      `uvm_info("BLTINSEQ", "register bit bash sequence started", UVM_LOW)
      // reset hardware register and register model
      p_sequencer.intf.rstn <= 'b0;
      repeat(5) @(posedge p_sequencer.intf.clk);
      p_sequencer.intf.rstn <= 'b1;
      rgm.reset();
      reg_bit_bash_seq.model = rgm;
      reg_bit_bash_seq.start(p_sequencer.reg_sqr);
      `uvm_info("BLTINSEQ", "register bit bash sequence finished", UVM_LOW)

      `uvm_info("BLTINSEQ", "register access sequence started", UVM_LOW)
      // reset hardware register and register model
      p_sequencer.intf.rstn <= 'b0;
      repeat(5) @(posedge p_sequencer.intf.clk);
      p_sequencer.intf.rstn <= 'b1;
      rgm.reset();
      reg_acc_seq.model = rgm;
      reg_acc_seq.start(p_sequencer.reg_sqr);
      `uvm_info("BLTINSEQ", "register access sequence finished", UVM_LOW)
    endtask
  endclass: mcdf_reg_builtin_virtual_sequence

三、寄存器模型的应用场景

1、如何用寄存器模型检查寄存器

  • 使用寄存器模型地场景
    • 全局的影子寄存器(LMU(LOCAL MEMORY UNIT))
      • 定义: 类似寄存器模型镜像值的方法
      • 功能
        • 暂存当时写入寄存器的值
        • 非易失,省略读取寄存器的步骤,LMU代替
        • 响应迅速——无需经过物理总线

    • 对硬件数据通路作数据比对 :_常规用法
      • 利用寄存器模型的镜像值可以实现实时读取

2、功能覆盖率的实现

  • 内部自动收集模式
    • 例化,采样
      • cg自动生成,寄存器有成千上万个时,合理例化以及使能采样。验证前期无需例化cg,后期需要采集功能覆盖率时,再考虑例化、使能采样
      • 调用has_coverage()来判断uvm_reg::m_has_cover的值
/*****************uvm_coverage_model_e*********************/
UVM_NO_COVERAGE
UVM_CVR_REG_BITS
UVM_CVR_ADDR_MAP
UVM_CVR_FIELD_VALS
UVM_CUR_ALL
      • sample()
        • read(), write()方法的回调函数,保证自动采样数据
      • sample_value()
        • 供外部调用的方法,在特定事件触发时调用, 通过get_coverage()方法判断是否允许进行覆盖率采样
    • 缺点
      • 不灵活,
        • 默认采样所有的域包括如保留域
        • 一个位宽很大的域不能分段采样
      • 不够智能
        • 无法使用交叉覆盖率组合出更多有意义的运用场景
        • 不同chnl的优先级组合
  class ctrl_reg extends uvm_reg;
    `uvm_object_utils(ctrl_reg)
    uvm_reg_field reserved;
    rand uvm_reg_field pkt_len;
    rand uvm_reg_field prio_level;
    rand uvm_reg_field chnl_en;

    covergroup value_cg;
      //将覆盖率信息保存于cg database中并打印报告
      option.per_instance = 1;
      //应该去掉保留域的采样
      reserved: coverpoint reserved.value[25:0];
      //关系的len.value为一个范围,不够灵活,无法指定每个bin的值
      pkt_len: coverpoint pkt_len.value[2:0];
      prio_level: coverpoint prio_level.value[1:0];
      chnl_en: coverpoint chnl_en.value[0:0];
    endgroup

    function new(string name = "ctrl_reg");
      //默认的UVM_CVR_ALL代表包含所有覆盖率类型
      super.new(name, 32, UVM_CVR_ALL);
      //设定可用或需要的覆盖模型,此处为field_value
      void'(set_coverage(UVM_CVR_FIELD_VALS));
      //检查是否具备对应的cg
      if(has_coverage(UVM_CVR_FIELD_VALS)) begin
        value_cg = new();//例化cg
      end
    endfunction
    
    virtual function void build();
      reserved = uvm_reg_field::type_id::create("reserved");
      pkt_len =...
      reserved.configure(this, 26, 6, "RO", 0, 26'h0, 1, 0, 0);
      pkt_len.configure ...
    endfunction

//uvm_reg预定义的函数,参数保持一致
    function void sample(
      uvm_reg_data_t data,
      uvm_reg_data_t byte_en,
      bit            is_read,
      uvm_reg_map    map
    );
      super.sample(data, byte_en, is_read, map);
      sample_values(); 
    endfunction

    function void sample_values();
      super.sample_values();
      //只有顶层允许例化cg时,,才能允许cg进行采样;
      if (get_coverage(UVM_CVR_FIELD_VALS)) begin
        value_cg.sample();
      end
    endfunction
  endclass

利用寄存器模型进行覆盖率采样的value是指哪一个val?

类uvm_reg_field的成员value,区别于desire val 和mirror val,成员value为rand属性,而desire val和mirror val是local属性,类uvm_reg在指定cg时只能对非local成员采样,在恰当的时刻,value的值与act的值是一致的

  • 事件触发外部收集模式__参考书本
    • 目的:采取自定义cg会更加贴合实际,贴合覆盖率验收标准
    • cg的创建:
      • 继承于uvm_subscriber,订阅从其他地方(mon)传来的信息。
      • 发送信息方,mcdf_bus_monitor::uvm_analysis_port。
        • 监听对象:前门访问读写事件。
        • 通过write()发往cg::uvm_analysis_export。
    • cg定义
      • 指定各个寄存器感兴趣的域或值范围。
      • 将各个相关的coverpoint进行cross,构成更复杂的场景实现要求
    • sample_value()的触发事件。
      • monitor监听到的前门访问读写事件。
UVM(Universal Verification Methodology)寄存器模型是一用于验证芯片寄存器功能的标准方法。它提供了一个统一的、可重用的框架,用于建立和管理寄存器模型,以及执行寄存器访问和验证UVM寄存器模型的主要组成部分包括寄存器模型寄存器层次结构、寄存器操作和寄存器验证环境。 1. 寄存器模型UVM寄存器模型是一个抽象的表示,用于描述芯片内部的寄存器寄存器字段。它提供了一种结构化的方式来定义寄存器的属性、寄存器字段的位宽和访问权限等。 2. 寄存器层次结构:UVM寄存器模型支持多层级的寄存器结构,可以通过层级关系来描述芯片内部的寄存器模块和子模块。这样可以更好地组织和管理寄存器模型,并提供寄存器之间的相互作用和访问。 3. 寄存器操作:UVM提供了一系列的API,用于执行寄存器读写操作。通过这些API,可以向寄存器模型发送读写请求,并获取响应。同时,还可以对寄存器的访问进行配置和控制,如重置、写入默认值等。 4. 寄存器验证环境:UVM寄存器模型可以与其他验证环境进行集成,以验证寄存器功能的正确性。通过使用事务级建模(TLM)接口,可以将寄存器操作与其他验证组件进行交互,并进行功能验证、覆盖率分析和错误注入等。 总之,UVM寄存器模型提供了一种规范化的方法来描述和验证芯片寄存器功能。它具有可重用性、灵活性和扩展性,并能与其他验证组件进行集成,从而提高验证效率和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值