模块化验证框架(1)

一、典型模块化验证框架

模块化的验证思想是:分层次、分模块

包括以下组件:


1.被测模块(DUT)

待测verilog(vhdl)模块

2.测试平台(testbench)

(1)激励生成器(driver):生成输入信号激励。

(2)监视器(Monitor):捕获DUT输出信号。

(3)参考模型(reference model):提供预期结果的黄金模型。

(4)比较器(scoreboard):对DUT输出与参考模型结果进行比较。

(5)覆盖率收集器(coverage collector):统计功能覆盖率和代码覆盖率。

3.验证环境

支持随机化测试、断言(assertions)和自动化回归测试。

二、验证步骤流程

1.验证计划

(1)目标:明确待验证功能点(如fifo的读写,ALU的运算)

(2)策略:确定测试类型(定向测试、随机测试),覆盖率目标(功能覆盖率100%,代码覆盖率95%)

(3)工具链:选择仿真工具(如modelsim/VCS)、脚本语言(python/perl)

2.测试平台开发

(1)接口定义:定义DUT输入输出信号的时序和协议。

(2)模块化设计:将driver、monitor等组件独立开发、支持复用。

(3)自动化脚本:编写脚本自动编译、运行仿真并生成报告。

3.测试用例编写

(1)定向测试:针对特定功能的手动测试(如复位信号测试)

(2)随机测试:通过约束随机生成输入激励(如随机数据、地址)

(3)边界测试:覆盖极端情况(如计数器溢出、fifo满/空状态)

4.仿真与调试

(1)波形分析:使用仿真工具查看信号时序。

(2)断言检查:插入assert语句实时验证协议或数据有效性。

(3)日志记录:记录错误信息及仿真上下文

5.覆盖率分析

(1)代码覆盖率:检查所有代码行是否被执行(line/branch coverage)

(2)功能覆盖率:验证所有功能点是否覆盖(通过覆盖组covergroup定义)

6.回归测试

自动化运行所有测试用例,确保代码修改未引入新错误

三、实例:

实例1:

fifo模块验证

1.DUT功能

模块:深度为8的同步fifo,支持读写操作和满/空状态标志。

2.验证计划

(1)功能点:正常读写、满、空标志、溢出处理、复位功能

(2)覆盖率目标:100%功能覆盖,95%代码覆盖。

3.测试平台结构

module fifo_tb;
  // 接口声明
  reg clk, rst, wr_en, rd_en;
  reg [7:0] data_in;
  wire [7:0] data_out;
  wire full, empty;

  // 实例化DUT
  fifo #(.DEPTH(8)) dut (.*);

  // 时钟生成
  initial begin
    clk = 0;
    forever #5 clk = ~clk;
  end

  // 参考模型(行为级FIFO)
  reg [7:0] ref_mem[0:7];
  int ref_wptr = 0, ref_rptr = 0;

  // 比较器
  always @(posedge clk) begin
    if (rd_en && !empty) begin
      assert(data_out === ref_mem[ref_rptr]) else $error("Data mismatch!");
      ref_rptr = (ref_rptr + 1) % 8;
    end
  end
endmodule

4.测试用例示例

// 测试1:正常写入和读取
initial begin
  rst = 1;
  #10 rst = 0;
  repeat(10) begin
    @(negedge clk);
    wr_en = 1;
    data_in = $random;
    ref_mem[ref_wptr] = data_in; // 更新参考模型
    ref_wptr = (ref_wptr + 1) % 8;
  end
  // 读取并验证数据...
end

// 测试2:溢出测试
initial begin
  rst = 1;
  #10 rst = 0;
  repeat(9) begin // 写入9次,触发溢出
    @(negedge clk);
    wr_en = 1;
    data_in = $random;
  end
  assert(full) else $error("FIFO未满!");
end

5.覆盖率收集

定义覆盖率组:

covergroup fifo_cov;
  coverpoint dut.wptr { bins wptr = {[0:7]}; }
  coverpoint dut.rptr { bins rptr = {[0:7]}; }
  cross dut.wptr, dut.rptr; // 覆盖读写指针组合
endgroup

6.回归测试

使用makefile自动化运行所有测试

sim:
  vlib work
  vlog fifo.v fifo_tb.v
  vsim -c fifo_tb -do "run -all; quit"

实例2:

AXI4-Lite总线接口验证

1. 设计概述

  • DUT: AXI4-Lite 从设备接口,支持寄存器读写,包含以下功能:
    • 支持32位地址和数据总线。
    • 支持单次读写操作(无Burst传输)。
    • 错误处理:解码错误(访问未映射地址时返回SLVERR响应)。
  • 应用场景: SoC中外设寄存器配置(如GPIO、UART控制器)。

2. 验证计划

  • 功能点:
    • 正常读写:验证地址对齐、数据正确性。
    • 错误注入:访问未映射地址时返回SLVERR。
    • 协议合规性:检查AXI信号时序(如VALID先于READY)。
  • 覆盖率目标:
    • 代码覆盖率 > 98%(Line + Branch + FSM)。
    • 功能覆盖率:地址范围、读写操作组合、错误响应覆盖。

3. 验证环境(基于UVM框架)​

 

systemverilog

// UVM Testbench 架构
class axi_lite_env extends uvm_env;
  // 组件实例化
  axi_lite_agent      agent;      // 驱动和监控AXI信号
  reg_block           reg_model;  // 寄存器模型(参考模型)
  axi_lite_scoreboard scoreboard; // 数据比对器
  coverage_collector  coverage;   // 覆盖率收集

  // UVM Phase 初始化
  function void build_phase(uvm_phase phase);
    agent = axi_lite_agent::type_id::create("agent", this);
    reg_model = reg_block::type_id::create("reg_model", this);
    scoreboard = axi_lite_scoreboard::type_id::create("scoreboard", this);
    coverage = coverage_collector::type_id::create("coverage", this);
  endfunction
