极简UVM RAL示例(PART3--后门访问,PART4--内建ral sequence)

本文介绍如何在RTL级验证中实现RAL后门访问,并通过修改测试代码进行后门路径、默认值及读写访问的序列检查。针对后门访问,文章详细展示了如何在不同阶段进行读写操作;对于序列测试,包括了后门路径的有效性验证、默认值的校验以及读写操作的正确性检查。

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

基于part2,修改支持ral 后门仿问

tests代码

第一处修改build_phase

rgm.reset();
rgm.set_hdl_path_root("tb_top.u_dut");

第二处修改main_phase

//backdoor
rgm.reg2_reg.write(status,'h20,UVM_BACKDOOR);
rgm.reg2_reg.read(status,value,UVM_FRONTDOOR);
`uvm_info(get_full_name(),$sformatf("frontdoor read %s:%0h",rgm.reg2_reg.get_full_name(),value),UVM_MEDIUM);
rgm.reg2_reg.read(status,value,UVM_BACKDOOR);
`uvm_info(get_full_name(),$sformatf("backdoor read  %s:%0h",rgm.reg2_reg.get_full_name(),value),UVM_MEDIUM);
rgm.reg2_reg.read(status,value,UVM_FRONTDOOR);
`uvm_info(get_full_name(),$sformatf("frontdoor read %s:%0h",rgm.reg2_reg.get_full_name(),value),UVM_MEDIUM);
rgm.reg2_reg.peek(status,value);
`uvm_info(get_full_name(),$sformatf("backdoor peek  %s:%0h",rgm.reg2_reg.get_full_name(),value),UVM_MEDIUM);
rgm.reg2_reg.read(status,value,UVM_FRONTDOOR);
`uvm_info(get_full_name(),$sformatf("frontdoor read %s:%0h",rgm.reg2_reg.get_full_name(),value),UVM_MEDIUM);

基于part3,还可以实验内建ral序列

1)检查后门路径的序列

修改tests的main_phase

uvm_reg_mem_hdl_paths_seq chk_bkdoor;
phase.raise_objection(this);
chk_bkdoor =new("chk_bkdoor");
chk_bkdoor.model = rgm;
chk_bkdoor.start(null);

检查结果

UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_mem_hdl_paths_seq.svh(70) @ 0: reporter@@chk_bkdoor [uvm_reg_mem_hdl_paths_seq] checking HDL paths for all registers/memories in rgm
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_mem_hdl_paths_seq.svh(97) @ 0: reporter@@chk_bkdoor [uvm_reg_mem_hdl_paths_seq] Validating HDL paths in rgm for default design abstraction
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_mem_hdl_paths_seq.svh(81) @ 0: reporter@@chk_bkdoor [uvm_reg_mem_hdl_paths_seq] HDL path validation completed

2)检查默认值的序列

修改tests的main_phase

uvm_reg_hw_reset_seq chk_default;
phase.raise_objection(this);
chk_default = new("chk_default");
chk_default.model = rgm;
chk_default.start(null); 

检查结果

Starting chk_default sequence…

UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_hw_reset_seq.svh(148) @ 0: reporter@@chk_default [uvm_reg_hw_reset_seq] Verifying reset value of register rgm.reg1_reg in map “rgm.uvm_reg_map”…
Verdi Enable Verdi Recorder.
Info: Verdi UVM 1.1d Hooks File 07/11/2013
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_hw_reset_seq.svh(148) @ 15000: reporter@@chk_default [uvm_reg_hw_reset_seq] Verifying reset value of register rgm**.reg2_reg** in map “rgm.uvm_reg_map”…
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_hw_reset_seq.svh(148) @ 21000: reporter@@chk_default [uvm_reg_hw_reset_seq] Verifying reset value of register rgm.reg3_reg in map “rgm.uvm_reg_map”…
UVM_ERROR /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/uvm_reg.svh(2929) @ 27000: reporter [RegModel] Register “rgm**.reg3_reg**” value read from DUT (0x0000000000000001) does not match mirrored value (0x0000000000000000)
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_hw_reset_seq.svh(148) @ 27000: reporter@@chk_default [uvm_reg_hw_reset_seq] Verifying reset value of register rgm.reg4_reg in map “rgm.uvm_reg_map”…

问题分析:检查默认值时,reg3的镜像值来自 reg3.configure()。所以,可以修改reg3的初始配置值。

3)检查读写的序列

修改tests的main_phase

uvm_reg_hw_reset_seq chk_default;
phase.raise_objection(this);
chk_default = new("chk_default");
chk_default.model = rgm;
chk_default.start(null); 

检查结果

Starting chk_access sequence…

UVM_WARNING /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_access_seq.svh(110) @ 33000: reporter@@chk_access.single_reg_access_seq [uvm_reg_access_seq] Register ‘rgm.reg1_reg’ has RO fields
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_access_seq.svh(145) @ 33000: reporter@@chk_access.single_reg_access_seq [uvm_reg_access_seq] Verifying access of register ‘rgm.reg2_reg’ in map ‘rgm.uvm_reg_map’ …
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_access_seq.svh(145) @ 45000: reporter@@chk_access.single_reg_access_seq [uvm_reg_access_seq] Verifying access of register ‘rgm.reg3_reg’ in map ‘rgm.uvm_reg_map’ …
UVM_ERROR /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/uvm_reg.svh(2929) @ 51100: reporter [RegModel] Register “rgm.reg3_reg” value read from DUT (0x0000000000000001) does not match mirrored value (0x0000000000000000)
UVM_INFO /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/sequences/uvm_reg_access_seq.svh(145) @ 57000: reporter@@chk_access.single_reg_access_seq [uvm_reg_access_seq] Verifying access of register ‘rgm.reg4_reg’ in map ‘rgm.uvm_reg_map’ …
UVM_ERROR /home/eda_tool/vcs-mx/O-2018-09-SP2-1/vcs-mx/O-2018.09-SP2-1/etc/uvm/reg/uvm_reg.svh(2929) @ 63100: reporter [RegModel] Register “rgm.reg4_reg” value read from DUT (0x000000000000ffff) does not match mirrored value (0x0000000000000000)

问题分析

因为reg3(WRC), reg4(RS) 不像 reg1是只读,所以会被检查,但是reg3/4的 dut值随着read动作变化,导致比较不通过。或者设置 NO_REG_TEST, NO_REG_ACCESS_TEST。但是奇怪的是,reg4(RS)应该推测出是ffff。

<think>好的,用户让我介绍一下如何用UVM实现一个AXI4-Lite接口的寄存器读写验证,包括覆盖率和记分牌。我需要先理清用户的需求,然后逐步构建回答的结构。 首先,用户可能是一个验证工程师,正在着手验证一个AXI4-Lite接口的寄存器模块。他们需要了解UVM框架下的验证方法,特别是覆盖率和scoreboard的实现。用户可能对UVM有一定的基础,但需要具体的步骤和示例代码。 接下来,我需要考虑AXI4-Lite协议的关键点。AXI4-Lite是化版的AXI4,主要用于寄存器访问,支持读写操作,数据宽度通常为32位或64位。验证的重点在于地址的正确性、数据读写的正确性以及控制信号的覆盖,比如读写响应是否正确处理。 然后,关于UVM的结构,通常包括testbench顶层、test、env、agent、scoreboard、coverage等组件。需要分别说明每个部分的作用,并给出代码示例。特别是scoreboard和coverage的实现,这是用户明确提到的部分。 覆盖率部分,需要覆盖地址、数据、操作类型(读或写)以及响应。可能需要使用covergroup来定义这些覆盖点,并在monitor中采样数据。需要举例说明covergroup的结构和触发时机。 Scoreboard负责检查DUT的行为是否正确。对于寄存器读写,可能需要一个预测模型,通常是寄存器模型(reg_model)。在scoreboard中,比较实际读写的数据与预期值是否一致。这里需要注意预测的时机,比如在axi_transaction完成后,或者通过寄存器模型的回调函数。 可能还需要考虑如何连接寄存器模型到scoreboard,以及如何处理前门访问后门访问。不过用户主要关注的是前门访问,即通过AXI接口的读写。 然后,测试用例的结构,需要生成随机的读写操作,覆盖不同的地址和数据。需要利用UVMsequence机制,生成并发送transaction给driver。 最后,需要整合所有组件,确保环境正确连接,并在test中启动sequence。同时,仿真完成后需要检查覆盖率和测试结果。 现在,需要检查是否有遗漏的部分。比如,是否需要考虑错误注入,或者异常情况下的响应?用户可能暂时不需要这些高级部分,但基础的正确性检查是必须的。 另外,代码示例需要确保语法正确,符合UVM的编码规范。例如,在scoreboard中,通常使用analysis端口接收来自monitor的transaction,然后进行处理和比较。 在覆盖率的实现中,需要注意covergroup的例化和触发方式,比如在monitor的analysis_port接收到transaction时触发采样。 可能还需要提到寄存器模型的使用,比如如何创建寄存器块,并将其集成到测试环境中,以方便预测和访问寄存器的值。 总结下来,回答的结构应该是: 1. 概述AXI4-Lite验证的重点和UVM组件的作用。 2. 详细说明各个组件的实现,包括agent、coverage、scoreboard。 3. 提供代码示例,特别是coverage和scoreboard的关键部分。 4. 描述测试用例的编写和仿真步骤。 5. 最后总结注意事项和可能的扩展点。 需要确保各部分逻辑清晰,代码示例准确,并且符合用户提供的格式要求,如数学表达式用$...$,独立公式用$$...$$,但在这个问题中可能涉及较少数学内容,主要代码部分需要用代码块展示。 现在,检查是否所有用户要求都被覆盖:结构清晰,步骤详细,包含coverage和scoreboard的实现,使用中文,符合格式要求。看起来是的。 可能需要注意,在scoreboard部分,如何获取预期的寄存器值。如果使用寄存器模型,可以通过predictor或者adapter来更新寄存器模型的值,然后在scoreboard中比较。或者,在scoreboard中直接引用寄存器模型的镜像值进行比较。需要明确说明这一点,避免混淆。 另外,覆盖率收集需要在monitor中完成,当transaction被捕获时,触发covergroup的采样。需要确保在代码示例中体现这一点。 最后,提醒用户需要根据实际DUT调整地址范围、寄存器宽度等参数,以及可能的协议细节,如响应类型、错误处理等。</think>以下是用UVM实现AXI4-Lite寄存器读写验证的详细说明,包含覆盖率(Co­ve­r­a­ge)和记分牌(Sc­o­r­e­b­o­a­rd)的实现步骤: --- ### **1. 验证目标** 验证AXI4-Lite接口寄存器: - 地址映射正确性 - 读写数据一致性 - 控制信号(如`AWVALID/WVALID/BVALID`)协议符合性 - 错误响应(如访问保留地址) --- ### **2. UVM组件架构** ```plaintext testbench_top ├── axi4_lite_env │ ├── agent : axi4_lite_agent │ ├── coverage : axi4_lite_coverage │ └── scoreboard : axi4_lite_scoreboard ├── reg_model : reg_block └── test : base_test ``` --- ### **3. 关键组件实现** #### **3.1 AXI4-Lite Agent** 负责驱动和监控AXI4-Lite协议: ```systemverilog class axi4_lite_agent extends uvm_agent; `uvm_component_utils(axi4_lite_agent) axi4_lite_driver driver; axi4_lite_monitor monitor; uvm_sequencer#(axi4_lite_seq_item) sequencer; virtual function void build_phase(uvm_phase phase); driver = axi4_lite_driver::type_id::create("driver", this); monitor = axi4_lite_monitor::type_id::create("monitor", this); sequencer = uvm_sequencer#(axi4_lite_seq_item)::type_id::create("sequencer", this); endfunction virtual function void connect_phase(uvm_phase phase); driver.seq_item_port.connect(sequencer.seq_item_export); endfunction endclass ``` --- #### **3.2 覆盖率收集(Co­ve­r­a­ge)** 定义地址、数据、操作类型的覆盖点: ```systemverilog class axi4_lite_coverage extends uvm_subscriber#(axi4_lite_seq_item); `uvm_component_utils(axi4_lite_coverage) covergroup axi_cov; // 地址覆盖:所有可访问寄存器地址 address_cp: coverpoint item.addr { bins reg_bins[] = {[0:32&#39;hFFFF_FFFF]}; // 根据实际地址范围调整 } // 数据覆盖:读写数据值 data_cp: coverpoint item.data { bins min = {32&#39;h0000_0000}; bins max = {32&#39;hFFFF_FFFF}; bins typical = default; } // 操作类型覆盖 op_cp: coverpoint item.op_type { bins READ = {AXI_READ}; bins WRITE = {AXI_WRITE}; } endgroup virtual function void write(axi4_lite_seq_item t); item = t; axi_cov.sample(); // 采样覆盖点 endfunction endclass ``` --- #### **3.3 记分牌(Sc­o­r­e­b­o­a­rd)** 对比DUT行为与寄存器模型预测值: ```systemverilog class axi4_lite_scoreboard extends uvm_scoreboard; `uvm_component_utils(axi4_lite_scoreboard) uvm_analysis_imp#(axi4_lite_seq_item, axi4_lite_scoreboard) item_export; reg_block reg_model; // UVM寄存器模型 virtual function void write(axi4_lite_seq_item item); uvm_reg_data_t mirrored_val; if (item.op_type == AXI_WRITE) { // 获取寄存器模型预测值 mirrored_val = reg_model.default_map.get_reg_by_offset(item.addr).get_mirrored_value(); if (item.data != mirrored_val) `uvm_error("SCBD", $sformatf("Write mismatch! DUT=%0h Model=%0h", item.data, mirrored_val)) } else { // 读取时比较实际数据与预测值 mirrored_val = reg_model.default_map.get_reg_by_offset(item.addr).get_mirrored_value(); if (item.data != mirrored_val) `uvm_error("SCBD", $sformatf("Read mismatch! DUT=%0h Model=%0h", item.data, mirrored_val)) } endfunction endclass ``` --- ### **4. 测试用例设计** 生成随机读写操作并检查覆盖率: ```systemverilog class reg_rw_test extends uvm_test; `uvm_component_utils(reg_rw_test) virtual task run_phase(uvm_phase phase); reg_access_seq seq = reg_access_seq::type_id::create("seq"); seq.reg_model = env.reg_model; // 绑定寄存器模型 seq.start(env.axi_agent.sequencer); endtask endclass ``` --- ### **5. 仿真流程** 1. **编译阶段**:集成寄存器模型到UVM环境 2. **运行阶段**: - 通过Sequence生成随机读写操作 - Monitor捕获DUT响应并发送至Scoreboard - Coverage收集功能覆盖数据 3. **报告阶段**: - 检查覆盖率是否达到100% - 验证Scoreboard错误计数器是否为0 --- ### **6. 注意事项** 1. 寄存器模型需与RTL地址映射完全一致 2. 需处理协议违规场景(如连续写操作无握手) 3. 可添加断言(Assertion)增强协议检查 --- ### **扩展建议** - 添加错误注入测试(如访问非法地址) - 实现寄存器前后门访问对比 - 使用RAL(Re­g­i­s­t­er Ab­s­t­r­a­c­t­i­on La­y­er)自动化寄存器操作 完整代码需结合具体DUT实现调整地址范围和数据宽度,可通过UVM提供的`uvm_reg`和`uvm_reg_map`管理寄存器映射关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值