作者:游昆霖,来源:北京开源芯片研究院
协同仿真(Co-simulation)是处理器核功能验证的重要手段,提供体系结构级功能验证和逐指令出错调试粒度,被学术界及工业界广泛应用,但现有仿真速度仍无法满足大规模验证需要。基于硬件仿真平台的协同仿真加速方法具有更高的理论速度上限,但频繁的软硬件通信成为性能关键瓶颈。
中国科学院计算技术研究所(简称“计算所”)和北京开源芯片研究院(简称“开芯院”)在 MICRO 2025 发表了题为《DiffTest-H: Toward Semantic-Aware Communication in Hardware-Accelerated Processor Verification》的论文,针对硬件加速协同仿真提出语义感知的通信优化方法,在降低通信频率、数据量的同时,保留指令级别的出错调试能力。DiffTest-H 在 FPGA 上达到 7.8MHz 的协同仿真速度,总计帮助“香山”处理器发现超过 150 个复杂 Bug,有效提升“香山”处理器的验证效率。
研究背景
在处理器开发过程中,验证已经成为耗时最长的关键环节。为了提高验证效率,协同仿真(Co-simulation)同时运行可综合的处理器待测设计(Design Under Test, DUT)和软件实现的参考模型(Reference Model, REF),并在每条指令运行后比较二者体系结构状态,提供体系结构级别的功能验证和指令级别的出错调试粒度,被学术界及工业界广泛应用。
在协同仿真中,仿真框架将每条指令从 DUT 中提取体系结构验证事件,如指令提交、寄存器更新等,驱动 REF 相应执行并进行对比。同时,外部中断、外设访问等 DUT 特有的非确定性验证事件,可以被完整从 DUT 同步至 REF,以对齐二者体系结构状态。 然而,现有协同仿真仍面临着仿真速度的问题:传统基于软件 RTL 仿真器的验证方法受限于大规模电路仿真,往往只有 KHz 级别的仿真速度;基于硬件加速器(如Palladium、FPGA)的方法需要将 DUT 和 REF 分别部署在硬件侧和软件侧,通过软硬件通路传输验证事件,如图 1 所示。实验评估表示,尽管现有硬件加速方法可将 DUT 电路仿真加速 300~10000 倍,整体协同仿真加速比仍仅有 2.5~20 倍,高达 99% 的仿真时间消耗于软硬件通信。优化软硬件通信成为提升协同仿真速度的关键问题。
图1:基于硬件仿真平台的协同仿真框架
通信建模分析
在基于硬件仿真平台的协同仿真框架中,软硬件通信主要包含三个阶段:通信启动、数据传输、软件处理。每一次验证事件都会进行一次通信,将 DUT 体系结构状态传输至 REF 进行比对。以 DiffTest 协同仿真验证框架为例,其覆盖 32 种验证事件,平均每周期约产生 15 次通信和 1.2KB 数据传输,产生高昂的软硬件通信开销。
软硬件通信开销可以采用如下公式刻画:
其中,通信启动延迟包含每次通信前的数据准备及软硬件同步时间,例如进行软硬件之间的 valid-ready 握手,并将硬件信号封装为 PCIe 等格式数据包,该部分开销与通信频率相关,频繁的短数据传输将产生显著的通信启动延迟;数据传输开销表示验证事件通过有限带宽通路的传输延迟,与数据量及软硬件通路带宽相关;软件处理延迟表示软件侧运行参考模型,并进行协同仿真检查的用时,现有串行执行的方法中,硬件将暂停等待软件处理完毕。
在不同待测设计(NutShell、香山)和不同硬件仿真平台(Palladium、FPGA)上,不同通信阶段的开销占比如图 2 所示。结果表明,针对通信频次高、单次通信数据量低的协同仿真场景,通信启动延迟成为最主要的通信开销部分。此外,在验证状态种类及数据量更大的复杂处理器验证场景(如“香山”处理器验证)下,数据传输开销显著上升;在高延迟、高带宽的软硬件通路中(如 FPGA PCIe),通信启动的延迟占比更加凸显。
图2:针对不同待测设计、不同仿真平台的软硬件通信开销分解
现有软硬件通信优化工作围绕通信三阶段开展:
通信启动阶段:打包不同类别的验证事件以降低通信频率,例如,将一个周期内的所有验证事件打包为一个长数据包,整体进行一次软硬件握手;
数据传输阶段:压缩相同类别的验证事件以降低通信数据量,例如,N 次指令提交可以被压缩为一次指令数为 N 的指令提交;
软件处理阶段:利用软硬件并行掩盖软件处理延迟,例如,采用非阻塞传输及比对方式,在软件处理的同时允许硬件侧继续向下运行。
然而,现有工作仍未彻底消除软硬件通信速度瓶颈,现有 SOTA 工作 Fromajo 在 100MHz FPGA 平台上的协同仿真速度仅约 1MHz。此外,压缩丢失了单条指令的体系结构行为细节,导致调试能力损失,出错时难以定位具体错误原因。
语义感知通信
针对通信优化的难题,香农–韦弗提出了“语义通信”概念,强调“理解信息的语义”能显著提升通信效率。在协同仿真中,验证事件同样携带三类关键语义属性,可据此优化通信:
结构语义:验证事件长度和数据结构
不同事件类型长度及数据结构差异大,为硬件打包、软件解包带来困难。例如,DiffTest 协同仿真验证框架覆盖 32 种验证事件,事件长度差距最高可达 170 倍。现有打包方法在数据包中为每类事件固定分配一段空间,当验证事件无效时以空泡填充,导致超过 60% 的无效空泡和带宽浪费。
利用结构语义,硬件侧可以根据验证事件的实际长度动态分配空间,将不同类别的变长事件紧凑打包,并由软件侧根据数据结构进行解析。紧凑打包可以消除数据包中无效空泡,提高带宽利用率。
顺序语义:验证事件的检查顺序
不同类型的验证事件遵循特定的检查顺序。例如,外部中断等非确定性验证事件将更新 REF 体系结构状态,需要保证之前的指令均已检查完毕,之后的指令均未检查。现有压缩方法将压缩事件的检查顺序与通信顺序相耦合,一旦在指令的压缩过程中遇到非确定性事件,需要终止指令压缩并传输至软件侧,以保证非确定性事件之前的指令均检查完毕。这将导致压缩频繁中断,压缩率下降。
利用顺序语义,压缩事件的检查顺序可以和通信顺序相解耦,允许非确定性事件先行传输并携带顺序标识,其余验证事件继续进行压缩,由软件侧根据顺序标识恢复检查顺序。顺序解耦的压缩能够减少因非确定性事件导致的压缩中断,降低软硬件通信数据量。
行为语义:验证事件检查的体系结构行为
每个验证事件将检查对应指令的体系结构行为,并将错误定位到相关的微结构部件。然而,压缩丢失了单条指令的行为细节,仅保留最终压缩后的整体行为结果,难以定位出错原因。现有调试方法利用体系结构验证事件定位错误,但仍依赖微结构波形调试,采用硬件快照的方式重新仿真整个 DUT,存在高昂的资源和时间开销。
利用行为语义,可以仅在出错位置附近重新检查压缩前的验证事件,无需重新仿真整个 DUT,即可提供逐指令的体系结构行为细节,保持指令级别的出错调试能力。
DiffTest-H 设计
在团队前期工作 DiffTest 协同仿真验证框架(MICRO’22)的基础上,本篇论文提出一种语义感知的硬件加速协同仿真框架 DiffTest-H,在优化协同仿真软硬件通信的同时,保留指令级别调试粒度。
DiffTest-H 主要包含三点设计:
Batch 优化通信频次,支持将不同结构的验证数据紧凑打包到单次通信
Squash 减少传输数据量,将验证数据的压缩和检查解耦,充分提升压缩率;
Replay 保持指令级别的出错调试粒度,仅重放出错点附近的验证事件,利用逐指令体系结构行为细节辅助调试。
DiffTest-H 在双核香山的验证框架如图 3 所示。
图3:DiffTest-H 验证双核香山框架示意
Batch:紧凑打包不同结构的验证事件
为了最小化通信频率,本工作提出基于结构语义的通信打包方案 Batch,工作流程如图4所示。
Batch 主要包含硬件侧数据打包和软件侧解包两个阶段:
在硬件侧打包过程中,Batch 将结构化的验证信息作为数据打包的基本单位,支持紧凑拼接来自不同结构的变长数据,消除数据空泡;与此同时,生成记录数据结构及数量信息的元数据 Meta,并在编译阶段生成对应的软件侧解析方法。
在软件侧解包过程中,Batch 将根据 Meta 调用相应的解析方法,从通信数据包中提取特定长度的验证数据,并将二进制比特流恢复为具备特定数据结构的验证状态。
实验结果显示,Batch 能够将通信频率降低约 43 倍。
图4:Batch 工作流示意
Squash:解耦检查顺序的高效压缩
为了有效降低协同仿真的通信数据量,本工作提出基于顺序语义的数据压缩方案 Squash,能够在保留正确检查顺序的同时大幅提升压缩效率,工作流程如图 5 所示。
Squash 包括压缩调度、数据差分以及重排序三个阶段:
在压缩调度阶段,Squash 支持将不同压缩事件的传输与检查顺序解耦以保证压缩连续性:非确定事件可以携带顺序标识,先行传输并缓存于软件侧;与此同时,其他验证事件仍可以继续压缩,从而最大限度提升压缩率。
在数据差分阶段,Squash 将压缩事件进一步拆分为更细粒度的单元,如 CSR 中的不同字段。硬件侧对同一类压缩事件的前后两次提交进行差分对比,仅传输变化的部分,从而去除数据冗余。软件侧将根据不变部分进行数据补全,恢复验证事件的完整结构。
在软件侧重排序阶段,不同类别的压缩事件将根据顺序标识重排序,以恢复正确的检查顺序。
实验结果表明,Squash 能够在不影响正确检查顺序的同时,将通信数据量降低 47 倍。
图5:Squash 工作流示意
Replay:逐指令出错调试
为了保留逐条指令粒度的出错调试能力,本工作提出基于验证事件行为语义的出错调试方案 Replay,支持在 Squash 压缩加速的同时保留每条指令的体系结构行为细节,工作流程如图 6 所示。
Replay 主要包含硬件重传和软件重新处理两个部分:
在硬件侧重传部分,Replay 将在压缩验证事件前,首先将其缓存至 Replay Buffer 中并添加标记。该标记将伴随压缩全过程,用于指示压缩事件对应的原始事件范围。当软件侧检查出错时,该标记将用于通知硬件侧确定范围,重新传输对应的原始未压缩事件。
在软件侧重新处理部分,Replay 需要将参考模型的状态恢复至出错前,以便重新检查重传事件。由于每次压缩事件检查时均可能报错,为降低频繁快照的开销,Replay 提出基于修改日志的轻量级状态恢复方法,将每次访存前的原始值保存至日志,并在出错时逆序恢复,从而实现轻量级状态恢复。
实验结果表明,Replay 能够在不影响加速优化效果的同时,实现逐指令的出错调试粒度。
图6:Replay 工作流示意
整体工作流
DiffTest-H 的工作流程如图7所示。在硬件侧,验证信息探针将收集来自不同类别、不同周期的验证事件(①),并将原始事件缓存以供可能的调试需求(②)。验证事件将分别经过压缩(③)和打包(④)得到格式统一的通信数据包,并通过软硬件通路非阻塞式的传输至软件侧(⑤),通过软硬件并行掩盖软件处理延迟。在软件侧,打包后的事件将被拆解、恢复至对应数据结构,并逐项比对检查(⑥)。
当检测到 DUT 和 REF 状态不一致时,Replay 调试模块将根据软件出错信息,通知硬件侧重新传输对应的原始验证事件(⑦),同时恢复参考模型至出错前状态,重新逐指令检查,并获得出错原因及现场报告(⑧)。
图7:DiffTest-H 验证工作流示意
实验结果评估
本工作基于不同待测设计、不同硬件仿真平台,对 DiffTest-H 不同优化组合效果进行评估,如表 1 所示。结果表明,DiffTest-H 在不同待测设计及硬件仿真平台上均取得了 74~80 倍的良好加速比。
表1:DiffTest-H 在不同 DUT 及硬件仿真平台上的优化分解
DiffTest-H 同时支持基于 Emulator/FPGA 硬件仿真平台加速协同仿真。相较现有工作,DiffTest-H 在具有保证更加充分的验证(更多的验证状态种类和单周期验证数据量)的同时,实现更低的软硬件通信开销和更高的协同仿真速度。其中,基于 FPGA 的评测结果相比现有 SOTA 提升 7.8 倍以上。同时,DiffTest-H 保留逐指令的出错调试粒度,能够更好地实现错误定位。
DiffTest-H 已开源(https://github.com/OpenXiangShan/difftest )并应用于开源高性能处理器“香山”的实际开发过程,并在论文复现(Artifact Evaluation)阶段得到全部三个徽章(可获取、功能正确、可重现)。在过去六个月内,DiffTest-H 共帮助“香山”处理器发现定位超过 150 个复杂 Bug,涵盖异常中断处理错误、缓存一致性错误、向量控制逻辑错误等多种错误类别,产生超过 19 个 PR,共计 780 行以上的代码修改。未来 DiffTest-H 将持续推进处理器敏捷验证的探索,提升处理器核验证效率。