
去年完成了一块6U VPX信号处理卡主处理器选用TI的TMS320C6678八核DSP逻辑部分用Xilinx的XC7VX690T FPGA整卡通过VPX背板与系统互联。这块板卡从需求分析、芯片选型、原理图设计、PCB Layout到软硬件联合调试前后花了将近四个月。过程中踩了不少坑也留下了一些值得记录的经验。这里把这块板卡的原理图设计思路和调试过程梳理出来给正在做VPX板卡或者打算用DSPFPGA做信号处理的同行做个参考。这块卡的核心定位是信号处理板前端通过高速ADC采集数据FPGA负责实时预处理和接口调度DSP负责后续复杂的算法运算整个组合比较适合雷达信号处理、软件无线电、通信基带等领域。1. 整体架构设计与芯片选型思路1.1 为什么选C6678 XC7VX690T先说选型。TMS320C6678是TI KeyStone架构的旗舰DSP片内集成8个C66x内核主频最高1.25GHz单核支持定点和浮点运算提供高达160 GMACS和40 GFLOPS的算力。算力只是一方面更重要的是C6678的外设完整度它有DDR3接口、SRIO、PCIe、HyperLink、EMIF、SPI、UART、GPIO几乎是专门为信号处理板卡准备的。XC7VX690T属于Xilinx Virtex-7家族逻辑资源丰富LUT、DSP Slice、Block RAM都足够用而且带有大量GTX高速收发器最高速率12.5Gbps。FPGA的作用主要在前端高速数据接入、协议解析、预处理滤波、高速接口桥接这些维度它把ADC采集的数据整理成DSP友好的格式然后通过SRIO/PCIe等高速接口送给DSP。选这两颗芯片的组合本质上是“并行流水线与多核处理”的搭配。FPGA擅长高数据率、低延迟、固定模式的信号处理比如数字下变频、FFT、脉冲压缩的预处理部分DSP擅长灵活的算法流程、浮点运算、多模式切换。把两者配合起来既有流水强度又有算法弹性这是整套系统的价值所在。如果是做纯数据采集或者控制类板卡用便宜一些的中端FPGA加单核DSP就够没必要上这个量级的组合。从成本上看6678和690T都不是便宜芯片整板BOM成本在消费类来看是“天价”但在军工、科研、通信设备等领域属于常规操作。选型时还评估过Zynq UltraScale之类的异构SoC后来因为DSP生态里很多现有算法库和项目兼容问题最终保留了独立DSPFPGA的结构。1.2 6U VPX标准对硬件设计的影响这块板卡采用6U VPX规范板卡尺寸为233.35mm x 160mm和传统6U CPCI尺寸相当但连接器和背板体系完全不同。VPX采用MultiGig RT2连接器支持高速差分信号单对差分速率可以跑到10Gbps以上这是CPCI那套没法比的。6U VPX板卡通常有一排或者两排连接器例如P0、P1、P2、P3、P4、P5等P0引脚承担系统管理、参考时钟和电源等固定定义其他连接器则可以根据需求定义通用IO。做VPX板卡第一件要习惯的事是不能像普通板级设计那样随意规划引脚。P0的定义是规范固定死的12V电源、3.3V管理电源、参考时钟、系统管理总线这些都在P0上。功能引脚分布在P1到P5必须根据背板槽位的定义来设计如果背板是自定义的还好如果是标准OpenVPX体系还需要注意Profile选择比如SLT6-PAY-4F1Q2U等Profile定义了数据平面、控制平面和扩展平面怎么映射。我们这次设计是在指定的背板架构下进行的所以在原理图阶段就和结构/背板团队把引脚定义确认清楚避免后面Debug时发现某个高速通道被错误分配到非功能引脚上。VPX板卡在机械结构上也有讲究6U板高散热器高度、助拔器位置、面板开孔都要和机箱匹配。C6678和XC7VX690T加在一起功耗相当可观整板功耗早期评估就超过60W高负荷运行可能冲到90W。VPX背板供电一般有12V和5V板卡需要把12V转换成各种低压轨PCB上需要大面积铺铜和过孔阵列传流结构上还需要导冷板配合否则高负载下芯片温度压不住。做原理图时就要把电源预算放在首要位置不能画完图才发现电流不够。2. 原理图设计核心环节拆解2.1 电源树设计与上电时序这可能是整张原理图里最重要、也最容易出问题的部分。C6678和XC7VX690T对电源的要求都比较严格各轨之间不但电压不同还有上电顺序要求。我先把两块芯片的主要电源轨列出来电源轨目标电压用途最大电流参考DSP CVDD1.0VC6678内核电源约8A~10ADSP DVDD1.5VDSP DDR3接口电源约2A~3ADSP VDD1_81.8VDSP IO和模拟电源约2ADSP VDD3_33.3VDSP GPIO/配置电源约1AFPGA VCCINT1.0VFPGA内核逻辑电源约12A~15AFPGA VCCAUX1.8VFPGA辅助电源约2AFPGA VCCBRAM1.0VFPGA Block RAM电源约3AFPGA VCCO1.2V/1.5V/1.8V/2.5V/3.3VFPGA各Bank接口电平看接口定义FPGA MGT供电1.0V/1.2VGTX收发器电源约4A~6AC6678有明确的上电时序要求。按照官方推荐内核电源CVDD应当先于IO电源DVDD和VDD1_8上电最稳妥的做法是使用专门的电源时序控制芯片比如TI的UCD9012或者LTC2974这类带PMBus的电源管理控制器。FPGA这边同样要求VCCINT先于VCCAUX/VCCO上电虽然Xilinx文档说VCCO和VCCBRAM可以同时或者早于VCCINT但在实际项目中我会把所有轨道都用时序控制器统一管理避免边缘条件下出现闩锁。电源架构上采用了两级转换。VPX背板提供的12V总线先经过输入滤波和防浪涌电路再分几路进入中间母线电压。内核大电流电源轨DSP CVDD、FPGA VCCINT采用多相Buck控制器或者大功率DC-DC模块比如TI的TPS549D22这类PMBus控制器和电源时序控制器配合可以通过I2C读取电流温度数据。小电流轨用TPS54620这类简单DC-DC就够了。这里要特别提一句原理图设计时容易忽略的是FPGA的MGT电源噪声要求。GTX收发器对电源纹波极其敏感MGT的1.0V电源最好使用低噪声LDO或者带滤波的DC-DC旁边加足够的磁珠和去耦电容。我第一次做这种板卡时以为大DC-DC电源足够结果SRIO误码率总是偏高后来在MGT电源上增加LC滤波和专用低噪声电源轨才解决。另外输入端的防浪涌和EMI滤波不能省VPX背板是共享电源其他槽位板卡的热插拔会产生瞬态压降输入级需要TVS、防反接、保险丝或者电子断路器等保护。设计时每一路板级电源的关键节点都要预留测试点方便调试时用示波器量测序波形。2.2 时钟系统设计高速数字系统里时钟就是心跳。C6678和XC7VX690T涉及的时钟并不少而且每路要求不同。C6678的主输入时钟SYSCLK通常选择100MHz或者66.667MHz内部PLL倍频后得到CPU时钟和DDR时钟。这里需要根据实际需要的CPU主频选择。我们用100MHz有源晶振通过PLL配置成1GHz的Core Frequency用既能发挥性能又留有余量。DSP的DDR3参考时钟一般也是由片内PLL产生但理论上也可以使用外部差分时钟设计时我直接采用片内生成减少一路时钟树。FPGA侧的时钟相对灵活。每个CMT和GTX Bank都有专用时钟引脚。FPGA主工作时钟我选择200MHz差分晶振作为逻辑主频和DDR控制器参考时钟。GTX部分需要额外的参考时钟因为SRIO、PCIe这些高速协议对参考时钟的频率稳定度和抖动都有要求。SRIO一般用125MHz参考时钟PCIe Gen2则要求100MHz。一个简单的方式是让FPGA内部用MGTREFCLK因为XC7VX690T的GTX Bank提供了独立参考时钟引脚。设计时钟树时需要注意以下几点首先差分晶振的输出格式必须和FPGA/DSP的引脚标准匹配例如LVDS或LVPECL不能随便接一个单端晶振。其次时钟引脚必须连接专用时钟引脚例如DSP的SYSCLK需要使用特定的时钟输入引脚不能通过普通IO间接输入。最后时钟走线尽量短差分对要做阻抗匹配和包地处理。原理图阶段我们就把所有时钟缓冲器、时钟开关、备用时钟引脚都规划好方便调试时替换。2.3 配置与加载JTAG、SPI Flash、QSPIC6678和XC7VX690T都是基于SRAM工艺的大器件掉电后配置信息全部丢失每次上电都需要从外部加载程序/配置比特流。C6678的启动模式由芯片的BOOTMODE引脚决定常见的有No Boot、SPI Boot、EMIF Boot、SRIO Boot等。我们的板卡设计了SPI Boot作为主启动方式把程序固化在SPI NOR Flash里面。C6678的SPI Boot需要先经过ROM Bootloader从SPI Flash读取程序到L2 SRAM然后执行。实际操作时通常先通过JTAG加载调试版程序确认功能正常后再固化到Flash。原理图上需要把SPI Flash的片选、时钟、数据引脚接到DSP对应引脚同时要保证Flash供电电压和DSP SPI IO电压一致。FPGA的配置方式更为灵活可以用JTAG、SPI x1/x4、BPI等模式。我们选择了主SPI x4模式板上放置一块QSPI Flash上电后FPGA自动从Flash加载配置。另外保留了JTAG链用于在线调试和Flash烧写。设计JTAG链时要么把所有器件串成一条链要么用专用JTAG switch芯片隔离。多目标芯片存在时建议使用Lattice的LTC4316之类的I2C JTAG MUX或者直接用物理跳线把不同器件的JTAG信号分开避免调试时互相干扰。C6678和XC7VX690T之间的配置也可以联动比如DSP通过GPIO控制FPGA的PROGRAM引脚在DSP启动完成后主动给FPGA重新加载配置或者通过SPI接口写FPGA Flash。这类复杂应用在原理图上只需预留控制信号软件层面实现即可。大多数情况下独立启动就够了。2.4 高速接口设计DDR3、SRIO、PCIe、LVDS板卡上要处理数据绕不开这几类高速接口。先说DDR3。C6678自带一个64位的DDR3控制器最大支持DDR3-1600 MT/s我们在设计时按照DDR3-1333频率跑留了裕量。DDR3的拓扑结构采用fly-by菊花链地址、控制、时钟线一根根串过去数据线按字节lane分组。原理图里要保证每组数据线的DQ、DQS、DM信号连到DSP对应引脚不能交叉错位。地址线和控制线虽然可以任意交换引脚但最好按Bank分组PCB布线时方便。终端电阻RZQ也需要接精密电阻到地这里建议用1%精度电阻。FPGA侧同样需要DDR3使用Xilinx MIG IP生成DDR3控制器。690T的HP Bank专门用于高性能IODDR3接口建议放在HP Bank上。MIG IP核会给出引脚分配建议但实际上我们根据板卡布局做了一定调整只要约束文件里正确配置引脚、位宽和对齐方式即可。SRIO是FPGA和DSP之间的主要数据通道。C6678的SRIO端口支持1x、2x、4x模式每通道最高5Gbps。我们用4x模式连接FPGA的GTX收发器。原理图设计时差分对也必须连接到GTX的专用引脚同时需要提供正确的MGTREFCLK。SRIO的差分信号之间要做好等长和阻抗匹配FPGA端的GTX还支持接收端均衡调试时可以调整参数改善信号质量。PCIe也是可选的高速互联。C6678内置PCIe控制器但它是Endpoint模式不是Root Complex所以想直接连接其他PCIe设备需要FPGA帮忙或者用专门的PCIE switch。我们板卡上的PCIe主要用于和背板连接比如通过PCIe接口跟系统控制器通信。FPGA的GTX可以灵活配置成PCIe但要注意PCIe一般需要100MHz参考时钟。原理图设计时把PCIe通道规划到P1连接器数据平面。实际调试时如果PCIe总是枚举失败优先检查参考时钟和复位信号。LVDS接口在FPGA Bank上很常用比如连接高速ADC数据输出。XC7VX690T支持LVDS电平标准但某些Bank的IO Bank电压必须匹配。比如ADC输出是1.8V LVDS那么FPGA对应Bank的VCCO也应该设置为1.8V。LVDS信号是成对出现的原理图上可以交换同组差分对的P和N但要做到一对内反接不能跨对交换。另外LVDS走线的等长要求较高通常要求差分对内等长不超过50mil对间等长不超过100mil这些需要在Layout阶段严格控制。3. FPGA与DSP协同工作的实现细节3.1 FPGA侧关键逻辑模块FPGA代码是整个板卡的数据入口。对我个人经验而言FPGA设计不要一上来就堆功能先把基础模块写稳。以下几个模块几乎每次做信号处理板都会用到。第一个是DDR3控制器。基于Xilinx MIG IP生成之后还要写一个简单的用户接口逻辑封装成FIFO接口方便其他模块读写数据。很多新手在MIG IP自带的example design里跑得通但迁到自己的工程里就各种问题大多数时候是地址对齐、数据宽度或者burst长度不匹配。MIG的user interface是AXI4或者Native接口我习惯在它外面包一层Simple FIFO接口这样逻辑里就只关心读使能、写使能和数据总线。调试初期先做一个“写固定数据再读回来比对”的self-test确认DDR链路没问题再做正式应用。第二个是高速ADC数据采集。ADC经常输出LVDS信号FPGA这边用ISERDES原语做串并转换达到需要的采样数据速率。如果ADC有SYNC引脚需要FPGA产生采样时钟同步信号。这个模块调起来一定要先用示波器看时钟、看同步信号再上板上逻辑分析仪。通常问题出现在时钟域处理上跨时钟域一定要用FIFO或者AXI握手来做绝不要直接用双沿时钟瞎采。这里推荐多写Testbench仿真时不光能验证逻辑还能帮你在波形上直观看到跨时钟域问题。第三个是串口调试模块。FPGA串口接收和发送虽然简单但每次调板都靠它输出调试信息。ChipScope或者ILA虽然好用但有些接口异常时很难抓到波形反而是串口最可靠。我们板卡上FPGA的UART接到一个DB9或者调试口初期做回环测试、状态上报非常方便。写串口模块的Testbench时我的习惯是用随机间隔的数据来压测接收逻辑避免只在理想时序下通过仿真。第四个是自定义控制寄存器。FPGA和DSP之间除了高速数据流还需要一些低速控制面比如让DSP通过EMIF或者GPIO读写FPGA的寄存器。FPGA内部定义一个寄存器数组每个bit的用途通过文档维护。DSP写控制字FPGA内部逻辑根据控制字切换数据源、启动/停止链路、上报状态。这种方式比高频握手简单可靠适合大多数信号处理板。FPGA侧Testbench是值得多说一句的。很多工程师眼高手低觉得写Testbench浪费时间。实际上一块复杂板卡上FPGA逻辑出bug的代价极高必须通过仿真提前验证。写Testbench的推荐做法是把时钟、复位、外部接口的行为模型搭好再用任务函数模拟主机读写、数据源发送最后通过断言检查输出。至少要把DDR控制器接口回环、串口收发、SRIO链路层回环这几个关键场景仿真通过再上板。3.2 DSP侧软件与驱动要点DSP开发环境一般是CCSCode Composer Studio调试C6678需要XDS系列仿真器。第一次开发C6678的同仁最容易卡在仿真器的连接和驱动安装上。仿真器驱动安装不是简单的“下一步”而是需要在CCS内配置Target Configuration选择对应的仿真器类型和目标芯片C6678然后连接目标板。如果CCS版本和仿真器驱动不匹配连接时经常报错。建议仿真器驱动和CCS版本保持一致并查看设备管理器确认仿真器被正确识别。C6678连接不上时80%的原因是电源时序、复位电路或者仿真器没有上电剩下20%才是配置问题。DSP上电后第一件事是初始化PLL、DDR控制器和电源管理。C6678的DDR初始化比较繁琐需要设置EMIF寄存器、DDR3控制器寄存器、PHY寄存器等。如果照抄别的项目的DDR配置代码经常跑不起来因为DDR颗粒不同时序参数也不一样。我的建议是直接使用TI提供的KeyStone DDR3配置参考代码然后根据我们板卡实际DDR颗粒型号修改timing参数和地址映射。初始化DDR后可以先用DSP做简单的写读测试确认DDR访问正确再继续上层应用。多核启动是C6678的一个重要特性。8个核都从复位后通常会先由一个主核Core0完成外设初始化然后通过IPC中断和共享内存把其他核引导到对应程序入口。如果只做单核开发那不用管多核启动但既然上了一块八核DSP还是要早早规划多核任务分区。例如Core0负责控制面和数据分发Core1~Core3各负责一路信号的算法Core4~Core7做其他通道处理。多核之间通过共享内存MSMC或者DDR交换数据但要注意cache一致性使用时要对共享区域做cache invalidate/flush操作。SRIO驱动开发是DSP和FPGA数据通路中的关键。C6678的SRIO寄存器不少但TI提供了完整的驱动库SRIO LLD我们一般直接基于它移植。调试时先做回环也就是DSP侧把数据发出去再收回来确认SRIO物理层和链路层正常。然后FPGA侧也做同样的回环最后再打通两端。如果SRIO链路时而通时不通优先检查差分对的极性、参考时钟引脚配置以及两个器件之间使用的传输格式是否一致。实际调试中我们还遇到过DSP和FPGA之间寄存器读写错乱的问题原因是DSP的EMIF总线时序和FPGA侧的逻辑握手不匹配。后来把EMIF的等待周期和读写时序参数调整到合适值问题就解决了。这类问题在原理图上体现不出来但引脚规划和上拉/下拉电阻会影响状态默认值所以原理图阶段也要把EMIF总线信号的电平、方向、上下拉处理清楚。3.3 联合调试流程联合调试绝不能一上来就直接跑全链路要有层次。我习惯按以下顺序推进电源测试上电前用万用表量测各电源轨对地阻抗确认没有短路再上电。上电后用示波器观察各个电源轨电压和上电时序是否符合设计。这里建议专门给电源时序控制器一个使能控制位方便逐级上电。JTAG调试先连DSP仿真器连接XDS后确认DSP可以识别。再连FPGA的JTAG链通过Xilinx Vivado Hardware Manager扫描器件确认FPGA可以发现。基础功能测试DSP和FPGA各跑简单的流水灯/寄存器读写测试。FPGA内部通过串口上报寄存器状态DSP通过EMIF读写FPGA寄存器两端能交互就说明低速通道OK。DDR测试DSP和FPGA分别做DDR自检通过串口或者CCS观察读写结果。这一步建议跑满读写次数比如循环读写一整天确保稳定性。高速接口回环SRIO先做内部回环再做板间回环。两个器件上都配置成回环模式如果用示波器能看到GTX差分信号说明物理链路已经OK。小包传输先传一小包固定数据确认数据内容和字节顺序无误再逐步增大包长验证大包连续传输时是否有丢包、错位。全链路加载FPGA采集ADC数据DSP处理并输出结果这时候功能已经完整可以测试长时间运行的稳定性和温度表现。联合调试中最常见的是数据错位问题。SRIO传输是按64-bit字或者32-bit字打包的两端设置的传输字长不一致时DSP收到的数据就是乱序的。排查的方法是发一组带序号的数据从序号变化判断错位规律。这种情况不需要改原理图但需要对软件配置对齐。4. 调试中遇到的典型问题与排查心得4.1 DSP上电后发热严重却连不上仿真器第一次调试时DSP上电电流明显偏大且表面发热。用万用表测CVDD和DVDD都正常但仿真器始终无法扫描到DSP。后来检查原理图发现DSP的若干GPIO和配置引脚的默认状态不对导致DSP进入了异常启动模式。C6678的BOOTMODE引脚是复用引脚外部没有正确上下拉时默认状态可能引导进入不详的启动模式比如尝试从外部存储器启动导致未初始化外设就一直卡住。查芯片手册并一一核实每个BOOTMODE引脚的电平后问题解决。吸取的教训是DSP启动模式引脚必须仔细设计需要根据最终启动方式确定上下拉电阻预留跳线作为调试备选。4.2 FPGA配置成功但MGT信号质量差FPGA通过QSPI加载成功串口也输出了系统信息但SRIO链路总是建不起来。用仿真器观察FPGA内部GTX的参考时钟状态发现MGT参考时钟没有正常锁存。原来是GTX参考时钟引脚误接到了普通CMT时钟引脚虽然频率相同但是GTX的PLL无法使用普通时钟引脚作为参考导致GTX无法工作。重新查阅FPGA引脚手册把参考时钟改到MGTREFCLK专用引脚后链路立即正常。这个问题说明原理图阶段必须核对“专用功能引脚”的引脚名不能只看物理位置或者Bank号。4.3 DDR3偶发读写错误FPGA的DDR3读写在低速率时正常跑到目标速率后偶发校验错误。用ILA抓错误地址和数据发现错误大多集中在某几个地址区域。初步怀疑是板级信号完整性问题后来对原理图复查发现有一片DDR3的地址线在连接器封装上做成了网络标号但PCB布线时把同一片DDR的三个地址球错接到了另一个地址位导致地址变换时出现瞬间的错误。这是一个典型的原理图符号引脚排序错误问题用DRC没有完全查出来。解决办法是画DDR3原理图时必须逐一对照BGA封装丝印和信号定义不要轻信网上的封装库。之后我们又系统地检查了所有DDR3地址线接通后故障消失。4.4 SRIO回环通过但板间互联丢包严重单个板卡内部回环没问题放到整机背板上互连时丢包而且误码率随速率升高急剧变差。一开始以为背板走线有问题后来通过在FPGA端调整GTX的TX预加重和RX均衡参数同时降低SRIO链路速率到3.125Gbps误码率恢复正常。这说明高速信号互联是一个链路整体背板连接器、走线过孔、电缆都会影响信号质量软件端的均衡参数是最后一道防线。原理图设计时留出GTX的串行电容、焊盘和调试位方便后续调整。4.5 常见问题速查表现象可能原因快速排查方法DSP无法连接仿真器上电时序不对、BOOTMODE错误、仿真器驱动配置不对量测电源轨电压/时序核对JTAG引脚电平重装/更新仿真器驱动FPGA不加载QSPI芯片损坏、配置模式引脚错误、Flash电气不兼容检查MODE引脚电平Vivado扫描JTAG并用临时bitstream验证DDR读写错误地址线错位、时序参数不合适、供电噪声按地址范围分块测试比对MIG时序配置用示波器观察电源纹波SRIO链路不通差分极性接反、参考时钟频率/引脚不对、链路协议配置不一致检查差分P/N连接核对MGTREFCLK引脚两端都做回环测试PCIe枚举失败参考时钟缺失、复位信号时序不对、通道映射错误检查100MHz时钟控制复位时序用Xilinx PCIe example design自检电源噪声大DC-DC器件选型不当、Layout环路大、滤波电容不足检查开关节点波形增加输入输出电容必要时改用LDO板卡工作过热散热器未装、电源效率低、风道不合理查看导冷板贴合情况用红外热像仪测量发热点5. 后续可扩展的方向这块板卡的原理图设计基本定型后还可以做几个方向的扩展。一个是把FPGA和DSP之间的数据通路升级为更大的数据带宽比如在SRIO之外再增加一组PCIe x4链路或者利用FPGA的GTZ收发器跑40Gbps以太网。另一个方向是增加同步采集能力比如在VPX背板上引入PTP时间同步或者1PPS信号让多板卡协同采集时间基准一致。还可以扩展FPGA侧的IO资源通过FMC接口连接专用数据采集子卡适应不同ADC/DAC模块。功耗优化方面如果后续改用更新的DSP或者多核SoC可以进一步降低整板功耗。目前C6678片上多核全开时功耗仍偏高不少项目用SRIO PCIe等高速外设也不一定全开。设计时可以预留动态电压/频率调节的接口通过PMBus调节内核电压和主频在性能要求不高时降功耗运行。从工程复用的角度我把这套原理图里的电源树、时钟树、DDR3接口、SRIO/PCIe链路、JTAG链和配置电路整理成标准模块库后续新的VPX板卡可以直接改芯片型号和引脚分配不必从头画。这个习惯对团队效率和板卡质量提升很有帮助。最后分享一个小技巧原理图设计时务必在每页图纸右下角标注版本号和修改记录。这个项目后期调试时我们经常需要回到某个电源改动或者某个接口定义修改的版本去排查问题如果没有版本记录全靠脑子和聊天记录很容易搞混。哪怕是一个电阻阻值的调整也要留一行修改记录这比画一堆“设计说明”有用得多。