Quick Start
本指南面向FPGA仿真中遇到仿真时间停止推进、信号卡在特定状态的工程师。通过阅读本文,您将掌握死锁的根本原因、排查流程与修复方法,并能在30分钟内定位并解决常见的组合反馈环死锁问题。
前置条件
- 具备基础的数字电路知识,理解组合逻辑与时序逻辑的区别。
- 熟悉Verilog/VHDL语法,特别是always块与assign语句。
- 拥有可用的仿真工具(如Vivado Simulator、ModelSim、VCS等),并能查看波形。
目标与验收标准
- 目标:能够独立识别并修复FPGA仿真中的死锁问题,确保仿真正常推进至结束。
- 验收标准:仿真时间持续增加,波形中所有握手信号(valid/ready)在指定时钟周期内完成翻转,无无限震荡或停滞。
实施步骤
步骤1:识别死锁现象
启动仿真后,观察波形窗口中的时间戳。如果时间在某个点停止增加(例如停留在100 ns不再前进),且时钟信号仍在正常翻转,则很可能发生了死锁。此时,检查关键握手信号(valid/ready)是否一直为低电平或高阻态。
步骤2:定位组合反馈环
死锁的根本原因是组合逻辑中的反馈环,导致信号在零延迟内无限震荡。排查时,重点检查所有always块的敏感列表是否包含其输出信号。例如,以下代码会形成组合环路:
always @(valid or ready) begin
valid = ready & some_condition;
end这种写法中,valid的变化会触发always块重新计算,而计算又依赖ready,若ready也由valid组合生成,则形成零延迟震荡。正确做法是使用寄存器输出:
always @(posedge clk) begin
valid_reg <= ready & some_condition;
end步骤3:检查握手协议依赖
在valid-ready握手协议中,常见死锁场景是slave的ready生成逻辑直接读取master的valid。例如:
assign ready = valid & fifo_not_full;此时,master的valid又等待ready为高才变化,形成组合环路。正确做法是让ready独立于valid,或使用寄存器打一拍:
always @(posedge clk) begin
ready_reg <= fifo_not_full;
end步骤4:检查Testbench中的无限循环
Testbench中若出现无延迟语句的无限循环(如while(1)),会导致仿真器卡死。确保循环内包含@(posedge clk)或#delay语句,例如:
while(1) begin
@(posedge clk);
// 执行操作
end步骤5:检查复位信号
复位信号未正确释放也可能导致死锁。检查复位同步器输出,确认复位释放后时钟沿有效。例如,异步复位同步释放电路应确保复位信号在时钟上升沿后稳定为高电平。
步骤6:插入寄存器或FIFO打破环路
对于已确认的组合反馈环,常用修复方法包括:



