单JTAG链多FPGA系统JIC文件生成与烧写全流程详解 1. 项目背景与核心挑战在FPGA项目开发中尤其是涉及多板卡、多核心的复杂系统里我们经常会遇到一种硬件拓扑一条JTAG链上串联了多个FPGA器件。这种设计简化了PCB布线也方便了调试。之前我们讨论过在这种结构下如何使用Virtual JTAG进行在线调试但当调试完成需要将最终的配置文件固化到非易失性的配置芯片如Altera/Intel的EPCS系列时问题就变得不那么直观了。直接使用ASActive Serial模式烧写POF文件是一种方法但这要求硬件上必须引出AS接口。对于追求精简设计、或量产时希望减少连接器和线缆的场合我们更希望通过JTAG接口间接地将配置数据烧写到EPCS芯片中。这就引出了JICJTAG Indirect Configuration文件的应用。然而单JTAG链多FPGA的结构让JIC文件的生成与下载过程与单器件场景有显著不同稍有不慎就会遇到“Device chain mismatch”等令人困惑的错误。本文将基于一次实际的量产前固件固化经历详细拆解其中的原理、步骤和那些容易踩坑的细节。2. 核心原理为什么单链多FPGA的JIC下载更复杂要理解操作步骤必须先搞清楚背后的硬件与软件逻辑。这不仅仅是“多加载几个文件”那么简单。2.1 硬件链路的约束在单JTAG链多FPGA的硬件设计中所有FPGA的JTAG接口TDI, TDO, TCK, TMS是串联的。更重要的是为了实现同步配置成功所有FPGA的CONFIG_DONE信号通常会在板级连接在一起并通过上拉电阻拉到高电平。这意味着只有当链路上的每一个FPGA都成功将其SRAM配置完成并释放其CONFIG_DONE引脚变为高阻态由上拉电阻拉高后整个系统的CONFIG_DONE网络才会变为高电平系统才认为配置完成。如果链上任何一个器件配置失败或未配置其CONFIG_DONE引脚会持续拉低导致整个网络被钳位在低电平系统启动失败。2.2 Quartus Programmer的工作逻辑Quartus Programmer软件在通过JTAG配置FPGA时会先扫描整条链识别出链上的器件类型和数量。当你提供一个配置文件如SOF或JIC时软件会检查这个文件所描述的器件链信息是否与物理扫描到的链信息完全匹配。在单器件情况下这很简单。但在多器件情况下如果你只提供一个针对某个器件的JIC文件Programmer会发现物理链上有N个器件而你的文件只描述了1个器件Flash Loader这就会立刻触发链不匹配的错误。2.3 Flash Loader的角色“通过JTAG烧写EPCS”这个功能本身并不是JTAG接口的原生功能。它是通过在FPGA的SRAM中临时加载一个特殊的、微小的设计——Flash Loader——来实现的。这个Flash Loader设计包含了与EPCS芯片通信的SPI控制器逻辑以及控制流程。Programmer通过JTAG与这个Flash Loader交互指挥它去擦除、编程EPCS芯片。因此整个流程分为两步配置Flash Loader将Flash Loader的SOF文件通过JTAG下载到目标FPGA的SRAM中。间接烧写FlashProgrammer与运行中的Flash Loader通信将JIC文件中的数据通过该FPGA的IO口传输给EPCS芯片。在单链多器件结构中我们不仅要让作为“烧写员”的FPGA运行Flash Loader还必须让链上其他所有FPGA也进入一个“已配置”的正常状态以满足CONFIG_DONE的硬件约束。这就是为什么我们需要为所有器件准备临时配置文件。3. 多器件JIC文件的生成步骤详解生成JIC文件是在Quartus的“File - Convert Programming Files”工具中完成的。多器件场景下的关键区别在于SOF Data部分的设置。3.1 转换工具配置流程打开转换工具在Quartus II或Prime中打开你的FPGA工程导航至File - Convert Programming Files。选择输出文件类型在Output programming file区块Programming file type: 选择JTAG Indirect Configuration File (.jic)。Configuration device: 根据你板载的EPCS芯片具体型号选择例如EPCS64。Mode: 这是一个关键选项。它指定了FPGA从EPCS芯片加载配置数据时的接口模式。Active Serial x1标准模式使用单一数据线DATA0串行读取。兼容性最好是最常用的选择。Active Serial x4快速模式使用四根数据线DATA0-DATA3并行读取。可以显著缩短FPGA上电配置时间但需要确保你的FPGA支持该模式且PCB布线将EPCS的这四根数据线都正确连接。如果布线不支持或不确定请选择x1模式。本文示例以x1模式进行。添加Flash Loader在Input files to convert区域的Flash Loader页签下点击Add Device。在弹出的器件列表中选择你那条JTAG链上打算充当Flash Loader角色的那个FPGA的具体型号。例如如果你的链上是两个Cyclone IV EP4CE15这里就添加一个EP4CE15。这一步是告诉转换工具将由哪个器件来执行烧写动作。添加SOF数据核心步骤切换到SOF Data页签。这里是操作的关键点。点击Add File首先添加Flash Loader器件的SOF文件。注意这个SOF文件不是你最终的应用设计而是专门为Flash Loader功能生成的。你需要在你的工程中为这个FPGA创建一个Flash Loader设计并编译。添加后不要停止。继续点击Add File按照JTAG链上的物理顺序依次添加链上其他所有FPGA器件的应用SOF文件。例如链上是FPGA0Flash LoaderFPGA1FPGA2那么你就需要添加三个SOF文件flash_loader.sof,fpga1_app.sof,fpga2_app.sof。顺序至关重要它必须与硬件JTAG链的扫描顺序一致。通常离JTAG接头TDI最近的器件是链中的第一个。生成文件指定输出JIC文件的路径和名称点击Generate。工具会将你添加的所有SOF文件数据按照链的顺序打包并加上引导头生成一个最终的.jic文件。这个文件包含了配置整条链所需的所有数据以及将其写入EPCS的指令信息。3.2 配置模式选择的注意事项关于Mode选择Active Serial x4这里需要深入说明一下。这个模式影响的是未来FPGA从这片EPCS芯片上电加载时的行为而不是现在通过JTAG烧写时的行为。选择x4模式生成JIC文件意味着烧写到EPCS里的数据排列格式是x4格式的。如果将来FPGA的MSEL引脚配置为x4加载模式它就能以四线并行方式快速加载。但如果你的硬件MSEL引脚配置为x1模式却烧录了x4格式的JIC会导致上电配置失败。因此此处的选择必须与硬件电路板上FPGA的MSEL引脚电平设置严格对应。在不确定的情况下保守选择x1模式总是安全的。4. 单JTAG链多FPGA的JIC下载实操流程生成JIC文件后使用Quartus Programmer进行下载。这是最容易出错的地方。4.1 错误示范与原因分析一个典型的错误操作是在Programmer中只简单Add File选择刚刚生成的JIC文件然后点击Start。你会立刻收到错误Error (209031): Device chain in Chain Description File does not match physical device chain -- expected 1 device(s) but found 2 device(s).这个错误非常明确JIC文件内部描述的器件链此时它只“知道”Flash Loader那一个器件与物理扫描到的2个或更多器件不匹配。Programmer拒绝执行这种不匹配的操作以防止误操作损坏非目标器件。4.2 正确的多器件同时编程配置正确的做法是模拟一次“完整的链配置”过程同时进行Flash烧写。扫描硬件链打开Programmer确保已连接好JTAG下载器如USB-Blaster并给目标板上电。点击Auto Detect让Programmer扫描出JTAG链上所有的FPGA器件。假设检测到两个器件EP4CE15_0(Device 1) 和EP4CE15_1(Device 2)。为Flash Loader器件分配JIC文件在检测到的器件列表中右键点击你指定作为Flash Loader的那个器件例如EP4CE15_0。选择Change File。在弹出的对话框中选择你生成的.jic文件。你会发现该器件对应的Program/Configure选项会自动勾选。为其他器件分配临时SOF文件对于链上非Flash Loader的其他所有器件例如EP4CE15_1你需要为它们指定一个临时的配置文件。右键点击该器件选择Change File。这里可以添加任何一个能成功配置该FPGA的SOF文件。它可以是一个功能简单的“空”或“透传”设计推荐最安全。其最终应用设计的SOF文件如果此时已有。甚至可以是之前调试用的任何有效SOF。目的不是为了运行其功能仅仅是为了让该FPGA在配置阶段能正确完成SRAM加载从而释放其CONFIG_DONE引脚。勾选所有器件的配置选项这是至关重要的一步。在Programmer主界面的Program/Configure列你必须确保链上每一个器件前面的复选框都被勾选。这意味着本次操作将同时对链上所有器件进行SRAM配置对于Flash Loader器件则是先配置再执行其内部的Flash烧写例程。执行下载点击Start按钮。Programmer将按以下顺序执行通过JTAG将Flash Loader的SOF文件配置到EP4CE15_0。通过JTAG将临时SOF文件配置到EP4CE15_1。此时两个FPGA都配置完成整条链的CONFIG_DONE信号变为高电平硬件环境就绪。Programmer开始与EP4CE15_0中运行的Flash Loader逻辑通信。Flash Loader接收来自Programmer的JIC文件数据流通过SPI接口控制将配置数据包含两个FPGA的映像烧写到公共的EPCS芯片中。烧写完成后Programmer报告成功。4.3 关键验证实验为了深刻理解硬件CONFIG_DONE的约束我进行了一个实验在正确添加了JIC文件和所有SOF文件后只勾选Flash Loader器件EP4CE15_0的Program/Configure而取消勾选其他器件EP4CE15_1。点击Start后下载过程会在初期似乎正常但最终会失败Message窗口会提示配置超时或失败。这是因为EP4CE15_1未被配置其CONFIG_DONE引脚持续拉低导致整个板子的配置完成信号无法拉高Programmer在等待超时后判定配置失败从而Flash烧写流程根本无从启动。这个实验反向证明了“全链同时配置”的必要性。5. 效率分析与进阶探讨5.1 下载耗时分析在我的实际案例中对一片EPCS64烧写一个包含两个中型FPGA设计的JIC文件耗时约1分40秒。这个时间主要消耗在对两个FPGA的SRAM配置这部分较快。通过JTAG和Flash Loader向EPCS串行烧写数据这是最耗时的部分。JTAG接口速度、Flash Loader逻辑的SPI时钟频率、以及EPCS芯片本身的页编程和擦除时间都是影响因素。选择AS x4模式生成JIC文件不会加快这个烧写过程因为烧写通道仍然是Flash Loader控制的单SPI总线。x4模式只影响后续FPGA从EPCS加载的速度。5.2 能否将链上第二个FPGA作为Flash Loader这是一个很好的技术思考题。答案是理论上可以但通常不这样做且更复杂。原理上可行Flash Loader可以例化在JTAG链上的任何一个FPGA中只要这个FPGA与EPCS芯片有正确的SPI连接连接到了EPCS的片选、时钟、数据线。在生成JIC文件时你在“Flash Loader”步骤添加的就是这个作为Loader的FPGA型号并在“SOF Data”中按链顺序放入对应的SOF文件。为何通常不这样做以链上第二个器件为例配置顺序问题JTAG链配置是顺序进行的从最靠近TDI的器件开始。如果Flash Loader在第二个FPGA里Programmer必须首先配置第一个FPGA需要一个临时SOF然后才能配置第二个FPGAFlash Loader。这意味着第一个FPGA必须有一个能正确运行、且不干扰系统总线的临时设计这增加了复杂性。硬件连接考量通常设计时我们会把EPCS芯片布置在作为系统核心或便于布线的FPGA旁边。这个FPGA往往被安排在链的某个特定位置不一定是第一个。从硬件连接简便性出发谁直接连着EPCS谁就做Flash Loader最自然。软件操作一致性将链首的FPGA作为Flash Loader操作流程无论是单器件还是多器件最为统一和简单。工程师只需记住“链上第一个器件负责烧写”即可减少出错可能。实操建议除非有特殊的硬件布局或功耗管理要求否则强烈建议将JTAG链中最靠近TDI接口的第一个FPGA设计为Flash Loader的角色。这使软硬件交互最为清晰可靠。6. 常见问题与排查技巧实录即使按照上述步骤操作在实际工程中仍可能遇到问题。以下是一些常见故障及排查思路6.1 问题Programmer检测不到JTAG链或检测到的器件数量/型号不对排查步骤硬件连接检查确认JTAG下载器与板卡连接牢固TCK、TMS、TDI、TDO线序正确电源已接通。电源与电平检查测量FPGA的VCCIO给JTAG引脚供电的Bank电压是否正常并确保其电平与JTAG下载器的输出电平兼容例如均为3.3V。链中器件状态检查确保链上所有FPGA都处于正常工作状态特别是上电复位完成。某些器件的故障可能导致整条JTAG链“哑掉”。Programmer设置检查在Programmer的Hardware Setup中选择正确的下载器型号。在JTAG Settings中可以尝试降低JTAG Clock Frequency过高的时钟在长链或信号质量不佳时可能导致通信失败。6.2 问题生成JIC文件时失败提示“Can‘t find SOF data for device xxx”排查步骤SOF文件顺序确认在“Convert Programming Files”工具的SOF Data页签中你添加的SOF文件顺序与硬件JTAG链的物理顺序完全一致。器件型号匹配确认每个SOF文件编译时指定的FPGA具体型号例如EP4CE15F17C8与链中对应位置的物理器件型号完全一致。即使是同一系列封装、速度等级不同也可能导致不匹配。文件路径与权限确保Quartus有权限读取这些SOF文件且文件没有损坏。6.3 问题下载过程中在“Configuring device xxx”阶段失败排查步骤临时SOF文件问题重点怀疑分配给非Flash Loader器件的那个“临时SOF文件”。这个设计本身可能存在缺陷导致配置失败。尝试使用一个极简的、经过验证的“空”设计例如只有IO缓冲和PLL旁路来生成SOF文件替换掉原来的临时文件。电源完整性多个FPGA同时配置瞬间电流较大可能引起电源跌落。用示波器监测FPGA核心电压在配置瞬间的波形看是否有大幅跌落。CONFIG_DONE 信号使用示波器或逻辑分析仪测量板级CONFIG_DONE网络的信号。在配置命令发出后观察它是否被拉低以及最终能否成功拉高。如果一直为低说明有器件配置失败。6.4 问题Flash烧写成功但系统重新上电后FPGA无法自动加载排查步骤MSEL引脚电平这是最高频的原因。用万用表测量FPGA的MSEL0, MSEL1等引脚的电平确认其与生成JIC文件时选择的ModeAS x1 或 x4是否匹配。例如选择了AS x4生成JIC但MSEL引脚被电阻拉为x1模式的电平。EPCS芯片型号确认Convert Programming Files时选择的Configuration device型号与实际焊接的EPCS芯片型号一致如EPCS16 vs EPCS64。容量选小了会导致部分配置数据未写入容量选大了可能导致寻址不对齐。上电时序与复位检查FPGA和EPCS芯片的供电时序、上电复位信号是否满足数据手册要求。不满足时序可能导致FPGA在尝试从EPCS读取数据时EPCS还未准备好。AS接口布线检查FPGA与EPCS之间的DCLK、DATA0等信号线连接是否可靠有无短路、断路。对于x4模式还需检查DATA1-DATA3的连接。核心避坑经验对于单链多FPGA的JIC下载最稳健的方法是准备一套“烧写专用”的临时SOF文件。为Flash Loader器件编译一个标准的Flash Loader设计为链上其他每一个FPGA编译一个最简单的“通过式”或“静态IO”设计。将这些SOF文件存档管理。每次需要烧写最终应用的JIC时都使用这套固定的临时SOF文件组合可以极大避免因临时设计不稳定导致的配置失败问题将变量降到最低。