我今年准备高职组集成电路应用开发国赛,FPGA部分要用Verilog实现SPI Flash的读写控制,但仿真时读写时序总对不上,数据读出来全是0。我用的是安路FPGA开发板,SPI时钟频率设了25MHz,Flash型号是W25Q64。有没有大佬分享下SPI Flash驱动设计的常见坑?比如命令发送后等待tSLHS时间、读数据时的时钟边沿对齐这些细节,国赛评委会不会深挖时序约束?
2026年,高职组集成电路应用开发国赛FPGA备赛,Verilog实现SPI Flash读写时时序总出错,怎么排查?
提问
回答 3

先别急着调时序约束,国赛评委大概率不会深挖SDC,他们更关心你代码逻辑对不对。你读出来全是0,最常见的原因是命令发送后没有等够Flash内部处理时间——W25Q64读数据之前,发完读命令和地址,得等大概几个us。仿真模型如果没模拟这个延迟,你直接采数据当然全是0。另外检查一下SPI模式,W25Q64默认是Mode 0(CPOL=0, CPHA=0),数据在时钟上升沿采样,下降沿输出。你25MHz时钟周期40ns,建议用状态机加计数器做等待,别用延迟赋值。先对着数据手册把读ID命令(0x9F)调通,能读到厂商ID了再搞读写。你仿真用的是官方的W25Q64 Verilog模型吗?还是自己写的?

读出来全是0,我猜你仿真时只给了时钟和命令,没加片选信号的释放和拉高动作。W25Q64在每次操作结束后,片选必须拉高至少tSLHS(一般50ns)才能进行下一次操作,否则Flash内部状态机卡住,返回数据全是0。另一个常见坑是:读数据时,FPGA必须在时钟的下降沿输出地址和命令,上升沿采样数据——但很多初学者搞反了边沿,导致采到的是上一个周期的无效值。你可以用三段式状态机来写:IDLE发命令、WAIT等延时、READ采数据。每个状态里单独计数,别用for循环。国赛评委不会专门考时序约束的细节,但如果你能把仿真波形里标出tSLHS、tCLQV这些参数对应到数据手册,会加分。另外25MHz对安路FPGA来说完全够用,不用开IO延时约束。你仿真用的工具是Modelsim还是Vivado?如果是Modelsim,可以试试在do文件里手动加force来模拟Flash的异步响应。

这个问题其实反映了高职组备赛里一个很典型的断层:大家把SPI时序想象得太简单,以为照着数据手册画个波形就能跑通,但实际仿真模型和真实芯片之间有不少隐性条件。你读出来全是0,最大可能是仿真模型没有正确模拟Flash的读操作流程——W25Q64的读数据命令(0x03)在发送完24位地址后,Flash需要至少tCLQV时间(时钟低电平到数据输出有效,典型值7ns)才能输出第一个字节,而你的仿真模型可能在这个窗口内直接输出了高阻或0。解决办法:第一步,去Winbond官网下载官方的Verilog仿真模型(不是自己写的简化版),这个模型会精确模拟tSLHS、tCLQV等参数。第二步,在Modelsim里用这个模型跑仿真,对比数据手册里的时序图,重点检查片选拉高后的等待时间是否足够。第三步,如果官方模型也读不到数据,就把SPI时钟降到1MHz试一下——很多高职组的开发板布线不规范,25MHz在杜邦线上会有信号反射,导致时钟沿抖动。另外关于国赛评委的考察点:去年高职组国赛确实有队伍因为SPI时序不稳被扣分,但评委更多是看功能完整性(能否正确写入并回读一段数据)和代码可读性(状态机清晰、参数化定义延时)。时序约束只在综合后STA出现大量违例时才被追问,你25MHz基本不会触发。建议你把精力放在写一个带超时保护的状态机上:比如读操作等待超过100us没返回数据就报错复位,这样即使Flash初始化失败也能自动重试,比死等某个固定延时健壮很多。最后问一句:你仿真时有没有把Flash的WP#和HOLD#引脚拉高?这两个脚在W25Q64里是低电平有效,悬空的话仿真模型会默认保持复位状态,数据读不出来很正常。
发表回答
登录后可在本页底部提交回答
