uvm之virtual sequence机制

本文介绍如何在UVM验证环境中使用virtualsequence机制解决多个sequencer和sequence之间的调度冲突问题。通过实例化virtualsequencer,并在connect_phase阶段将其与各个环境中的sequencer相连接,实现复杂验证场景下的高效调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

《uvm实战》书上介绍的uvm验证平台,往往只有一个in_agent(即包括driver、in_monitor和sequencer)。

然而,一个agent代表一种协议。
由sequence机制的简单理解,可以知道,1个sequencer负责多个sequence的顺序调度。如果出现多个driver或者多个sequencer,必然出现顺序执行的调度问题。

举个例子,一个IP,包括APB寄存器配置接口、AXIslaver数据接口、AXImaster数据接口。像这样的IP,搭建其验证平台,往往需要3个in_agent;于是出现了3个driver、3个sequencer,另外还有N个sequence。(类似IP env环境,重用到Chip env环境里。)

virtual sequence机制,就是为了解决N个sequence、多个sequencer同时调度的冲突问题。

这里写图片描述

实现步骤

  • 定义virtual sequencer,里面包含各个env里的sequencer类型的指针。
  • base_test作为uvm_test_top,即uvm树形结构的最顶层。负责chip_env和virtual sequencer的规划。
    • 实例化virtual sequencer;
    • virtual sequencer与各env的sequencer连接在一起,具体实现是通过function connect_phase对virtual sequencer的指针,赋值为各个env的sequencer实例层次。
  • 定义virtual sequence。
    • 多个sequence的实例化
    • 利用`uvm_do_on类型宏,实现指定某个sequencer(这个由vritual sequencer的`uvm_declare_p_sequencer宏和p_sequencer公共变量来指定)负责各个sequence的顺序调度。
      注意:`uvm_do这样的宏,针对的处理对象,不仅仅是transaction,还可以处理sequence。
  • 在my_case0类似的case定义中,使用uvm_config_db方式实现virtual sequencer和virtual sequence的default_sequence设置。

细节分析

  1. base_test类里,实例化virtual sequencer。并在其function connect_phase里实现virtual sequencer的指针(其中,virtual sequencer类里定义sequencer的指针)与各env(envA、envB、envC)的sequencer层次连接在一起。
  2. sequence里组织事务的产生。其中virtual sequence里组织的是sequence的顺序调度。所以,在uvm验证平台里,有一个现象,sequence类的参数类型是my_transaction;而virtual sequence类的定义是没有参数的。
  3. virtual sequence里负责start_phase的raise_objection和drop_objection,避免不必要的重复定义。这是uvm实战里约定的。其中drop_objection代码注释后,可以使验证平台不自动$finish。
  4. 4.
<think>嗯,用户想了解UVMvirtualsequence的作用与使用方法。我首先需要梳理清楚核心概念,避免混淆virtualsequencevirtualsequencer的区别。从用户的提问方式来看,应该已经对基础sequence有了解,但可能在多组件同步场景中遇到了瓶颈。用户的引用材料[1][2]很有价值,特别提到了"不产生transaction"和"调度真实sequence"的特性。这提示我应当重点解释它的协调功能,比如AXI和APB总线的同步场景。用户可能需要具体知道怎么连接virtualsequencer与物理sequencer的指针,这块要配合代码片段说明。考虑到用户要教程级指导,得把步骤拆解清楚:先创建virtualsequencer并包含物理sequencer句柄,再建立virtualsequence的启动机制。关键的set_connections方法容易出错,需要强调parent_sequencer的手动连接操作。使用场景上,用户可能正在处理跨时钟域验证,或是多协议协同测试。可以举中断处理+数据流的复合场景案例,这样比纯理论说明更直观。异步复位情境的波形图也是重点,virtualsequence能保持多个sequence的复位同步性。要提醒注意事项的级别,尤其是避免直接挂载到agent而忘了virtualsequencer的中间层。调试技巧部分也值得补充,比如常见错误"Nullobjectaccess"往往就是指针未初始化造成的。</think> 下面详细介绍UVM中的`virtual sequence`作用及使用教程,结合引用内容进行系统说明: --- ### **一、Virtual Sequence 的核心作用** 1. **跨组件同步协调** - 协调多个物理sequence(如APB/AXI/UART驱动)的执行顺序 - 实现场景级同步(例:当AXI完成DMA传输后触发UART发送中断) - ▶️ 本质是**控制调度器**而非数据产生器[^1] 2. **资源访问中枢** 通过`virtual sequencer`内含的句柄访问物理sequencer: ```systemverilog class my_virtual_sequencer extends uvm_sequencer; apb_sequencer p_apb_sqr; // APB接口句柄 axi_sequencer p_axi_sqr; // AXI接口句柄 endclass ``` ![Virtual Sequence调度示意图](https://via.placeholder.com/500x200?text=virtual_sequencer+连接物理sequencer) *示意图:virtual sequencer集中管理物理sequencer* 3. **提升代码复用** 将复杂场景(如总线交互+数据校验)封装成独立可重用的virtual sequence --- ### **二、使用教程(四步法)** #### **步骤1:创建virtual sequencer** ```systemverilog class v_sqr extends uvm_sequencer; // 声明指向物理sequencer的指针 apb_sequencer apb_sqr; axi_sequencer axi_sqr; `uvm_component_utils(v_sqr) endclass ``` #### **步骤2:连接物理sequencer** 在`test`或`env`中建立连接: ```systemverilog class my_env extends uvm_env; v_sqr v_sqr; apb_agent apb_agt; axi_agent axi_agt; function void connect_phase(uvm_phase phase); // 关键连接操作 v_sqr.apb_sqr = apb_agt.sequencer; v_sqr.axi_sqr = axi_agt.sequencer; endfunction endclass ``` #### **步骤3:编写virtual sequence** ```systemverilog class bus_sync_seq extends uvm_sequence; `uvm_object_utils(bus_sync_seq) // 声明virtual sequencer句柄 v_sqr v_sqr; task body(); apb_trans_seq apb_seq = new("apb_seq"); axi_dma_seq axi_seq = new("axi_seq"); fork axi_seq.start(v_sqr.axi_sqr); // 启动AXI传输 apb_seq.start(v_sqr.apb_sqr); // 并行启动APB配置 join #10ns; // 等待同步完成 endtask endclass ``` #### **步骤4:在test中启动virtual sequence** ```systemverilog class base_test extends uvm_test; task run_phase(uvm_phase phase); bus_sync_seq sync_seq = new(); sync_seq.start(env.v_sqr); // 挂载到virtual sequencer endtask endclass ``` --- ### **三、典型应用场景** 1. **多协议协同** ```mermaid sequenceDiagram VirtualSequence->>AXI_sequencer: 启动DMA传输 VirtualSequence->>APB_sequencer: 配置外设寄存器 VirtualSequence->>UART_sequencer: 发送完成中断 ``` 2. **原子操作封装** ```systemverilog task perform_boot(); flash_erase_seq.start(v_sqr.flash_sqr); firmware_load_seq.start(v_sqr.axi_sqr); signature_check_seq.start(v_sqr.apb_sqr); endtask ``` 3. **动态场景切换** 根据寄存器状态切换sequence组合: ```systemverilog if(reg_model.mode_reg.get() == DMA_MODE) dma_sequence.start(v_sqr); else poll_sequence.start(v_sqr); ``` --- ### **四、调试技巧** 1. **空指针检查** 在virtual sequence中首次访问前添加: ```systemverilog if(v_sqr == null || v_sqr.axi_sqr == null) `uvm_fatal("NULLPTR", "Virtual sequencer连接错误!") ``` 2. **层次化追踪** 使用`uvm_top.print_topology()`确认virtual sequencer连接关系 --- ### **常见问题解答** **Q:virtual sequence能直接使用physical sequencer吗?** ▶️ 不可直接使用,必须通过virtual sequencer中转(否则无法访问跨组件资源)[^2] **Q:多个virtual sequence会冲突吗?** ▶️ 需注意:不同virtual sequence同时访问同物理sequencer时需仲裁,推荐设置`sequence`的优先级参数: ```systemverilog high_pri_seq.start(v_sqr.axi_sqr, null, , UVM_SEQ_PRIORITY_HIGH); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值