IC验证06--UVM Sequence 基础示例与解析(附源码)

概要

在 UVM 验证环境中,Sequence 是生成激励事务(Transaction)的核心组件。下面通过一个完整示例,详细说明 Sequence 的结构、关键组件及使用方法。

一、基本 Sequence 结构示例

// 1. 定义事务类
class my_transaction extends uvm_sequence_item;
    rand bit [7:0] addr;
    rand bit [15:0] data;
    rand bit        wr_rd;  // 1=写, 0=读
    
    // 约束条件
    constraint c_addr_range { addr inside {[8'h00:8'hFF]}; }
    constraint c_wr_data { wr_rd == 1 -> data > 16'h100; }
    
    // 注册到UVM工厂
    `uvm_object_utils_begin(my_transaction)
        `uvm_field_int(addr,  UVM_ALL_ON)
        `uvm_field_int(data,  UVM_ALL_ON)
        `uvm_field_int(wr_rd, UVM_ALL_ON)
    `uvm_object_utils_end
    
    function new(string name = "my_transaction");
        super.new(name);
    endfunction
    
    // 自定义方法:打印事务信息
    virtual function void print_info();
        `uvm_info("TRANS", $sformatf("Addr=0x%02h, Data=0x%04h, Wr/Rd=%b", 
                                      addr, data, wr_rd), UVM_MEDIUM)
    endfunction
endclass

// 2. 定义基础Sequence类
class base_sequence extends uvm_sequence #(my_transaction);
    `uvm_object_utils(base_sequence)
    
    // 存储配置参数的句柄
    my_config cfg;
    
    function new(string name = "base_sequence");
        super.new(name);
    endfunction
    
    // body()方法:Sequence的核心执行体
    virtual task body();
        my_transaction tx;
        
        // 1. 从config_db获取配置参数(如果有)
        if (!uvm_config_db#(my_config)::get(null, get_full_name(), "cfg", cfg))
            `uvm_warning("CFG", "No config provided, using default values")
        
        // 2. 创建并随机化事务
        `uvm_do(tx)  // 等价于:
                     // tx = my_transaction::type_id::create("tx");
                     // start_item(tx);
                     // if (!tx.randomize()) `uvm_fatal("RAND", "Transaction randomization failed");
                     // finish_item(tx);
        
        // 3. 可选:修改事务属性
        tx.print_info();
    endtask
endclass

// 3. 定义具体测试Sequence(继承自base_sequence)
class write_sequence extends base_sequence;
    `uvm_object_utils(write_sequence)
    
    function new(string name = "write_sequence");
        super.new(name);
    endfunction
    
    // 重写body()方法
    virtual task body();
        my_transaction tx;
        
        // 生成5个写事务
        repeat (5) begin
            `uvm_do_with(tx, { wr_rd == 1; addr < 8'h80; })
            tx.print_info();
        end
    endtask
endclass

class read_sequence extends base_sequence;
    `uvm_object_utils(read_sequence)
    
    function new(string name = "read_sequence");
        super.new(name);
    endfunction
    
    // 重写body()方法
    virtual task body();
        my_transaction tx;
        
        // 生成3个读事务
        repeat (3) begin
            `uvm_do_with(tx, { wr_rd == 0; addr >= 8'h80; })
            tx.print_info();
        end
    endtask
endclass

// 4. 定义复合Sequence(包含多个子Sequence)
class mixed_sequence extends base_sequence;
    `uvm_object_utils(mixed_sequence)
    
    write_sequence write_seq;
    read_sequence  read_seq;
    
    function new(string name = "mixed_sequence");
        super.new(name);
    endfunction
    
    virtual task body();
        // 创建子Sequence
        write_seq = write_sequence::type_id::create("write_seq");
        read_seq  = read_sequence::type_id::create("read_seq");
        
        // 顺序执行子Sequence
        `uvm_info("MIXED", "Starting write sequence", UVM_MEDIUM)
        write_seq.start(m_sequencer);
        
        `uvm_info("MIXED", "Starting read sequence", UVM_MEDIUM)
        read_seq.start(m_sequencer);
        
        // 可选:并行执行子Sequence
        // fork
        //     write_seq.start(m_sequencer);
        //     read_seq.start(m_sequencer);
        // join
    endtask
endclass

二、关键组件解析

1. 事务类(Transaction Class)

核心要素:

  • 随机化属性(rand变量)
  • 约束条件(constraint块)
  • 工厂注册(uvm_object_utils宏)
  • 自动化字段(uvm_field_*宏)

作用:封装激励数据,定义合法取值范围

2. Sequence 类

核心方法:

  • body():Sequence 的主执行体
  • start():启动 Sequence
  • pre_body()/post_body():执行前 / 后的钩子函数

关键 API:

  • uvm_do():创建、随机化并发送事务
  • uvm_do_with():带约束的事务生成
  • start_item()/finish_item():手动控制事务流程

3. Sequencer

作用:

  • 调度和管理 Sequence 执行
  • 实现 Sequence 间的同步和仲裁

连接方式:

  • 通过seq_item_port连接到 Driver
  • 通过analysis_port发布生成的事务

三、在验证环境中使用 Sequence

1. 环境配置

class my_agent extends uvm_agent;
    my_sequencer sequencer;
    my_driver    driver;
    my_monitor   monitor;
    
    `uvm_component_utils(my_agent)
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        
        // 创建组件
        if (is_active == UVM_ACTIVE) begin
            sequencer = my_sequencer::type_id::create("sequencer", this);
            driver    = my_driver::type_id::create("driver", this);
        end
        monitor = my_monitor::type_id::create("monitor", this);
    endfunction
    
    virtual function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        
        // 连接driver和sequencer
        if (is_active == UVM_ACTIVE) begin
            driver.seq_item_port.connect(sequencer.seq_item_export);
        end
    endfunction
endclass

2. 在测试中启动 Sequence

class my_test extends uvm_test;
    my_env env;
    
    `uvm_component_utils(my_test)
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        env = my_env::type_id::create("env", this);
    endfunction
    
    virtual task run_phase(uvm_phase phase);
        mixed_sequence seq;
        
        phase.raise_objection(this, "Running mixed sequence");
        
        // 创建并启动Sequence
        seq = mixed_sequence::type_id::create("seq");
        seq.start(env.agent.sequencer);
        
        phase.drop_objection(this, "Sequence completed");
    endtask
endclass

3. Driver 接收并执行事务

class my_driver extends uvm_driver #(my_transaction);
    `uvm_component_utils(my_driver)
    
    virtual my_if vif;  // 接口句柄
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
            `uvm_fatal("DRV", "Could not get vif")
    endfunction
    
    virtual task run_phase(uvm_phase phase);
        my_transaction tx;
        
        forever begin
            // 从sequencer获取事务
            seq_item_port.get_next_item(tx);
            
            // 执行事务(驱动DUT)
            drive_transaction(tx);
            
            // 通知sequencer事务完成
            seq_item_port.item_done();
        end
    endtask
    
    virtual task drive_transaction(my_transaction tx);
        // 根据事务内容驱动接口信号
        if (tx.wr_rd) begin
            // 写操作
            vif.addr <= tx.addr;
            vif.data <= tx.data;
            vif.wr_en <= 1'b1;
            @(posedge vif.clk);
            vif.wr_en <= 1'b0;
        end else begin
            // 读操作
            vif.addr <= tx.addr;
            vif.rd_en <= 1'b1;
            @(posedge vif.clk);
            vif.rd_en <= 1'b0;
            // 读取数据...
        end
    endtask
endclass

四、Sequence 高级特性

1. 参数化 Sequence

class param_sequence extends uvm_sequence #(my_transaction);
    `uvm_object_utils(param_sequence)
    
    rand int num_trans;
    rand bit [7:0] addr_range;
    
    constraint c_num { num_trans inside {[5:10]}; }
    
    function new(string name = "param_sequence");
        super.new(name);
    endfunction
    
    virtual task body();
        my_transaction tx;
        
        repeat (num_trans) begin
            `uvm_do_with(tx, { addr < addr_range; })
        end
    endtask
endclass

2. Sequence 回调(Callback)

class my_sequence extends uvm_sequence #(my_transaction);
    `uvm_object_utils(my_sequence)
    
    function new(string name = "my_sequence");
        super.new(name);
    endfunction
    
    // 预回调函数
    virtual function void pre_body();
        if (starting_phase != null)
            starting_phase.raise_objection(this, "Running sequence");
    endfunction
    
    // 主执行体
    virtual task body();
        // ...
    endtask
    
    // 后回调函数
    virtual function void post_body();
        if (starting_phase != null)
            starting_phase.drop_objection(this, "Sequence completed");
    endfunction
endclass

五、验证流程总结

1、定义事务类:

  • 包含随机化字段和约束条件

  • 注册到 UVM 工厂

2、创建 Sequence:

  • 继承自uvm_sequence
  • 在body()方法中生成事务

3、配置环境:

  • 创建 Sequencer 和 Driver
  • 连接 Sequencer 和 Driver 的端口

4、启动 Sequence:

  • 在测试的run_phase中实例化 Sequence
  • 调用start()方法并指定目标 Sequencer

5、执行与验证:

  • Driver 接收事务并驱动 DUT
  • Monitor 捕获 DUT 响应
  • Scoreboard 比较预期与实际结果

通过这种方式,Sequence 机制实现了激励生成与驱动的分离,提高了验证环境的可重用性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yang_20250429

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值