工业控制、测试测量这类场合,主机侧要高速下指令、实时回传采集数据,设备侧还得有硬实时的控制环路,这两件事塞进一颗芯片里通常做不干净。这套以 PEX8311 牵头的 PCIE 应用开发板,思路就是把两件事拆开:PCIE 侧交给专用桥片,业务逻辑交给 FPGA,实时控制丢给 TMS320F28335。整包硬件工程用 PROTEL99 完成,原理图和 PCB 文件都在里面,属于那种拿到手就能改改就用的"半成品平台"。它适合三类人:一是手上压着老平台维护任务、需要复用 99SE 工程习惯的硬件工程师;二是想搞明白 PCIE 到底怎么从金手指一路走到本地总线、再走到 DSP 的嵌入式开发者;三是需要一块能跑的 PCIE 采集/控制卡原型、又不想从零画板的项目负责人。下面我把这块板子从架构到布线、从原理图到打样调试的整条链路拆开讲,重点讲清楚每一个设计动作背后的原因,以及那些手册上不会写的坑。
1. 这块板到底解决什么问题:整体架构与选型拆解
1.1 三段式数据通路是核心
整块板子最值得先看清楚的,是它的数据流被切成了三段,每一段用的器件类型都不一样。上位机(就是插卡的那台主机)通过 PCIE 链路把数据推给 PEX8311,桥片把这串高速串行包翻译成一条并行本地总线上的读写周期;FPGA 挂着这条本地总线,把数据搬进内部 FIFO 或者寄存器组;FPGA 的另一侧又用 XINTF 接口挂到 TMS320F28335 上,DSP 通过读写自己的外部存储空间就能把数据取走或者回传。反方向也同理,DSP 写 XINTF,FPGA 收到后通过本地总线推给 8311,8311 再打包上传给主机。
这么切的好处非常直接。PCIE 协议栈复杂、链路训练、TLP 封包拆包这些东西,自己用 FPGA 实现一套软核不是不行,但调试周期会拉得很长,而且版本一升级就得重来。用 8311 这种专用桥片,PCIE 侧的事情它全包了,你只需要面对一条相对老实的并行总线,时序清晰、逻辑分析仪一挂就能看。FPGA 在这中间扮演的是"翻译官+缓冲池",把两种完全不同的总线时序对起来,同时用 FIFO 吸收两侧的速率差和突发性。DSP 则完全不用管 PCUE 那一套,它只认自己的 XINTF 时序,代码上就是在几个固定地址读写,工程师上手成本极低。
我见过不少人一上来就想用一颗 FPGA 把 PCIE 硬核、控制算法、数据缓存全包了。能做成,但对团队要求很高:PCIE 硬核的时序约束、跨时钟域、驱动开发、算法定点化,四件事同时压上来,任何一环出问题都会让整个项目卡住。分段之后,每一段都可以单独验证,出了问题也容易定位到是哪一段。
1.2 三颗器件的分工边界
PEX8311 是 PLX(后来被收购)的 PCI Express 到本地总线桥,单通道 Gen1,理论单向带宽 250MB/s 量级。对绝大多数工业采集和控制场景,这个带宽是够的,尤其是配上 DMA 之后,实际能跑出来的持续吞吐通常能到百兆字节每秒级别。它支持本地总线地址数据复用和非复用两种接法,也支持两个 DMA 通道,还有串行 EEPROM 用来加载配置信息。
FPGA 在这块板上的定位很明确:总线桥接 + 数据缓冲 + 必要的时序整形。不承担算法主运算,只做搬数据和握手。选型上不需要太大,逻辑单元够放几个 FIFO、一套地址译码、一套跨时钟域同步电路就行,管脚数量反而是重点——要同时接 8311 的本地总线和 DSP 的 XINTF,IO 数量不能省。选择时优先看 IO 数量、是否有足够的 Block RAM 做 FIFO、以及封装是否方便布线。
TMS320F28335 是 TI C2000 系列里的经典款,150MHz 主频,带浮点单元,XINTF 外部接口能直接挂异步外设。把它放在这里,看中的就是实时性和外设资源:ePWM、ADC、eCAP 一应俱全,做电机控制、电源变换、数据采集都是熟路子。它不需要参与 PCIE 通信,只通过 XINTF 跟 FPGA 交换数据,代码里就是往几个固定地址读写,非常干净。
1.3 为什么这套工程还在用 PROTEL99
这个问题必须正面回答,不然很多人第一反应就是"都什么年代了还用 99SE"。原因通常有三层。第一层是存量:很多工业设备厂商的硬件资产库里,从九十年代末到 2010 年前后的板子全是 99SE 工程,格式统一、元件库统一、评审流程统一,新板子在这个体系里走最省事。第二层是许可与 IT 环境:有些内网环境只部署了 99SE,新工具装不上或者审批麻烦,团队只能沿着老路走。第三层是能力匹配:99SE 画这种双层或四层、几十个网络标号的中低速板子,功能完全够用,熟练工程师用起来速度极快。
但必须承认它的短板:没有真正的差分对规则,没有交互式等长绕线(只有 Tools 菜单下的长度匹配工具),阻抗计算要靠层叠管理器里附带的计算器,跨页高速信号的约束管理基本靠人脑和文档。所以用 99SE 做 PCIE 板,考验的不是工具,而是工程师自己有没有把规则记在脑子里、落实到检查清单上。后面第 4 章我会专门讲 99SE 里怎么靠手工手段实现等长和差分控制。
2. 关键器件特性拆解与接口时序匹配
2.1 PEX8311 侧必须搞清的几件事
用 8311 最容易翻车的地方,是配置空间的初始化。芯片上电后会去读串行 EEPROM,从里面加载 Vendor ID、Device ID、子系统 ID、Class Code 以及各个 BAR 的大小和类型。EEPROM 里面没烧内容或者内容不对,主机枚举时看到的可能就是一堆默认值,BAR 申请不到你期望的空间,驱动加载直接失败。所以打样前一定要把 EEPROM 的配置内容先规划好,写清楚每个 BAR 要多大空间、映射到本地总线还是内部寄存器、是内存空间还是 IO 空间。
第二个关键是本地总线模式的选择。8311 支持地址数据复用和非复用两种本地总线接法,复用模式下地址和数据共用一批引脚,省管脚但时序更紧;非复用模式下地址线独立,逻辑分析仪抓波形更直观,FPGA 侧写逻辑也更容易。考虑到 FPGA 的 IO 本来就紧张,同时还要接 DSP,实际项目中选复用模式的偏多,但调试阶段非复用确实省心。这个取舍没有标准答案,取决于你的 IO 预算和团队调试习惯。
第三是本地总线时钟。8311 的本地总线跑在一个独立的时钟域上,这个时钟通常由外部有源晶振提供,频率选择要兼顾 FPGA 的时序余量和带宽需求。频率越高带宽越大,但对 FPGA 内部时序收敛和 PCB 走线质量的要求也越高。我的经验是从中低频率起步,先把功能跑通,再评估要不要提频。
2.2 FPGA 作为总线翻译官的实现要点
FPGA 内部逻辑其实可以拆成四个模块来看。第一个是本地总线从设备接口,负责识别 8311 发过来的读写周期、锁存地址、响应数据、拉低准备好信号。第二个是 XINTF 从设备接口,负责识别 DSP 发过来的片选和读写选通、给出数据、必要时用 XREADY 插入等待周期。第三个是双口 FIFO 或者寄存器堆,作为两侧的数据交换区。第四个是中断与状态逻辑,把 8311 侧的中断信号、DSP 侧的中断请求、各种状态位管理起来。
跨时钟域是这个模块里最容易出问题的地方。本地总线的时钟和 XINTF 的时钟来自不同源,两者之间传数据必须做同步。FIFO 指针这种多比特信号不能直接用两级触发器打拍,要么用格雷码加两级同步,要么直接用 FPGA 厂商提供的异步 FIFO IP。地址和数据总线更麻烦,因为它们是随读写选通一起有效的,必须用握手信号把它们"圈"住,让对侧只在确定有效的窗口内采样。
还有一个隐蔽的坑:DSP 的 XINTF 是异步接口,配置成多少个等待周期是可以调的。如果 FPGA 侧逻辑还没把数据准备好,DSP 又没插足够的等待,读回来的就是垃圾数据或者上一次的残留。稳妥做法是让 FPGA 用 XREADY 信号主动申请延长周期,而不是靠软件里试出一个"刚好够用"的等待参数——那种参数在温度变化、电压波动、批次差异下很容易失效。
2.3 TMS320F28335 的 XINTF 时序约束
F28335 的 XINTF 是异步并行接口,有独立的地址总线、数据总线、片选和读写选通,每个 Zone 可以单独配置时序参数,包括建立、激活、跟踪三个阶段的最小周期数。芯片把外部空间分成了几个 Zone,每个 Zone 有固定的片选和地址范围,实际接线时通常把 FPGA 映射到其中一个 Zone 上,地址范围取够用就行。
配置的时候有个容易忽略的点:XINTF 的时钟来自系统时钟的分频,而这个分频系数和 Zone 的时序参数共同决定了实际访问速度。如果你的 FPGA 逻辑响应需要若干个时钟周期,那就要把 Zone 的激活周期配置得比它长,同时留出余量。我的习惯是先按保守值配置,用示波器或者逻辑分析仪实测一次读写的完整波形,确认余量之后再逐步收紧,每次都重新测一遍。
数据总线宽度也要提前定。XINTF 支持不同的数据宽度配置,宽度选得越宽,同样的数据量占用的访问次数越少,但 FPGA 侧的接口逻辑也更占资源。对于以命令和小批量数据为主的场景,窄总线足够;对于大批量流式数据,宽总线更划算。这个决策要和上位机的数据包结构一起考虑,避免出现"宽度很宽但每次都只填几个字节"的浪费。
2.4 时钟与复位网络的统一规划
这块板上有三个主要时钟域,必须提前规划好各自的来源和走向。PCIE 侧需要一路 100MHz 的差分参考时钟,通常由主板通过金手指提供,走线时要严格按差分规则处理。本地总线侧需要一个本地时钟源,由板上有源晶振提供。DSP 侧用一颗晶振经过内部锁相环倍频到系统主频,同时 DSP 还能输出一路时钟给 FPGA,用作 XINTF 侧的同步参考。
复位方面,PCIE 侧的复位来自接口信号,需要经过电平转换或者同步之后送给 8311;系统侧还要有一个独立的板级复位源,保证在上位机没上电或者没枚举之前,FPGA 和 DSP 能进入确定状态。这里有个实际经验:不要让 DSP 的复位完全依赖 PCIE 侧的复位信号,因为很多人调试时是先给板子单独供电、后插主机,顺序一乱就容易出现一侧已经跑起来、另一侧还在复位里的状态,调试现象会非常迷惑。用一个独立的上电复位芯片同时管住系统侧,PCIE 复位另外单独处理,逻辑上清爽很多。
3. PROTEL99 原理图设计实操
3.1 元件库准备与自建元件
99SE 时代最大的痛点之一就是元件库不齐。8311 这种 BGA 封装、几百个管脚的芯片,标准库里基本不可能有现成的,必须自己建。我的做法是分两步:先建原理图符号,把管脚按功能分组摆放,而不是按物理顺序一字排开。按功能分组的好处是原理图上连线清晰,832 个管脚一字排开画出来谁都不想看,评审也没法审。
建符号时有几个细节要注意。电源和地管脚不要隐藏,99SE 允许把电源管脚设成隐藏并自动连接,看起来省事,但一旦网络名写错或者漏连,ERC 根本查不出来,最后只能靠人肉核对。命名上保持和手册一致,别自己发明缩写,否则半年后回来改板,自己都认不出哪个脚是哪个。管脚编号一定要和封装一一对应,BGA 封装的编号通常是字母加数字的组合,容易看花眼,建完之后至少找两个人交叉核对一遍。
PCB 封装更要小心。BGA 的焊盘直径、球间距、阻焊开窗尺寸都有讲究,建议直接找器件厂商的封装推荐文档,或者用 IPC 标准计算器算一遍。别从别的项目直接复制过来,不同批次的芯片封装可能有差异,尤其是球径和间距。
3.2 图纸分页与网络标号规范
一块中等复杂度的板子,原理图肯定要分好几页。合理的分法是按功能模块分:PCIE 接口与桥片区、FPGA 及其配置电路区、DSP 及其外设区、电源区、时钟与复位区。分页之后跨页信号全靠网络标号,这时候命名规范就变成生死攸关的事情。
我的规矩是这样的:总线类信号统一前缀,比如本地总线地址用统一前缀加位号,数据线同理;差分对的两个网络用固定的后缀区分正负,并且从原理图阶段就成对出现,方便后面在 PCB 里批量选中;控制信号用功能加极性后缀,低电平有效的加明确的标记。特别要注意的是别用中文标号,也别用特殊符号,99SE 对特殊字符的处理一直不太靠谱,导出网表的时候容易出莫名其妙的错误。
另外,99SE 的全局网络标号是全局有效的,不同页里出现同名标号就自动连在一起。这既是优点也是陷阱:同一个名字在 FPGA 页和 DSP 页都用,就会把两处连起来。命名的时候要带上模块前缀,比如给 FPGA 侧和 DSP 侧的同类信号加上不同的模块标识,避免误连。
3.3 电源域划分与去耦网络
这块板至少有三个电源域:PCIE 接口提供的 12V 和 3.3V、板内降压出来的各级电压、以及芯片各自需要的核心电压和 IO 电压。画原理图时建议把每个芯片的电源管脚单独拉出来一片区域,把去耦电容和它并排放在一起,而不是把电容统一堆在图纸角落。统一堆放的后果是画 PCB 时你得靠记忆去放,很容易漏。
去耦电容的配置上,大容量和小容量搭配使用是常规做法:每个电源管脚附近放小容量的高频去耦,每个电源域再放若干大容量的储能电容。这里有个经验值:BGA 封装芯片的背面空间要提前规划好,去耦电容要尽量靠近管脚,宁可多放几个过孔从背面接过去,也别为了省事放在远处。特别是内部有多路电源域的芯片,每一路的去耦都要独立考虑,不能共用。
原理图上还要把电源域之间的连接关系标清楚,比如哪一路是给核心供电、哪一路是给 IO 供电、有没有上下电顺序要求。有些芯片要求核心电压先建立、IO 电压后建立,或者反过来,这个顺序要求必须在原理图上标注出来,并在电源设计时用使能信号或者电源管理芯片来实现。
3.4 ERC 检查与常见报错处置
99SE 的 ERC 检查能力有限,但只要认真用,能拦下相当一部分低级错误。跑完 ERC 之后常见的几类报错要区别对待。管脚冲突类报错,多半是两个输出管脚接到了同一个网络,或者输入管脚悬空,这类必须逐条查清,不能放过。未连接管脚类报错,要看是设计上真的不用,还是漏连了,前者可以在属性里标记为忽略,后者必须补上。
还有一类报错是电源管脚未驱动,通常是因为电源网络被当成了普通网络。这时候要检查电源网络是否被正确定义。另外,元件重复位号、网络标号拼写不一致这类问题,ERC 不一定能全部揪出来,需要自己写检查清单手动过一遍。
我个人的习惯是:ERC 跑完之后,把原理图从头到尾再"读"一遍,不是看连线,而是按信号流向读,从接口进去、经过哪颗芯片、到达哪个引脚、再从哪出来。这个"读图"过程往往能发现 ERC 发现不了的设计逻辑错误,比如把读写选通接反了、片选接到了错误的 Zone 上。花半小时读图,后面可能省下两周的调试时间。
4. PCB 布局布线的核心环节实现
4.1 叠层设计与 100 欧姆差分阻抗计算
PCIE 的差分阻抗要求是 100 欧姆(差分),对应单端大约 50 欧姆。在 99SE 里做阻抗控制,要先用层叠管理器定好叠层结构,把每一层的材料、厚度、铜厚设置好,然后用里面附带的阻抗计算功能估算线宽和间距。
给一个实际可用的估算过程,方便你建立直觉。假设用常规 FR-4 材料,介电常数取 4.3,顶层到内层地平面的介质厚度 0.2mm,铜厚按 1 盎司(约 0.035mm)算。单端微带线的阻抗可以按下面的经验关系估算:
- 单端阻抗大致正比于介质厚度的对数、反比于线宽的对数,介质越厚、线越细,阻抗越高
- 差分阻抗还要考虑两根线之间的耦合,间距越小耦合越强,差分阻抗越低
把这些关系代进去算,介质厚度 0.2mm 的情况下,线宽做到 0.23mm 左右、间距 0.2mm 左右,差分阻抗大致落在 100 欧姆附近。这个结果只能用来起步,实际误差可能有正负百分之十,因为介电常数会随频率和树脂含量变化,压合后的实际介质厚度也和你标称的不完全一样。
正确的做法是:把叠层和线宽间距参数发给板厂,让他们用实际压合参数回算并给出阻抗测试报告。如果板厂不支持阻抗测试,那就自己留一条测试线,板子回来之后用 TDR 测一下,根据实测结果决定后续批次要不要调整线宽。我见过不少项目直接抄别人的线宽,结果换了一家板厂、材料批次一变,阻抗偏了十几个点,链路虽然能连上但眼图很差,高温下就出误码。
4.2 PCIE 差分对的布线规则
差分对是这块板最讲究的部分。规则可以总结成几条,但每条背后的原因要明白。
对内等长是第一位的。同一对的正负两根线,长度差要控制在很小的范围内,否则两根线上的信号到达时间不一致,差分信号会退化成带共模分量的信号,接收端眼图张开度变差。经验值是对内长度差控制在几个密耳以内。在 99SE 里没有自动对内等长工具,需要手工绕蛇形线,或者用 Tools 菜单里的长度匹配功能,选定网络后设定目标长度,由工具自动绕线,绕完之后一定要目视检查一遍,确认绕出来的蛇形线节距均匀、没有回折。
对内间距要恒定。两根线要全程保持大致相同的间距,不要一会儿贴近一会儿分开。间距变化会造成局部阻抗不连续,产生反射。布线的时候最好让两根线"绑"在一起走,拐弯处两根线同步拐,别出现一根拐大弯一根拐小弯的情况。
差分对之间不需要严格等长。这一点经常被误解。PCIE 的发送方向每一对是独立的,对与对之间没有严格的到达时序要求,只要各自满足对内等长即可。真正需要注意的是对与对之间的间距,要保持足够距离避免串扰,通常建议至少三倍线宽以上的间隔,有条件的话在不同层之间用地平面隔开。
参考平面要完整。差分线经过的区域下方必须有连续的参考平面,不能跨平面分割。跨分割会让回流路径断裂,阻抗突变,辐射也变大。布线前先把平面规划好,把分割区域的边界画出来,布差分线的时候绕着走。
过孔要少且对称。每条差分线经过的过孔数量越少越好,如果必须换层,两根线要同时换层、用过孔对称布置,并且换层处旁边要加回流过孔,给信号提供就近的回流路径。不同层之间走线长度也要计入总长度,不能只算某一层。
4.3 本地总线和 XINTF 总线的走线策略
这两条总线虽然不像 PCIE 那么敏感,但也不建议随意。地址线、数据线、控制线最好分组走,同一组线尽量走同一层,参考同一个平面。地址线和数据线内部不需要严格等长,因为它们的时序余量通常比 PCIE 大得多,但走线长度还是尽量接近,避免出现某几根线特别长、导致时序裕度被吃掉。
控制信号要特别注意。读写选通、片选、准备好这些信号往往是决定采样时刻的关键,它们的走线要尽量短、尽量直,避免绕远。如果 FPGA 和 DSP 之间的控制信号走线很长,可以在 FPGA 侧做输出寄存,把时序关系拉直。
跨时钟域的接口线要格外当心。本地总线的时钟域和 XINTF 的时钟域不同,如果这两组信号在 PCB 上长距离并行走线,容易互相串扰,导致其中一侧偶发采样错误。分组的时候把两组信号在空间上分开,中间用地线或者地平面隔开。
4.4 电源平面分割与去耦电容摆放
四层板的典型叠层是顶层信号、内层地、内层电源、底层信号。电源平面做分割的时候,要按电源域划分清楚,分割边界要留出足够的间距,避免不同电源域靠得太近产生耦合。分割的宽度要保证电流密度不超过铜箔的承受能力,大电流路径要留足够的铜宽,必要时用多个过孔并联。
去耦电容的摆放原则是"就近、短回路"。电容的一端接电源管脚,另一端接地,两者的回路面积要小。做法是把电容放在芯片背面对应的位置,电源引脚直接打过孔到电容焊盘,再短距离打到地平面上。电容的电源过孔和地过孔要尽量靠近,减少回路电感。大容量储能电容可以放在稍远的位置,但也要保证电流路径短而宽。
实际经验里有一个容易被忽略的细节:BGA 芯片背面的去耦电容会和信号过孔抢空间。所以在 BGA 扇出规划阶段就要把电容位置一起考虑进去,预留出足够的区域。如果做完了扇出才发现电容放不下,只能把电容挪远,效果大打折扣。
4.5 金手指区域的特殊处理
金手指部分有几个硬性要求。板厚要符合规范,太厚插不进去,太薄接触不良。金手指的倒角要按规定做,通常是在插入端做一个斜切,便于插拔并对准。金手指区域的正反两面都要做,且不能铺铜、不能走线,只能保留金手指本身和必要的连接走线。
金手指的走线要尽量短,尤其是 PCIE 的几对差分信号,从金手指到桥片的走线越短越好,中间不要有过多过孔和绕行。参考时钟差分对也要按同样的规则处理。金手指区域的丝印要避开接触面,避免印料影响接触。
还有一个工艺细节:金手指通常需要做特殊表面处理,保证耐磨和低接触电阻,这个要和板厂沟通清楚,用常规喷锡工艺做金手指是很容易出问题的。
4.6 PROTEL99 的规则设置与 DRC
99SE 的规则系统虽然简单,但基本够用。布线前至少要设置好几类规则:安全间距,根据工艺能力设定;线宽,按信号类型分别设定,电源和地要单独加宽;过孔尺寸,统一到板厂能做的范围;短路检查,必须开启。
差分线在 99SE 里没有专门的规则,只能靠命名约定加手工操作。建议把差分网络按固定后缀命名,布线时用查找功能批量选中,然后统一设置线宽和间距。等长用 Tools 菜单里的长度匹配功能,先在规则里设定好目标长度,再执行。
DRC 跑完之后,重点看几类报错:间距违规,判断是真的违规还是可以接受的;未布线网络,一条都不能放过;短路,必须查清。另外 99SE 的 DRC 对某些跨层的情况检查不充分,重要的差分线和电源网络建议手工再核对一遍,别完全依赖工具。
5. 常见问题与排查技巧实录
5.1 链路训练失败的排查路径
板子插上主机之后,如果系统根本识别不到设备,或者识别到了但报错,第一步是确认金手指接触是否良好,换一个插槽试试,排除机械接触问题。第二步用示波器或者差分探头测 PCIE 参考时钟,确认 100MHz 差分时钟存在、幅度正常、波形干净。这路时钟如果来自主板,要确认主板这个插槽是否真有时钟输出。
如果时钟正常但还是识别不到,就要怀疑差分信号本身。这时候可以用 TDR 测差分线的阻抗,看看是不是偏离太多;也可以用高速示波器观察链路训练时发送的差分信号,看幅度和眼图。很多情况下问题出在参考平面不完整或者对内不等长上,改板之前可以先确认这两个点。
还有一种常见情况是复位信号的问题。PCIE 侧的复位信号如果电平不匹配或者时序不对,桥片会一直处在复位状态,表现就是完全没反应。这时候测一下复位引脚的波形,确认它在链路上电之后被正确释放。
5.2 本地总线读写异常的定位方法
链路通了、驱动装上了,但读写数据不对,这时候问题多半在本地总线或者 FPGA 逻辑上。定位方法是从简到繁:先写一个固定的测试寄存器,往里面写一个固定值再读回来,确认最基本的读写通路是通的。如果不通,用逻辑分析仪抓本地总线的波形,看读写周期有没有正常发出、地址对不对、数据有没有被驱动。
如果基本读写通了但批量传输有问题,重点查 FIFO 的状态逻辑和 DMA 配置。常见的坑是 FIFO 的空满标志和实际数据量不一致,导致数据被截断或者重复。还有一个坑是 DMA 的传输长度寄存器和实际配置不匹配,比如单位是字节还是双字搞混了。
DSP 侧读写异常的话,先确认 XINTF 的时序配置是否足够宽松,可以用软件方式把等待周期调到明显偏大,看问题是否消失。如果消失,说明是时序余量不够;如果依然存在,问题可能在 FPGA 逻辑或者两侧的握手协议上。这个"放宽参数看现象是否改变"的思路,能快速把问题在时序和逻辑之间分开。
5.3 枚举与空间映射类问题
主机枚举阶段的问题通常和 EEPROM 配置有关。如果 BAR 申请不到空间,或者申请到的空间大小和预期不符,先检查 EEPROM 里的配置内容。可以采用的办法是:先用默认配置让卡能被识别成一个通用设备,确认物理链路和枚举流程没问题,再逐步调整成目标配置。这样能把"物理链路问题"和"配置内容问题"分开,避免两头一起查。
地址映射的问题也很常见。桥片的本地总线地址和主机侧的地址之间要做映射,映射关系配置错了,主机会把数据写到错误的本地地址上去,表现为数据"丢了"或者"写到了别的地方"。调试时可以把映射关系简化成一对一,先跑通再改。
5.4 99SE 使用过程中的坑
99SE 在 Windows 新版本系统上运行需要一些兼容性处理,建议在虚拟机或者兼容模式下跑,避免出现保存失败、文件损坏这类问题。文件路径不要太深,也不要用中文路径,否则容易出现打不开或者保存异常。
规则设置方面,99SE 不支持按类设置复杂规则,很多约束要靠手工。建议自己在工程目录下维护一份检查清单文档,每次布线完成后逐条核对。原理图和 PCB 之间的同步也是一样,网表更新之后要仔细核对有没有元件被误删或者重命名。
还有一个很实际的坑:99SE 的自动保存和撤销功能都不太可靠,大板子的操作建议频繁手动保存,并且定期另存一个版本。改板的时候保留几个历史版本,出问题还能回退。这些习惯看着土,但真能救命。
6. 打样、焊接与上电验证顺序
6.1 上电前的静态检查
板子回来之后,第一件事不是上电,而是目视加万用表检查。重点看几个地方:各个电源网络对地是否短路,尤其是核心电压这种低电压大电流的电源,短路了上电就是一缕烟;芯片有没有明显的焊接缺陷,BGA 尤其要检查是否虚焊、桥接;金手指有没有氧化或者损伤。
BGA 焊接质量在目视下很难判断,有条件的话用 X 光检查一遍,尤其是桥片和 FPGA 这两颗。如果没有 X 光设备,至少要确认焊接厂有 BGA 返修能力,出问题能修。
6.2 分级上电与波形验证
上电要分级。先只上主电源,测各路电压是否正常、纹波是否在允许范围内,确认之后再上核心电压。如果电源有上下电顺序要求,要用示波器看几路电源的上升沿时序是否符合要求。
电源正常之后,先测时钟。三路时钟都要测:PCIE 参考时钟、本地总线时钟、DSP 主时钟。测的时候注意探头的接地要短,用弹簧地针而不是长引线,否则测出来的波形全是环路耦合进来的噪声。时钟幅度、频率、占空比、抖动都要看一下。
然后是复位。确认所有复位信号在上电后都被正确释放,释放的时刻和时钟稳定的时刻之间的关系要合理。这一步做好了,后面调试会顺利很多。
6.3 联调顺序与经验总结
联调建议按链路顺序推进,不要跳步。先单独给板子供电,确认 FPGA 能配置成功、DSP 能跑起来最基本的程序(比如翻转一个 IO),这一步不涉及 PCIE,最容易验证。然后插到主机上,不装驱动,先在系统设备列表里确认设备能被枚举出来。这一步过了,说明物理链路和最基本的配置没问题。
接着装驱动,做最简单的寄存器读写测试。再往后是 DMA 传输测试,从小数据量开始,逐步加大到满带宽,同时用逻辑分析仪观察本地总线上的实际活动。最后才是把 DSP 拉进来,做三方联调。
这一路走下来,我在实际项目里体会最深的是两点。一是所有"暂时先这么接"的地方,最后都会变成调试时最头疼的问题,尤其是电源和复位这种基础网络,省事一时,还债很久。二是逻辑分析仪和示波器不是出问题才用的,而是每推进一步都用它确认一次实际波形,把"我以为是这样的"变成"我看到了是这样的"。这块板子涉及三个不同的时钟域和两种总线协议,靠猜是猜不出来的,老老实实测,比什么都快。
后续如果要扩展,我一般会建议在这个框架上加一版:把 FPGA 到 DSP 的接口从单 Zone 扩展成双 Zone,一个走命令、一个走数据流,减少相互阻塞;同时在本地总线侧加一个片外的 SRAM 或 FIFO 做深缓冲,让突发数据的吸收能力更强。这些改动不大,但对手头任务多的项目来说,边际收益很明显。