根据您描述的CY7C68013A(FX2LP)在同步Slave FIFO模式下与FPGA通信时出现的问题(发送2字节正确,发送4字节以上出现丢失前两个字节、后两个字节重复的现象),结合官方固件未更改的情况,这是一个非常经典且由特定原因导致的同步时序问题。以下是可能的原因和排查步骤:
核心原因分析:
FIFO指针和满标志(`FF)的同步时序问题 (最可能):
- 在同步Slave FIFO模式下,FPGA使用FX2LP提供的
IFCLK来读取FD[]数据和采样状态标志(FF, EF)。
- 关键点:
FF (FIFO 满标志) 的更新相对于IFCLK可能存在一个或几个时钟周期的延迟。
- 问题发生过程:
- 初始状态: FPGA看到
FF=0 (FIFO不满),开始读取。
- 发送小量数据 (如2字节): FX2LP将数据写入FIFO后,
FF可能还来不及拉高,或者即使拉高,因为数据量小,在FF真正起作用前,FPGA已经读走了数据。不会触发问题。
- 发送大量数据 (如4字节以上):
- FX2LP连续将数据写入FIFO。当写到第3或第4个字节时,内部FIFO达到满状态。
- 此时,
FF标志不会立即变为高电平(表示满),它会在随后的某个IFCLK边沿更新。
- 在这个延迟周期内,FPGA并不知道FIFO已经满了,它会继续发出读脉冲(
SLRD或SLRD下降沿取决于配置),试图读取下一个数据。
- 由于FIFO物理上已经满了,这个“额外”的读操作将把当前停留在输出端口上的最后一个有效数据(即刚刚写入的第4个字节)再次读出一次。这是重复字节的来源。
- 同时,由于这次“多余”的读操作消耗了一个FIFO位置,FX2LP看到有空位(或者
FF最终变高但FPGA停止读了),它会继续将剩余的数据写入(丢失的是本该此时写入的第5、第6个字节等等?实际上丢失的是最开始两个字节的空间)。
- 但是FPGA因为之前看到了
FF变高(或其他原因如停止条件),它可能只读了它认为有效的次数(比如4次),而实际有效数据位置由于那次空读被占用了两个,所以读出的结构是:位置3, 位置4 (被读了两次), 位置5, 位置6。但位置上存放的是原本的第3, 第4, 第5, 第6字节。FPGA看到的是:第3字节(正确), 第4字节(正确), 第4字节(重复), 第5字节(应该在第6位)。这就造成了头两个字节丢失(未被正确读出),后两个字节(一个重复,一个后移) 的现象。
- 小结: 根本原因是
FF标志的更新延迟导致FPGA在FIFO实际已满时多读了一个数据,破坏了FIFO的读写指针同步,后续的读写操作全部错位。
固件配置问题 (即使使用官方固件,细节设置仍需确认):
- FLOWSTATE / FIFO Flags:
SYNC位是否已设置? (IFCONFIG, b1) - 确认工作在同步模式。
FLOWSTATE寄存器 (FIFOPINPOLAR): 检查FF (FLAGA)的极性(POLAR)是否正确配置?FX2LP默认输出可能是低有效(POLAR=0),FPGA需要相应处理。FX2LP拉高FF表示满,FPGA端应检查FF为高时停止读。如果极性反了会导致一直读或从不读。
PINFLAGSx寄存器: 确认FLAGA(通常用于FF)是否被正确映射到期望的端点满状态。
- 端点配置 (EPxCFG / EPxFIFOCFG):
- 端点类型 (
TYPE): 确认为0 (Disabled) 或 2 (BULK)。Slave FIFO模式下端点应启用并配置为BULK或其他合适类型。
- 方向 (
DIR): 对于IN端点(FPGA->PC),OUT端点(PC->FPGA,即您的方向)。确认端点方向正确。
- 大小 (
SIZE, INMAXPKT/OUTPKTEND): 虽然官方固件通常会设置合理值(如512字节),但确认端点缓冲区大小设置合理(不是意外设置成了2字节)。
- FIFORESET: 上电或重新枚举后是否发送了适当的
FIFORESET命令来初始化FIFO指针?
FPGA逻辑设计问题:
FF采样和读逻辑 (SLRD) :
- FPGA在哪个
IFCLK边沿采样FF?必须在SLRD有效之前的同一个时钟沿或其后的时钟沿采样状态。
SLRD激活逻辑是否正确?只有在FF=0 (FIFO不满) 时,才应该在每个时钟周期使能读操作吗?在同步模式下,通常是持续时钟,SLRD拉低表示读有效。
- 是否在
SLRD无效期间锁存FD[]数据?数据通常在SLRD从低到高(上升沿)时锁存。
- 状态机设计: FPGA读取的状态机是否过于简单?理想情况是:
- 等待
EF=0 (FIFO不空) && FF=0 (FIFO不满)。(对于OUT端点,FF是关键满标志,EF是空标志)。
- 在
IFCLK有效沿,如果FF=0,则拉低SLRD(如果使用SLRD电平控制)或者在一个IFCLK周期内产生SLRD脉冲(下降沿),并准备锁存数据。
- 在下个
IFCLK有效沿(或SLRD上升沿)锁存FD[]数据。
- 关键:避免在
FF=1时发出任何SLRD脉冲。 这是防止多读的关键。
- 同步器和亚稳态处理:
- 如果您在FPGA内部使用另一个时钟处理数据,
IFCLK域的信号(FD[], FF, EF)是否使用了至少两级寄存器同步后再使用?
IFCLK到FPGA后,是否做过了时钟域约束?
- 时序约束: FPGA项目是否对
IFCLK和FD[]/FF相关的输入路径进行了正确的时序约束?确保满足FX2LP输出的Tsu/Th要求。
硬件问题:
- 信号完整性:
IFCLK, FD[], FF, SLRD等关键信号在PCB上的布线是否良好?是否存在过长的走线、反射或串扰?尤其在48MHz时钟下,信号质量问题可能在某些数据量下显现。
- 电源噪声: FX2LP和FPGA的供电是否干净稳定?特别是在大电流切换或通信时。
- 连接错误: 检查
SLRD, FD[], IFCLK, FF, EF的物理连接是否有误?
针对性排查和解决步骤(优先级排序):
彻底检查FPGA读取端逻辑: 这是最可能的根源。
- 使用逻辑分析仪或FPGA内嵌逻辑分析仪(
ILA/ChipScope/SignalTap)抓取IFCLK, FD[], FF, SLRD (或SLRD),EF的实际波形。
- 重点观察: 在发送4字节数据时,当FX2LP写入第3、4个字节前后:
FF是什么时候拉高的?
SLRD是什么时候发出脉冲(下降沿)的?
SLRD发出脉冲时,FF的值是多少?
- 修复: 修改FPGA状态机,确保在
FF=1时绝对不发出SLRD读脉冲。严格遵循状态机:只有检测到FF=0时才在该时钟周期或下个时钟周期发起读取。考虑在FF变高后,即使数据尚未读完(但已经满了),也要暂停读取,等待FF变低再继续。这通常能解决“多读”的问题。
检查并调整FX2LP固件标志配置:
- 仔细检查
FLOWSTATE (0xE6) 和相关的 PINFLAGSx (0xE8 - 0xEE)寄存器设置。确认FF (FLAGA)对应的是目标OUT端点(FIFO)的满状态,并且极性正确 (POLAR位)。可以尝试修改POLAR位,看看行为是否有变化。
- 尝试在
REVCTL (0xB6)寄存器中设置 DYN_OUT = 1 (Dynammic OUT FIFO Sizing)。这个功能有时能改善FIFO管理行为,尤其是在流量突然变化时。
验证端点配置:
- 使用Control Center的“View->Device Settings”查看端点配置。确认OUT端点大小(
MAX Packet Size)设置合理(如512)。
- 查看
EPxCFG (x 为端点号) 和 EPxFIFOCFG寄存器的值,确认端点类型和方向正确。
检查信号完整性和硬件:
- 如果条件允许,用示波器检查
IFCLK, FD[] (重点看几个位), FF, SLRD的波形。关注上升/下降时间、过冲/下冲、毛刺。
- 检查板卡电源稳定性。
总结:
您遇到的问题几乎可以肯定是FX2LP的FF满标志更新延迟导致FPGA在FIFO实际已满时多读了一个数据,破坏了后续所有读写的同步性。首要解决方案是修改FPGA端的状态机逻辑,确保在FF=1时不进行任何读操作。务必使用逻辑分析仪捕获实际通信波形,这是定位此类同步通信问题的黄金标准。仔细检查和调整FX2LP的FIFO标志配置(极性、映射)也能帮助规避问题。
希望这些分析能帮助您快速定位和解决问题!如果方便,也希望能分享排查结果!
|
|
|
2025-6-9 18:10:00
评论
举报
|
|
|
|