endclass
关键组件说明:
  1. AXI Agent:
    • Driver: 生成符合AXI协议的读写操作(支持随机化地址和数据)。
    • Monitor: 捕获总线上的实际传输,发送至Scoreboard和Coverage。
  2. 寄存器模型 (Register Model):
    • 镜像DUT内部寄存器状态,预测读写结果。
  3. Scoreboard:
    • 比较DUT输出与寄存器模型的预测值(如读数据、SLVERR响应)。
  4. Coverage Collector:
    • 收集以下覆盖率:
       

      systemverilog

      covergroup axi_cov;
        // 地址范围:覆盖所有可访问寄存器地址
        address_cp: coverpoint addr {
          bins reg0 = {32'h0000_0000};
          bins reg1 = {32'h0000_0004};
          bins invalid = {[32'h0000_0008:32'hFFFF_FFFF]};
        }
        // 操作类型:读写组合
        op_cp: coverpoint {read, write} {
          bins read_op = {1};
          bins write_op = {2};
        }
        // 错误响应覆盖率
        error_cp: coverpoint resp {
          bins ok = {AXI_OKAY};
          bins slverr = {AXI_SLVERR};
        }
      endgroup

4. 测试用例设计

用例1:基础寄存器读写
 

systemverilog

class basic_rw_test extends uvm_test;
  virtual task run_phase(uvm_phase phase);
    // 写入寄存器0,数据为0xA5A5_A5A5
    axi_lite_seq::start(agent.seqr, .addr(32'h0000_0000), .data(32'hA5A5_A5A5), .is_write(1));
    // 读取寄存器0,验证数据
    axi_lite_seq::start(agent.seqr, .addr(32'h0000_0000), .is_write(0));
    assert (scoreboard.last_rd_data == 32'hA5A5_A5A5) else uvm_error("DATA_MISMATCH");
  endtask
endclass
用例2:错误注入测试
 

systemverilog

class error_test extends uvm_test;
  virtual task run_phase(uvm_phase phase);
    // 尝试访问未映射地址0xFFFF_0000
    axi_lite_seq::start(agent.seqr, .addr(32'hFFFF_0000), .is_write(0));
    // 验证响应为SLVERR
    assert (scoreboard.last_resp == AXI_SLVERR) else uvm_error("SLVERR_NOT_RECEIVED");
  endtask
endclass
用例3:随机化测试
 

systemverilog

class random_test extends uvm_test;
  virtual task run_phase(uvm_phase phase);
    repeat(1000) begin
      // 随机生成地址(覆盖合法和非法范围)、操作类型(读/写)
      axi_lite_seq::start(agent.seqr, .addr($urandom_range(0, 32'hFFFF_FFFF)), .is_write($urandom%2));
    end
  endtask
endclass

5. 仿真与调试

  • 波形调试: 使用Verdi或SimVision查看AXI信号时序(如VALID/READY握手)。
  • 断言检查: 插入协议断言确保设计符合AXI规范:
     

    systemverilog

    // 断言:VALID信号一旦置高,必须保持到READY置高
    property valid_hold;
      @(posedge clk) disable iff (rst) 
      $rose(axi_valid) |-> axi_valid throughout axi_ready [->1];
    endproperty
    assert_valid_hold: assert property (valid_hold);

6. 覆盖率分析与改进

  • 覆盖率报告:
    • 代码覆盖率: 通过VCS或Questa生成,确保所有代码分支(如错误处理逻辑)被覆盖。
    • 功能覆盖率: 通过回归测试迭代补充用例,例如:
      • 若发现“连续写后读”场景未覆盖,增加对应测试序列。

7. 回归测试自动化

  • 脚本示例 (Makefile):
     

    makefile

    run_tests:
      for test in basic_rw_test error_test random_test; do \
        vcs -sverilog axi_lite_dut.sv axi_lite_tb.sv +define+UVM_NO_RELNOTES; \
        ./simv +UVM_TESTNAME=$$test; \
        urg -format both -dir simv.vdb; \
      done
  • CI/CD集成: 通过Jenkins/GitLab CI自动运行回归测试并生成覆盖率报告。

8. 工业实践关键点

  1. 模块化与复用:
    • AXI Agent可封装为通用组件,复用于其他AXI接口验证。
  2. 随机约束:
    • 使用rand变量和constraint控制随机化范围,例如限制90%的操作为合法地址。
  3. 性能测试:
    • 添加吞吐量测试(如连续1000次读写的延迟统计)。
  4. 门级仿真:
    • 在综合后网表上重跑测试用例,验证时序收敛性。

总结

通过以上流程,一个工业级AXI4-Lite接口的验证可实现:

  • 高可靠性: 协议断言和随机测试覆盖极端场景。
  • 高效率: UVM框架支持测试用例快速迭代。
  • 可追溯性: 覆盖率报告与回归测试确保需求完全覆盖。

四、关键点总结

  1. 模块化:Testbench组件需解耦,便于复用。
  2. 自动化:通过脚本实现编译、仿真、覆盖率分析全流程。
  3. 覆盖率驱动:以覆盖率为导向迭代补充测试用例。
  4. 断言与参考模型:实时验证协议正确性,避免后处理分析延迟。

通过以上流程,可系统性地完成Verilog模块的验证,确保设计符合功能需求且鲁棒性达标。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值