2. 编写第一个UVM测试用例

任务说明

在已有UVM验证环境(含driver、monitor、scoreboard)基础上,编写第一个UVM测试用例:通过sequence产生随机激励,由scoreboard自动比对DUT输出,最终通过UVM报告机制确认测试通过。本案例聚焦测试层(test→sequence→sequencer)的编写与运行闭环,不重复搭建完整环境。

环境依赖

  • UVM库(推荐1.2+,兼容1800.2)
  • 仿真器:VCS、QuestaSim或Xcelium任一
  • 已有可用的UVM环境:包含my_driver、my_monitor、my_scoreboard、my_env(本案例不展开这些组件的实现,仅使用其接口)

关键完整代码

// 文件: test_my_case.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

// 1. 随机激励序列:产生N个随机数据包
class my_random_seq extends uvm_sequence #(my_transaction);
    `uvm_object_utils(my_random_seq)
    function new(string name = "my_random_seq");
        super.new(name);
    endfunction

    rand int unsigned num_pkts;
    constraint c_num { num_pkts inside {[10:20]}; }

    task body();
        my_transaction tx;
        repeat (num_pkts) begin
            tx = my_transaction::type_id::create("tx");
            start_item(tx);
            assert(tx.randomize());
            finish_item(tx);
        end
    endtask
endclass

// 2. 测试用例:配置sequence并启动
class test_my_case extends uvm_test;
    `uvm_component_utils(test_my_case)
    my_env env;

    function new(string name = "test_my_case", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        env = my_env::type_id::create("env", this);
    endfunction

    task run_phase(uvm_phase phase);
        my_random_seq seq;
        seq = my_random_seq::type_id::create("seq");
        phase.raise_objection(this);
        begin
            assert(seq.randomize());
            seq.start(env.agent.sequencer);
        end
        #100ns; // 等待scoreboard完成最后比对
        phase.drop_objection(this);
    endtask

    function void report_phase(uvm_phase phase);
        super.report_phase(phase);
        // 通过UVM报告机制自动汇总:若scoreboard检测到不匹配,
        // 会打印UVM_ERROR,仿真结束时UVM会自动统计并判定失败
        if (uvm_report_server::get_server()->get_severity_count(UVM_ERROR) == 0)
            `uvm_info("TEST", "=== TEST PASSED: 所有数据比对一致 ===", UVM_LOW)
        else
            `uvm_error("TEST", "=== TEST FAILED: 存在比对错误 ===")
    endfunction
endclass

运行与验证

  1. 编译(以QuestaSim为例):
    vlog -sv +incdir+$UVM_HOME/src $UVM_HOME/src/uvm_pkg.sv test_my_case.sv
  2. 仿真:
    vsim -c -do "run -all; quit" +UVM_TESTNAME=test_my_case work.top_module
    (top_module为你的顶层模块,需实例化DUT并连接UVM接口)
  3. 通过条件:
    仿真结束时日志中出现 UVM_ERROR : 0,且打印 TEST PASSED。若scoreboard发现数据不匹配,会打印UVM_ERROR,仿真结束时报错并打印 TEST FAILED。

关键说明

  • 本测试通过my_random_seq产生10~20个随机事务,经sequencer发送至driver,driver驱动DUT后由monitor采集响应,scoreboard自动比对。测试自身不直接检查数据,而是依赖scoreboard的UVM_ERROR报告。
  • #100ns延迟用于确保scoreboard在最后一个事务后完成所有比对,避免提前drop objection导致比对未完成。若你的scoreboard使用uvm_analysis_imp同步比对,可适当缩短或移除该延迟。
  • 若环境中没有名为env.agent.sequencer的路径,请按实际层次修改seq.start()中的sequencer句柄。