ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FPGA从SelectMAP配置接口详解:时序分析、Verilog实现与调试指南

FPGA从SelectMAP配置接口详解:时序分析、Verilog实现与调试指南 1. 从一次批量烧写事故说起搞FPGA开发这么多年JTAG下载应该是大家最熟悉的配置方式了。但如果你做的是通信板卡、视频处理板这类需要在线升级逻辑的设备迟早会遇到一个场景上百块板卡通过背板互联主控板需要远程更新各业务板上的FPGA程序。通过JTAG菊花链一根根串下去速度只能到二三十Mbps遇到大的工程镜像光烧一块板就要几分钟批量场景下简直让人崩溃。选型阶段我比较过几种主流的从配置模式最终敲定了slave SelectMAP方案。今天这篇就围绕这个主题把从原理分析到逻辑实现再到调试踩坑的完整过程捋一遍给同样在折腾FPGA配置接口的朋友一些参考。如果你正准备在自己的板子上引入SelectMAP或者只是想把配置这块的知识体系补完整这篇文章应该对你有用。需要提前说明的是本文的核心是基于Xilinx 7系列FPGA比如Artix-7、Kintex-7的从SelectMAP接口展开的。其他厂商的器件配置时序大同小异具体细节要以对应数据手册为准。2. 为什么偏偏选slave SelectMAP2.1 几种配置方式的对比FPGA的配置方式本质上解决的是“程序从哪来、怎么进FPGA”的问题。主流的几种方案各有优劣配置方式时钟来源典型速率接口资源消耗适用场景JTAGTCLK约30Mbps4根信号线调试、小批量烧写SPI x1/x4FPGA内部产生最高约100Mbps4~6根信号线单板自启动BPI并行FPGA内部产生最高约200Mbps约28根信号线大容量并行加载slave SelectMAP x8/x16外部输入最高约400Mbpsx16数据线控制线多板同步升级、高速动态配置slave SelectMAP x32外部输入最高约800Mbps数据线控制线高性能动态重构系统SelectMAP最大的优势在于数据从外部主动灌入FPGA只负责被动接收。这意味着外部控制器MCU、CPU、CPLD、甚至另一片FPGA可以精确控制配置的发起时机和数据节奏非常适合做系统级的统一管理和远程升级。相比之下SPI和BPI模式下FPGA自己是主控外部存储只能被动等待FPGA来读灵活性就差了不少。2.2 SelectMAP适合什么样的项目从我实际接触的项目来看SelectMAP典型用在下面几类场景多板卡集中管理系统。比如一个机箱里插了8块相同或不同的FPGA板卡背板上有一块主控板。主控板可以通过SelectMAP接口一块一块地给业务板下发配置文件。这在通信基站、雷达信号处理、视频拼接墙等产品里很常见。需要快速反复重构的系统。部分可重配置计算平台会根据运行状态切换不同的加速任务配置过程不能被慢速的存储配置拖后腿。外部处理器直接从内存中读取配置镜像通过SelectMAP灌进去可以实现毫秒级的重构。主控逻辑不希望占用额外存储芯片。有些小系统里存储资源紧张或者想省掉配置芯片的成本利用系统已有的主控CPU直接完成配置加载SelectMAP是比JTAG高效得多的选择。2.3 核心技术的价值拆解站在技术学习的角度SelectMAP配置逻辑麻雀虽小五脏俱全它会逼你把下面几件事搞清楚配置数据是按字节还是按字传输的字节顺序是什么配置过程中CS_B、RDWR_B、BUSY这几个信号配合的精确时序是什么配置失败后如何复位重试多片FPGA的SelectMAP接口如何共享数据总线而不打架这些问题搞明白之后你再去接触PCIE、DDR、SerDes这种高速接口会发现在“时序理解”这件事上是相通的。配置接口本身就是FPGA入门的进阶训练场。3. SelectMAP接口信号与时序基础3.1 引脚逐个说清楚SelectMAP的引脚不多但每个引脚的作用和时序关系都是硬约束。先把家底盘清楚引脚名称方向功能说明CS_B输入片选信号低有效。拉低表示选中该FPGA进行配置RDWR_B输入读写控制。低电平表示写配置数据高电平表示回读BUSY输出忙信号。为高时表示FPGA当前忙外部不能写入数据D[31:0]或D[15:0]/D[7:0]双向配置数据总线位宽由配置模式决定CCLK输入时钟在从模式下由外部提供PROG_B输入配置复位信号低有效拉低后FPGA清空配置存储区INIT_B双向初始化指示兼错误指示。配置前拉低表示正在清空存储区配置过程中变高表示准备好接收数据若配置出错会被拉低DONE输出配置完成信号上拉电阻配合下为高表示配置成功这里要特别提一下DONE引脚。虽然它是输出但外部最好给它接一个上拉电阻通常4.7kΩ。不接的话如果FPGA内部没有启用DONE的上拉配置完成后DONE可能无法可靠地拉到高电平导致外部控制器误判配置失败。3.2 手工描述配置时序的过程SelectMAP的时序如果光看数据手册里的时序图第一次接触会有点绕。我用文字把整个流程拆开讲第一步复位阶段。外部控制器把PROG_B拉低至少几百纳秒规格书上要求最小脉冲宽度7系列要求大于500ns然后释放。FPGA会进行内部配置存储区的初始化此时INIT_B信号被FPGA拉低一段时间。这段时间内外部控制器不能发送配置数据。第二步等待初始化完成。观察INIT_B信号当它从低变高时表示FPGA已经准备好接收配置数据。这个沿非常重要配置数据必须在INIT_B拉高之后才能开始发送。第三步数据装载阶段。外部控制器把CS_B拉低、RDWR_B拉低然后在CCLK的上升沿逐个写入配置数据。这里有一个关键机制如果BUSY信号为高那么外部控制器必须暂停写入直到BUSY拉低才能继续。BUSY本质上就是FPGA内部配置逻辑的流控信号相当于告诉对方“你慢点我处理不过来”。第四步配置完成。配置数据全部写入后FPGA会进入启动序列DONE信号拉高配置完成。此时CCLK还需要再给几个时钟完成启动序列的收尾工作。各个阶段之间环环相扣任何一个环节时序不满足要求都会引发配置失败而且失败的表现形式很隐蔽——可能是DONE永远起不来也可能是DONE起来了但功能不对。3.3 字节顺序和位宽这个坑SelectMAP支持8位、16位、32位数据位宽。位宽的选择由配置模式引脚M[2:0]的电平决定。7系列FPGA中slave SelectMAP x8对应M[2:0]110x16对应001具体以器件手册为准不同封装下引脚编号有差异。位宽确定之后字节顺序也是配置逻辑初始化的关键。以32位模式为例配置镜像文件是字节流那么在数据总线上到底是“低字节在前”还是“高字节在前”取决于你使用的生成工具配置。ISE/Vivado中生成配置文件的BITGEN选项里有一个byte-swapping的设置默认情况下是关闭的也就是按照正常的字节顺序输出。实操中我遇到过一个很典型的问题外部控制器通过SelectMAP x32加载BIT文件结果每次配置到约90%的时候就报错INIT_B被拉低。排查了一整天最后发现是字节序反了。配置文件里的4字节数据组被颠倒装入数据总线导致FPGA解析数据时前后矛盾。所以这里先立下一个规矩在写配置逻辑之前先确认你的BIT文件生成设置和你的总线接入方式是否匹配。4. 配置逻辑的完整Verilog实现4.1 模块划分配置逻辑本质上是把“FPGA配置协议”翻译成“外部控制器接口”的桥接逻辑。我把它拆成三个子模块selectmap_top顶层模块负责时钟域处理、对外接口管理selectmap_wr配置状态机完成配置数据的时序控制selectmap_busy_syncBUSY信号的跨时钟域同步处理外部控制器通过一个简单的异步FIFO接口把配置数据交给selectmap_topselectmap_top把数据变成符合SelectMAP时序要求的波形。4.2 关键模块代码这里给出一份经过上板验证的32位slave SelectMAP配置逻辑核心代码module selectmap_top ( input clk_50m, // 外部时钟 50MHz供 SelectMAP 时钟使用 // 外部控制器接口 input wr_en, // 写请求信号 input [31:0] wr_data, // 待配置数据 output wr_ready, // 可接收新数据指示 // SelectMAP 物理接口 input map_busy, input map_init_b, output reg map_cs_b, output reg map_rdwr_b, output reg map_cclk, output reg [31:0] map_data, input map_done, // 控制信号 input start_config, // 启动配置使能 output config_error, // 配置错误指示 output config_done // 配置完成指示 ); // 省略FIFO实例化这里直接处理写请求握手 reg fifo_empty; wire [31:0] fifo_data; wire fifo_rd_en; // 状态定义 localparam ST_IDLE 4d0; localparam ST_RESET 4d1; localparam ST_WAIT_INIT 4d2; localparam ST_WRITE 4d3; localparam ST_ERROR 4d4; localparam ST_DONE 4d5; reg [3:0] state; reg [15:0] reset_cnt; reg [15:0] init_wait_cnt; // 配置状态机主逻辑 always (posedge clk_50m or negedge rst_n) begin if (!rst_n) begin state ST_IDLE; map_cs_b 1b1; map_rdwr_b 1b1; map_cclk 1b0; map_data 32h0; end else begin case (state) ST_IDLE: begin if (start_config) begin map_cs_b 1b1; // 先确保不选中 map_rdwr_b 1b1; reset_cnt 16d1000; // 拉低 PROG_B 维持时间 state ST_RESET; end end ST_RESET: begin // 注意PROG_B 需要在外部连到 FPGA 对应引脚 // 这里留给顶层模块做引脚约束本模块只给控制逻辑 if (reset_cnt ! 0) begin reset_cnt reset_cnt - 1b1; prog_b_reg 1b0; // 保持低 end else begin prog_b_reg 1b1; // 释放复位 init_wait_cnt 16hFFFF; state ST_WAIT_INIT; end end ST_WAIT_INIT: begin // 等待 INIT_B 拉高 if (map_init_b) begin map_cs_b 1b0; // 选中 FPGA map_rdwr_b 1b0; // 写模式 state ST_WRITE; end else if (init_wait_cnt 0) begin state ST_ERROR; // 超时INIT_B 未拉高 end else begin init_wait_cnt init_wait_cnt - 1b1; end end ST_WRITE: begin if (fifo_empty) begin // FIFO 为空等待新数据 end else begin if (!map_busy) begin // 仅在 BUSY 为低时写入数据 map_data fifo_data; map_cclk ~map_cclk; // 产生时钟沿 fifo_rd_en 1b1; end end if (map_done) begin // 配置完成进入结束状态 map_cs_b 1b1; state ST_DONE; end end // ... 其他状态略 endcase end end endmodule4.3 代码背后的几个设计考量写上面这段代码时有几个细节需要单独解释为什么用CCLK翻转而不是直接用50MHz晶振因为SelectMAP是一个同步接口。CCLK是数据采样的基准时钟数据是在CCLK上升沿被FPGA锁存的。我们在代码里通过翻转信号来产生CCLK可以让数据和时钟边沿的关系完全由我们的逻辑控制避免使用PLL锁相环带来的相位不确定性。BUSY信号为什么必须在采样时钟域内判断如果BUSY信号和CCLK不是同一个时钟域就会出现亚稳态问题。所以代码里的map_busy实际是经过两级寄存器同步后的信号。这里有个细节同步后的BUSY信号会滞后实际的BUSY若干个时钟周期所以写入时要注意留出裕量不能看到BUSY为低就立即写入否则有可能在BUSY刚拉高的边界处犯错。为什么用FIFO而不是直接寄存器缓冲配置数据是持续的字节流外部控制器比如ARM写入数据的速度不可能是严格恒定的。用FIFO解耦外部控制器只需要保证FIFO不空配置逻辑就能持续输出数据不会被突发的总线阻塞打断。4.4 跨时钟域处理的正确姿势BUSY信号从FPGA的配置逻辑返回它的实际时钟域是CCLK域。如果我们的逻辑用的是50MHz独立时钟那么BUSY必须先同步到本地时钟域再使用。reg busy_sync_ff1, busy_sync_ff2; always (posedge clk_50m or negedge rst_n) begin if (!rst_n) begin busy_sync_ff1 1b0; busy_sync_ff2 1b0; end else begin busy_sync_ff1 map_busy; busy_sync_ff2 busy_sync_ff1; end end两级同步之后busy_sync_ff2可以安全地用于状态机判断。实际使用中还可以再加一级进一步提高可靠性代价是多两个时钟周期的判断延迟。5. 硬件连接与关键设计细节5.1 引脚分配与约束思路SelectMAP接口虽然看起来只是几根线但PCB布局和引脚分配上仍有很多门道D[31:0] 数据线建议连续排列在一片Bank中不要跨Bank分散放置。跨Bank会导致信号完整性问题而且时序约束处理起来也麻烦。高速切换时数据线之间的相对延迟如果不一致会直接踩到配置接口的建立保持时间。CCLK尽量单独走线保持短而直不要和DDR、SerDes这类高速信号并行走线。配置时钟本身不是特别高但是作为同步信号它的干净程度直接影响配置成功率。INIT_B这个信号是双向的用在配置逻辑中建议给它加上拉电阻4.7kΩ或10kΩ。开漏输出需要上拉才能可靠实现高电平。PROG_B也可以依据情况接上拉防止系统启动瞬间产生毛刺导致FPGA误复位。5.2 电气特性的考虑SelectMAP总线上如果挂了多片FPGA数据线会成为双向总线。这时候就要考虑多片FPGA共享数据总线配置完一片之后这片的D[31:0]如果持续输出会不会干扰下一片的配置答案是会的。所以多片设计时每片FPGA的D[31:0]都必须通过外部三态缓冲器隔离或者依赖FPGA内部的IO状态控制。Xilinx FPGA在配置完成且未启用用户逻辑时SelectMAP引脚会自动变成高阻态但为了保险起见很多成熟设计会在SelectMAP数据线上串联33Ω或47Ω的电阻做隔离缓冲也可以直接外挂74LVC245这类三态收发器。5.3 时钟输入的关键限制SelectMAP模式下CCLK是外部输入的。7系列FPGA对这个时钟的频率有一个上限要求具体数值在数据手册中可以查到。x8模式大约在100MHz150MHz量级x32模式典型上限几百MHz。但实际做设计时我建议先把频率放低一点比如一开始用25MHz或50MHz把逻辑调通再逐渐提高频率。为什么因为配置频率一旦提高数据线之间的等长问题、CCLK到数据线的相对时序裕量都会暴露出来。用低速把逻辑跑通至少能先把协议层面的问题排除掉高速跑不通时再去查硬件。6. 配置过程的完整时序演示6.1 用文字逐步还原一次成功配置为了让大家有一个直观的印象我把一次成功的SelectMAP配置完整走一遍相当于用业务流程的方式描述时序假设系统启动后一个ARM通过GPIO模拟SelectMAP时序或者通过FPGA桥接逻辑向Xilinx FPGA加载配置。ARM先将PROG_B拉低保持约10us确保FPGA内部完成复位。释放PROG_BFPGA开始清空自己的配置存储区此时INIT_B引脚被FPGA驱动为低电平。大约若干毫秒后INIT_B自动变高说明FPGA已经准备好接收配置数据。ARM检测到INIT_B为高后拉低CS_B置RDWR_B为低开始往D[31:0]数据线上逐个写入配置数据。每写一组32位数据前ARM检查BUSY是否为空闲。BUSY为高时等待为低时写入数据并送出一个CCLK上升沿。判断配置是否完成的依据是DONE信号。DONE变高说明配置成功此时还需要给FPGA一段启动序列时间可以继续送几个CCLK然后拉高CS_B结束本次配置。6.2 配置失败时的表现配置失败在示波器上最常见的迹象是配置数据还没发完INIT_B突然被拉低。这表明FPGA在解析配置数据的过程中发现了致命错误——位流格式不对、数据校验失败、或者是配置数据被损坏。另一个常见的失败表现是DONE一直处于低电平配置数据发完了FPGA也没有给出错误指示但就是起不来。这种情况大概率是配置文件本身的问题BIT文件和FPGA型号不匹配。6.3 用ILA调试配置逻辑调试SelectMAP配置逻辑时ILA集成逻辑分析仪是排障神器。把ILA挂在配置状态机上可以抓到每一个状态的跳转、BUSY信号的变化、以及写入数据的进度。这里有一个套实用的做法把配置进度计数器和状态编码挂到ILA上加上DONE、INIT_B、BUSY、CS_B这几个关键信号采满一帧数据后回放基本能定位90%以上的问题。有一种特殊情况要提醒ILA本身也需要FPGA跑起来才能用而配置阶段FPGA还没加载用户逻辑ILA没法直接在配置阶段工作。怎么办实践中通常有两种办法在外部控制器ARM/CPLD上加逻辑分析仪功能通过打印日志来追踪配置状态先把配置逻辑连同ILA一起打包成一个完整的BIT文件比如通过JTAG下载这个测试版本让ILA在配置完成后仍然监控正在工作的配置逻辑信号然后外部通过SelectMAP触发一次重新配置观察时序第二种方法我实际用过触发条件设为start_config信号的上升沿这样就能抓拍到完整的配置过程时序。7. 常见问题与排查技巧实录这里把我在实际调试中遇到过的典型问题整理成一个速查表每个问题都附上排查思路和最终解决办法问题现象可能原因排查方法与解决方案INIT_B始终为低配置无法开始PROG_B脉冲宽度不够FPGA初始化未完成检查PROG_B低电平时间适当延长到10us以上INIT_B短暂拉高后又拉低配置数据错误率过高检查数据总线的接线是否正确确认BIT文件类型是否为SelectMAP格式配置数据写入不到1/4INIT_B拉低数据位宽配置错误检查M[2:0]引脚电平确认x8/x16/x32配置与逻辑一致数据发送完毕但DONE一直不起配置文件使用了压缩格式FPGA不支持重新生成BIT文件取消压缩选项写入时BUSY频繁拉高配置时钟频率过高降低CCLK频率检查时序是否满足要求多片FPGA配置时互相干扰数据总线没有隔离增加三态缓冲器或串联电阻隔离配置成功但用户逻辑运行异常配置完成后启动序列被过早打断在DONE变高后再提供至少16个CCLK确保启动序列完成示波器上数据波形脏、毛刺多信号完整性差检查走线长度匹配数据线上增加串阻7.1 问题排查的通用方法论上面这些问题是点状的实际操作中遇到配置失败时按照什么顺序排查才最有效率我这里总结一个自己的排查顺序供参考。第一步先只测硬件不测逻辑。用示波器测量PROG_B拉低以后INIT_B是否出现正常的低脉冲然后变高。如果INIT_B根本没有反应多半是PROG_B没真正送到FPGA引脚或者FPGA供电有问题。第二步查CS_B和RDWR_B的电平。在INIT_B拉高之后确认CS_B能正常拉低RDWR_B能正常拉低且两者之间没有毛刺。如果这两个信号在示波器上看起来有毛刺需要在逻辑里加同步或滤波。第三步抓数据总线波形。在CCLK的上升沿处检查数据总线是否稳定。如果数据在CCLK附近跳变说明建立保持时间不满足需要调整数据输出时机。第四步跟踪BUSY。如果BUSY一直为高说明FPGA内部配置逻辑被卡住了。这时多半是芯片进入了异常状态把PROG_B重新拉低再试一次。7.2 一个真实项目的调试过程这里分享一个印象深刻的实测案例。当时要做的是基于Xilinx Artix-7的采集板主控是Zynq通过EMIO模拟SelectMAP时序给Artix-7配置。第一次上电Zynq通过GPIO发送配置数据结果发现配置进度走到一半INIT_B被拉低配置失败。刚开始以为时序不对把CCLK降到了10MHz依旧失败。又以为是数据线接反了仔细检查原理图和PCB发现D[31:24]在PCB上走线时被整体翻转了。也就是说D31接到了FPGA的D24引脚D30接到了D25引脚。硬件上这样接软件上完全看不出来只有配置才会暴露出问题。把PCB改版后问题解决。这个案例说明配置失败时首先检查的不是代码而是硬件对应关系。看似不起眼的问题往往比逻辑Bug更难定位。8. 进阶多片FPGA并联配置的扩展思路8.1 多片并联的两种拓扑如果你的系统里有多片FPGA都要用SelectMAP配置拓扑上通常有两种做法独立SelectMAP每片FPGA独占一组SelectMAP接口。优点是灵活任意一片可以独立配置缺点是占用主控大量IO资源不适合FPGA数量多的系统。共享总线SelectMAP多片FPGA共享D[31:0]、CCLK、RDWR_B但是CS_B独立控制。同一时刻只选中一片配置完一片再选下一片。共享总线方案是我比较推荐的它在IO资源和灵活性之间取得了很好的平衡。实现上只需要在状态机里增加一个CS_B控制寄存器组每个FPGA对应一个CS_B。配置第一片时只有它的CS_B被拉低其他片的CS_B保持高电平。8.2 共享总线时的注意事项共享总线方案有两个务必注意的点一是数据总线的驱动冲突。配置完成的那片FPGA其SelectMAP数据引脚在用户逻辑加载后可能变成用户自定义功能如果碰巧驱动为低电平会直接影响下一片的配置。所以正规设计里每片FPGA的SelectMAP数据线在硬件上就通过三态缓冲器隔离或者在FPGA用户逻辑中把相关引脚设为高阻输入。二是DONE信号的汇合。如果所有FPGA的DONE信号通过线与方式连在一起主控可以通过DONE整体状态判断整个系统是否配置完成。但是如果其中一片配置慢其他片配置快DONE出现的时间不同线与判据就不准确。所以我倾向于用独立的DONE输入主控分别判断。8.3 如何做动态重配置SelectMAP最有魅力的地方是它可以实现动态重配置。在FPGA运行过程中外部控制器可以拉低PROG_B重新初始化FPGA然后重新灌入新的配置镜像。这里特别说明一个重要区别SelectMAP动态重配置和Xilinx的PCAP/PR部分重配置不是一回事。SelectMAP的重新配置是整个FPGA整体重新加载配置过程中用户逻辑会中断。要做部分重配置需要用到Xilinx的PR功能和专用的ICAP接口。如果只是整体升级SelectMAP配合“先擦后写”的思路就足够了。在拉低PROG_B之前先确认业务上已经停止使用FPGA功能避免热插拔式的重新配置导致系统出现不可预期的故障。9. 配置速率优化与性能权衡9.1 理论带宽和实际带宽的差距很多人在评估SelectMAP性能时直接用位宽乘频率来算理论带宽。比如32位接口、100MHz理论带宽就是400MB/s。但在真实系统里几乎不可能达到这个数字。主要原因有三个一是BUSY等待会周期性插入停顿二是外部控制器读取配置数据的效率不可能100%三是配置镜像本身除了有效数据还有同步字、ID码校验字等额外开销。实测下来50MHz时钟下32位SelectMAP实际有效数据吞吐大约在150MB/s180MB/s之间大约是理论值的75%90%。如果还想提高优化的重点方向通常是减少BUSY等待。BUSY拉高一方面说明FPGA的配置接口处理不过来另一方面也可能说明外部写入的时序不够紧凑。建议先把数据输出的逻辑优化成“连续发送、只在BUSY高时暂停”这样可以让FPGA处于持续接收状态。9.2 合理规划配置数据存储配置数据流是一个持续性的过程中间不能出现长时间的断层否则FPGA配置逻辑可能因为超时进入异常状态。所以主控侧的数据源要保证稳定供给。有两种典型的存储方案外部Flash存储配置镜像放在SPI Flash或并行Nor Flash中。配置开始后主控读取Flash数据并发往SelectMAP接口。这种方案的瓶颈在Flash读取速度一般SPI Flash x4模式读速在50MB/s左右会成为瓶颈。内存镜像存储如果主控是ARM或Zynq可以将配置镜像提前搬入DDR然后从DDR读取数据发往SelectMAP。这样吞吐量远高于Flash方案适合大批量配置场景。9.3 多级缓冲策略要想让配置过程高效又稳定一个FIFO往往不够。我通常会在主控侧做二级缓冲第一级是一个大容量的DDR缓冲存放整包配置镜像第二级是一个小容量的同步FIFO比如4KB或8KB负责DDR和SelectMAP接口之间的数据搬运。这样做的意义在于即使DDR读取出现短暂的延迟抖动比如被操作系统调度或DMA占用二级FIFO也能兜住这段真空期保证SelectMAP接口的数据持续供给不会因为FIFO空洞导致配置中断。10. 最后分享一点实战心得把slave SelectMAP配置逻辑讲到这里最后聊聊我个人在实战中最深的几点体会。第一配置接口从来不是孤立存在的。很多项目里SelectMAP只是整个系统的一小环但它和供电、时钟树、复位策略、启动时序都紧密关联。写配置逻辑之前先花半天时间把上电时序图理清楚比写完代码再调要省太多时间。第二时序约束早加早安心。SelectMAP的数据线虽然看起来“只是一堆普通IO”但在Vivado里还是建议显式创建时序约束把CCLK的周期约束、数据线的输入延迟约束加进去。否则综合工具默认优化可能把配置接口当成普通IO处理时序优化方向就偏了。第三调试配置问题时的耐心是最大的成本。这类问题的隐蔽性高有时是硬件对应关系错了有时是软件字节序反了还有时是配置文件生成选项的问题。我在调试配置类问题时习惯先把数据手册中相关的波形图打印出来放在手边对照着排除比凭感觉修改快得多。如果你正准备在自己的板子上引入SelectMAP按照这篇的思路把时序理清、把状态机写扎实大概率可以少走不少弯路。配置逻辑本身并不玄但它是FPGA工程化能力的一块试金石——能把配置逻辑跑得又快又稳的工程师做其他高速接口时心里通常也有底。
返回列表