FPGA网口远程升级:适用于A7及PL端部分,支持回退多重启动

FPGA网口远程升级:适用于A7及PL端部分,支持回退多重启动 FPGA 网口远程升级适用与A7,或只有PL端部分。 网口采用百兆udp需搭配上位机使用。 可支持升级失败后的回退多重启动。 使用IP且只有fifo和ram。蹲在实验室调了三天三夜FPGA远程升级终于搞定了这个用网口升级镜像的方案。传统JTAG烧录太麻烦尤其设备部署在野外的时候总不能每次都派人去现场插下载器吧今天就跟大伙聊聊这个纯PL实现的网口远程升级方案。先上核心架构图假装这里有手绘示意图。整个系统就靠三个模块撑场面网络接口模块负责收UDP包数据解析模块拆包校验启动控制模块玩转双镜像切换。重点在于全程只用FIFO和Block RAM绝对不碰任何高端IP核。网络接口模块的核心是千兆变百兆的骚操作。直接上代码片段// 百兆速率适配 always (posedge clk_25m) begin if(eth_rx_valid) begin byte_cnt (byte_cnt 3) ? 0 : byte_cnt 1; fifo_wr_en (byte_cnt 3); end end这坨代码把千兆MAC的125MHz时钟域转到25MHz用计数器实现四选一采样。注意看fifowren的生成逻辑——每四个时钟周期才写一次FIFO完美适配百兆速率。调试时候在这卡了半天后来用ChipScope抓信号发现时钟域没同步加了级寄存器才稳定。FPGA 网口远程升级适用与A7,或只有PL端部分。 网口采用百兆udp需搭配上位机使用。 可支持升级失败后的回退多重启动。 使用IP且只有fifo和ram。上位机发的数据包得带CRC32校验FPGA端校验模块长这样always (posedge clk) begin if(rst) begin crc 32hFFFFFFFF; end else if(data_valid) begin crc next_crc32(crc, data_byte); end end function [31:0] next_crc32; input [31:0] crc; input [7:0] data; begin next_crc32 {crc[23:0], 8h00} ^ crc_table[(crc[31:24] ^ data)]; end endfunction查表法算CRC比直接算快十倍实测在125MHz下完全无压力。记得预先生成好crc_table常量数组这玩意儿用Python脚本生成最方便。镜像切换才是重头戏。我们在Block RAM里存了两份启动配置状态机切起来像跳舞case(current_state) BOOT_MAIN: if(update_valid) begin boot_sel 1b1; reboot_counter 24hFFFFFF; end BOOT_BACKUP: if(reboot_counter 0) begin boot_sel 1b0; // 超时回退 end endcase这里有个坑——切换启动镜像后必须延迟一段时间再检测是否成功。我们的方案是用计数器实现30秒超时期间如果FPGA没有收到心跳包就自动切回旧镜像。实测这个机制救过好几次砖特别是网络闪断导致镜像传输不完整的情况。最后说说上位机配合要点。数据包要拆成1472字节的UDP包避开IP分片每个包带序列号和结束标志。推荐用Python的socket库实现注意设置超时时间和重传机制。曾经因为没处理丢包导致升级到一半卡死后来加了ACK机制才解决。这套方案在A7-35T上实测资源占用不到15%速度稳定在8MB/s左右。当然还有优化空间比如用DDR缓存镜像或者上TCP协议不过对于大部分应用场景来说这个丐版方案已经够用了。