UVM实战:virtual sequence与virtual sequencer的协同调度机制解析

1. 从“单兵作战”到“集团军指挥”:为什么我们需要virtual sequence和virtual sequencer?

刚开始接触UVM验证的时候,我们写的sequence通常都很“单纯”。比如,你有一个AXI总线的主设备,那么你就写一个AXI的sequence,里面用uvm_do宏生成几个transaction,然后通过start()方法挂载到对应的AXI sequencer上。这个sequencer再把transaction交给driver,驱动到接口上。整个过程清晰明了,就像是一个士兵(sequence)听从一个班长(sequencer)的指挥,完成一项具体的任务。

但是,真实的芯片验证场景,哪有这么简单?想象一下,你现在要验证一个复杂的SoC子系统,比如一个数据通路模块。这个模块一头连着几个数据输入通道(Channel),另一头连着一个格式化输出单元(Formatter),中间还受控于一个配置寄存器(Register)模块。验证这个模块,你需要同时做几件事:给几个通道发送不同模式的数据包;动态配置格式化器的参数;还要时不时地读写寄存器来改变模块的工作模式。

这时候,如果你还用“单兵作战”的思路,问题就来了。你写了三个sequence:一个发数据的data_seq,一个配寄存器的reg_cfg_seq,一个控制格式化器的fmt_seq。你怎么让它们协同工作?难道在测试用例(test)里,一个一个地start,然后用fork...join把它们并行起来?且不说代码会变得臃肿混乱,更关键的是,它们之间的时序和逻辑依赖关系很难优雅地描述。比如,你必须先完成寄存器的基本配置,才能启动数据流;或者,在测试的某个阶段,需要暂停通道0的数据,单独对通道1进行压力测试。

这种需要跨多个sequencer、协调多种类型sequence执行流程的场景,就是virtual sequencevirtual sequencer大显身手的地方。你可以把virtual sequencer想象成集团军的“指挥部”,它本身不直接带兵打仗(不产生具体的transaction),但它手里掌握着所有一线作战部队(各个底层sequencer)的通讯录(句柄)。而virtual sequence,就是坐在这个指挥部里的“总指挥”,它根据作战计划(测试场景),通过指挥部里的通讯录,向不同的部队下达精确的、有时序要求的命令(启动具体的sequence)。

我刚开始在项目里用这组机制时,感觉就像打开了新世界的大门。以前那种在test里手忙脚乱协调多个sequence的“土办法”被彻底抛弃了,测试场景的抽象度和可控性上了好几个台阶。接下来,我就结合一个具体的案例,带你看看这个“指挥部”和“总指挥”是怎么搭建和工作的。

2. 核心角色拆解:virtual sequencer如何成为“路由枢纽”?

我们先来深入看看virtual sequencer。很多新手容易把它想复杂了,其实它的定义非常简单。从代码继承关系上说,它就是一个普通的uvm_sequencer,并没有什么特殊的基类。

class mcdf_virtual_sequencer extends uvm_sequencer;
    // 1. 声明各个底层sequencer的句柄
    cr_master_sequencer   cr_sqr;
    reg_master_sequencer  reg_sqr;
    chnl_master_sequencer chnl_sqr0;
    chnl_master_sequencer chnl_sqr1;
    chnl_master_sequencer chnl_sqr2;
    fmt_slave_sequencer   fmt_sqr;

    `uvm_component_utils(mcdf_virtual_sequencer)
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
endclass

看上面的代码,mcdf_virtual_sequencer的核心作用就一点:声明并容纳多个底层sequencer的句柄。你可以把它看作一个“句柄容器”或者“路由表”。cr_sqrreg_sqrchnl_sqr0等等,这些句柄在virtual sequencer创建之初都是空的(null)。它自己并不知道这些cr_sqr具体对应环境中的哪个agent下面的sequencer实体。

那么,谁来把这些“名字”和“真人”对上号呢?答案是顶层的环境类(uvm_env)。这步操作通常发生在环境的connect_phase。这个阶段,环境中所有的组件都已经构建(build)好了,实体对象都存在于内存中,正是进行“连线”的好时机。

class mcdf_env extends uvm_env;
    // 声明各个具体的agent
    cr_master_agent   cr_agt;
    reg_master_agent  reg_agt;
    chnl_master_agent chnl_agt0;
    chnl_master_agent chnl_agt1;
    chnl_master_agent chnl_agt2;
    fmt_slave_agent   fmt_agt;
    // 声明virtual sequencer
    mcdf_virtual_sequencer virt_sqr;

    `uvm_component_utils(mcdf_env)
    // ... new和build_phase省略,其中需
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值