3. 编写UVM sequence产生随机激励

编写UVM sequence产生随机激励 学习卡片

任务目标

编写一个UVM sequence,通过约束随机生成AHB-like总线事务(地址、数据、读写控制),并经sequencer发送至driver,最终在testbench中完成激励生成与驱动的闭环验证。

环境依赖

需要UVM-1.2库(或等效实现),仿真器支持+UVM_TESTNAME参数传递。以下代码基于标准UVM类库编写,不依赖额外IP。

核心实现

// 文件: ahb_transaction.svh
class ahb_transaction extends uvm_sequence_item;
    rand bit [31:0] addr;
    rand bit [31:0] data;
    rand bit       write;
    rand bit [1:0]  burst;

    constraint c_addr_range { addr inside {[32'h0000_1000 : 32'h0000_2FFF]}; }
    constraint c_burst_valid { burst != 2'b00; }  // 禁止单次突发

    `uvm_object_utils_begin(ahb_transaction)
        `uvm_field_int(addr, UVM_ALL_ON)
        `uvm_field_int(data, UVM_ALL_ON)
        `uvm_field_int(write, UVM_ALL_ON)
        `uvm_field_int(burst, UVM_ALL_ON)
    `uvm_object_utils_end

    function new(string name = "ahb_transaction");
        super.new(name);
    endfunction
endclass

// 文件: my_sequence.svh
class my_sequence extends uvm_sequence #(ahb_transaction);
    `uvm_object_utils(my_sequence)

    function new(string name = "my_sequence");
        super.new(name);
    endfunction

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

// 文件: my_driver.svh
class my_driver extends uvm_driver #(ahb_transaction);
    `uvm_component_utils(my_driver)

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

    virtual task run_phase(uvm_phase phase);
        ahb_transaction tx;
        forever begin
            seq_item_port.get_next_item(tx);
            // 模拟驱动:打印事务内容(实际设计中此处驱动总线信号)
            `uvm_info("DRV", $sformatf("Driving: %s", tx.convert2string()), UVM_MEDIUM)
            seq_item_port.item_done();
        end
    endtask
endclass

// 文件: testbench_top.sv(最小验证环境)
module testbench_top;
    import uvm_pkg::*;

    // 简单连接:driver直接挂在sequencer上
    class my_env extends uvm_env;
        `uvm_component_utils(my_env)
        my_driver drv;
        uvm_sequencer #(ahb_transaction) seqr;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            drv  = my_driver::type_id::create("drv", this);
            seqr = uvm_sequencer#(ahb_transaction)::type_id::create("seqr", this);
        endfunction

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            drv.seq_item_port.connect(seqr.seq_item_export);
        endfunction
    endclass

    class my_test extends uvm_test;
        `uvm_component_utils(my_test)
        my_env env;

        function new(string name, uvm_component parent);
            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_sequence seq;
            phase.raise_objection(phase);
            seq = my_sequence::type_id::create("seq");
            seq.start(env.seqr);
            #100ns;
            phase.drop_objection(phase);
        endtask
    endclass

    initial begin
        run_test("my_test");
    end
endmodule

运行方式

# 使用支持UVM的仿真器(如VCS、Questa等)
vlog +incdir+$UVM_HOME/src $UVM_HOME/src/uvm.sv \
     ahb_transaction.svh my_sequence.svh my_driver.svh testbench_top.sv
vsim -c -do "run -all; quit" testbench_top +UVM_TESTNAME=my_test

验证方法与判定标准

  1. 约束随机性验证:观察打印的10个事务,确认addr始终在0x1000~0x2FFF范围内,且burst值不为0。
  2. 驱动闭环验证:仿真日志中应出现10条UVM_INFO DRV记录,每条包含完整的地址、数据、读写和突发类型信息,表明sequence生成的每个事务均被driver成功接收并处理。
  3. 无UVM错误:仿真结束时UVM报告无UVM_ERROR或UVM_FATAL,且objection机制正确平衡(无“Objection raised but not dropped”警告)。

若日志中事务数量不足10或地址越界,则说明随机约束或sequence-driver握手存在缺陷,需检查约束声明和start_item/finish_item调用时序。