
1. Design Editor 在紫光同创FPGA流程中的真正位置1.1 综合、实现、位流Design Editor卡在哪一步很多刚接触紫光同创FPGA开发的人会把PDSPango Design Suite当成一个“写完代码点一下就能出比特流”的黑盒子。RTL写完之后跑综合、跑实现、生成位流、下载到板子上看起来一气呵成。但一旦遇到时序收敛不过、资源利用率奇高、板级信号乱跳这类问题黑盒子就变成了一团迷雾。实际上PDS的完整流程大致是这样的RTL综合Synthesis把Verilog/VHDL变成网表然后进入实现Implementation阶段。实现阶段又分为映射Map、布局Place和布线Route三个子步骤。布局负责把网表中的LUT、FF、BRAM、DSP等单元放到FPGA内部的物理位置上布线负责把这些物理位置用可编程互联资源连起来。而Design Editor就是紫光同创PDS里承担“布局布线结果可视化查看与手动编辑”的图形化工具。说得直白一点自动布局布线是工具替你做了绝大多数工作Design Editor是让你在自动结果不满意的时候能够打开芯片内部图自己动手挪一挪、连一连、看看问题到底出在哪。它有点像PCB设计里的Layout软件只不过对象从元器件变成了FPGA内部的逻辑单元和布线通道。这里要澄清一个常见的误区Design Editor不等于“必须手动布局布线才能用”。绝大多数设计靠自动布局布线都能完成手动介入是一种调试手段、优化手段而不是必经流程。我见过一些初学者一上来就在Design Editor里到处拖拽逻辑单元结果越拖越乱时序反而更差。正确的思路是先用自动布局布线跑出版本再用时序报告和资源利用率数据判断问题最后才在Design Editor里做有针对性的调整。1.2 什么情况下才需要手动介入根据我实际用下来的经验遇到下面这几类情况才真正值得打开Design Editor手动操作关键路径时序收敛困难自动布局布线跑完之后时序分析报告显示某几条路径的建立时间裕量Setup Slack为负而且差距不大就差那么几十皮秒。这时候手动把路径两端的逻辑单元拉近往往能救回来。局部拥塞严重某个区域的LUT和FF占用率已经超过90%布线通道挤成一团。自动工具在这个区域里绕来绕去都绕不开手动把一部分逻辑搬到资源空闲的区域效果立竿见影。有特殊物理位置需求比如某个高速接口需要靠近特定的IO Bank或者某个模块要求放在某个时钟区域的中心位置。这类需求在约束文件里写起来比较抽象在Design Editor里直接看图形、直接摆放直观得多。排查信号完整性与跨die问题多die封装的器件里die间的布线资源是有限的。用Design Editor看跨die路径走线能清楚地发现问题是出在die间跳转过多还是某个die内拥塞。除开这些日常开发中我并不推荐动它。自动布局布线工具的综合优化能力在绝大多数场景下是优于人手操作的盲目手动干预只会浪费时间。Design Editor的价值在于“精准手术”而不是“常规体检”。2. 上手第一步把两个透视图的关系先搞清楚2.1 器件视图芯片内部的棋盘格第一次打开Design Editor的人大概率会被满屏的彩色小格子吓到。这是它的器件视图Device View也是平时最常用的一个视图。你可以把它理解成一张芯片内部结构的“卫星照片”上面的每个格子都对应FPGA内部真实的物理资源。器件视图里芯片被分成了若干个行列网格。每一行每一列交叉的区域是一个可配置逻辑块CLBCLB里面主要有LUT和FF。除此之外还有固定位置的BRAM、DSP、IO块、时钟管理单元PLL/MMCM等资源。不同资源类型在视图里用不同的颜色区分比如BRAM通常是一种颜色DSP是另一种颜色IO和时钟资源又是别的颜色。把鼠标悬停到某个格子上能看到这个格子的坐标、资源类型、当前被占用的逻辑单元名称。紫光同创的器件命名和资源排布在不同系列上略有差异比如Logos系列的资源布局和Titan系列就不完全一样。但它们的共同点是整个芯片以时钟区域Clock Region为基本分区单位每个区域内部的布线资源是相对独立的跨区域的走线需要经过特定的时钟区域边界。理解了这层结构你才能明白为什么“把逻辑挪到一起”能显著改善时序——因为跨区域的走线延迟远大于区域内走线。2.2 封装视图管脚与bank的“物理地图”器件视图旁边一般会有封装视图Package View。这个视图展示的是芯片封装后的管脚分布从顶视图看过去芯片外围一圈是密密麻麻的焊盘按bank分组排列。封装视图和器件视图之间是有关联的。IO逻辑单元在器件视图里有它的物理位置对应的封装管脚在封装视图里有它的引脚编号。当你给某个信号分配了物理管脚之后可以在封装视图里直接看到这个管脚落在哪个bank、哪个位置、和相邻管脚的距离。对做板级验证的人来说这个视图特别有用——它能让你直观地确认差分信号的P/N管脚是否配对时钟管脚是否落在了正确的时钟专用引脚上IO管脚和相邻管脚的间距是否会导致信号串扰风险。我自己的习惯是在写管脚约束之前先在封装视图里把要用的管脚挨个看一遍确认它们所在bank的VCCO电压标准匹配再回PDS工程里写约束。这能避免不少低级错误比如把3.3V的bank和2.5V的bank搞混。2.3 几个高频使用的视图操作技巧Design Editor和大多数EDA工具一样基本操作是鼠标滚轮缩放、按住滚轮或右键拖动平移。以下几个技巧是我用得最多的按资源类型筛选显示在视图上方的筛选器里可以勾选/取消勾选显示LUT、FF、BRAM、DSP、IO等资源类型。当整个芯片的资源密密麻麻看不清楚时只显示某类资源会让你瞬间抓住重点。按网表单元搜索定位Design Editor支持按网表里的实例名Instance Name搜索定位。比如我想找UART接收模块里的rx_dly_reg这个寄存器直接在搜索框输入名称视图会自动跳转到它所在的物理位置并高亮。这个功能在排查特定信号时极其高效。显示布局结果和布线结果切换布局完成之后视图里显示的是所有逻辑单元的物理位置布线完成之后视图里显示的是金属走线。先看布局再看布线能清楚地判断一个时序问题到底是“摆得远”还是“绕得远”——两者是完全不同的优化方向。3. 手动布局以一条跑不过时序的关键路径为例3.1 在网表里找出要搬移的逻辑和资源手动布局的第一步不是打开Design Editor乱点而是在网表里锁定目标。我一般会先跑一遍布局布线然后打开时序报告找一条最关键的违规路径记下这条路径的起点和终点实例名。比如起点是一个FF终点是另一个FF中间经过了两级LUT。在Design Editor的网表视图或者叫层次视图里展开对应的模块层次找到这些实例。这里有一个前期经验的总结选择要搬移的逻辑单元时不要只看路径上的起点和终点要把整条路径经过的所有组合逻辑一起选中。因为布局优化是“一荣俱荣一损俱损”的你把起点和终点拉近了中间的组合逻辑却留在原地布线照样要绕一大圈延迟根本没降下来。选中方式有两种一种是按住Ctrl键逐个点击要搬移的单元另一种是在网表视图里选中某个模块然后右键选择“选中该模块的所有物理单元”整个模块的LUT、FF就会全部高亮。模块整体搬移的粒度比较粗但胜在效率高适合模块本身在芯片上分布太散的情况。3.2 移动、对齐、固定一次完整的布局操作选定目标之后就可以开始搬移了。在Design Editor里移动逻辑单元的通用操作是鼠标左键选中单元或单元组然后按住鼠标左键拖拽到目标位置释放后工具会尝试把单元放到最近的合法位置。如果目标位置已经被占用工具会给出提示你需要换一个位置或者先搬走占用的单元。搬移过程中有几个细节特别值得注意尽量保持相对位置不变多个单元一起搬移时让它们保持原有的相对排列关系这样逻辑内部的走线长度基本不变只是整体挪了个地方。不要在搬移过程中随便重新排列那样会破坏原本已经优化的内部连接引入新的布线延迟。贴着目标资源放如果这条路径最终要接到一个DSP或BRAM上把整条路径的逻辑搬到紧邻该DSP/BRAM的位置。绝对不要隔着一大片空白区域搬否则路径内的走线是短了但和DSP的连接又变长了。留意时钟资源的位置FPGA内部时钟信号走的是专用的时钟网络不是普通布线资源。搬移逻辑时要确保逻辑仍处于所属时钟信号能够到达的时钟区域范围内。一旦搬到了时钟覆盖区域之外布局工具会报错或者后续布线时被迫消耗宝贵的全局时钟资源去绕路。搬移完成之后一般还需要对单元做对齐微调。Design Editor提供了对齐工具可以选中一组单元将它们按上边缘、下边缘、左边缘、右边缘或中心对齐。这个操作主要是为了让布局看起来更整齐对性能的影响不如位置选择大但整齐的布局会让后续布线更容易也方便你自己检查。3.3 搬完之后必须检查的三个地方手动搬移布局之后不能直接点保存就完事。我每次都会按照下面三个步骤做一遍检查确认没有问题再继续跑布线第一检查布局合法性。在Design Editor里有一个DRC检查或者叫布局规则检查运行一遍看有没有单元被放到了非法位置有没有逻辑单元超出了所在CLB的容量限制有没有出现资源重叠。这一步必须做否则跑到布线阶段报错回头再改更麻烦。第二检查拥塞变化。搬移逻辑之后目标区域的资源占用率会升高原来的区域占用率会降低。在视图里打开资源利用率分布图确认目标区域没有出现新的拥塞点。如果目标区域本来就已经占用80%以上了那就需要换一个更空的区域或者缩小搬移范围。第三检查时钟和复位的扇出范围。搬移后的逻辑单元它的时钟信号仍然来自原来的时钟网络。虽然大多数情况下时钟网络覆盖率足够但当你把逻辑搬到芯片边缘或者某个死角时最好确认一下这个位置仍然在时钟网络的覆盖范围内。同理异步复位信号的走线如果过长也容易引起复位释放时的竞争问题。4. 布线调整拆线、重布与拥塞判断4.1 布线资源和拥塞现象布局完成之后布线就是下一步。FPGA里的布线资源不是无限的芯片上有一定数量的水平走线通道和垂直走线通道分布在行列之间。这些走线通道按照长度分为不同类型有的只连接相邻单元有的跨越几个CLB有的横跨整个芯片。布线工具的任务就是为每一条逻辑连接找一条由这些走线拼接而成的路径。当某个区域内需要连接的信号数量超过走线通道容量时就出现了拥塞Congestion。拥塞的直接后果是布线工具只能绕远路导致信号延迟剧增甚至在某些极端情况下出现布线失败。在Design Editor里判断拥塞最直观的方式是看布线资源密度图。紫光同创的布线视图通常会用颜色标注拥塞程度绿色表示空闲黄色表示紧张红色表示拥塞。如果你在某个区域看到大面积红色基本可以判定这里就是布局时需要疏散的重点区域。4.2 交互式布线的正确打开方式布线的调整方式和布局很不一样。布局是对单元位置的调整布线则是对信号走线的调整。Design Editor里针对某一条具体网络你可以拆掉它现有的布线然后手动选择走线路径。我常用的做法是先在网表视图或器件视图里选中一个高扇出的关键信号网络右键选择“显示布线”让这条信号的全部走线高亮显示出来。这时候你能清楚地看到它从起点出发经过哪些布线通道到了哪些终点。如果发现这条信号绕了很大一个弯或者经过了一段明显拥塞的区域就选中该网络先执行拆线操作再手动指定一条更合理的路径。手动指定路径的操作本质上是利用Design Editor里“锁定布线路径”的功能。你点击起点工具会自动指导你沿着合法的走线通道拖拽到终点过程中会自动避开已经被占用的通道。这条路径一旦锁定后续执行自动布线时工具会优先保留你的手动路径只在必要时才调整。但我要提醒一点手动布线一定要慎用。FPGA内部的布线通道关系极其复杂你以为手动指定了一条“更近”的直线路径实际上可能绕了几个弯或者占用了其他关键网络的必经通道。我个人的原则是只在以下两种情况下手动布线——一是某条关键网络已经被拥塞挤得绕了太远二是需要保证某条高速信号走特定的延迟路径。其他情况交给自动布线工具它在全局优化上永远比你一个人脑强。4.3 布线长度、扇出与延迟怎么看才靠谱布线长度和信号延迟的关系很多人以为是一条直线距离越长延迟越大。其实不完全对。FPGA的走线延迟由两部分组成一部分是走线本身的物理长度带来的传输延迟另一部分是走线经过的每个开关节点可编程互联开关带来的开关延迟。打个比方这就像开车从A到B直线距离近但路上要经过十几个红绿灯反而比绕一条没有红绿灯的远路更慢。所以判断一条信号快不快不能只看布线长度还要看路径上经过了多少个可编程开关节点。Design Editor在显示布线路径时一般会显示每一段的延迟估算值和开关节点数用这个数据来判断才算对症。扇出Fanout也是一个要留意的因素。一个信号驱动越多的终点它的布线就越复杂延迟也越大。在Design Editor里选中一个高扇出网络时你能看到一条信号从源头出发像树杈一样分到多个目的地。这时候单纯手动布线很难改善因为问题不在走线路径而在驱动能力。合理的做法是回到RTL层面对高扇出信号做复制或插入缓冲器这是另一个话题了但你在Design Editor里看到这个现象时要能判断出问题的根因在哪一层。5. 和时序报告连起来用才能真正收敛5.1 时序报告里每一段延迟对应芯片上的哪段距离时序分析报告里一条路径的延迟通常分成两大类逻辑延迟Logic Delay和布线延迟Route Delay。逻辑延迟是信号经过LUT查找表、进位链等逻辑资源本身的时间布线延迟是信号在金属走线和开关节点上花费的时间。打开时序报告看一条关键路径里面会列出信号从起点FF经过的每一个节点先经过FF的时钟到输出延迟Tco再经过第一级LUT的逻辑延迟然后是一段布线延迟再到第二级LUT又是一段布线延迟最后到达终点FF的建立时间要求Tsu。把这些节点和Design Editor里的物理位置对照起来看你就能知道自动布局布线工具为这条路径选了一条什么样的物理路线哪一段布线绕远了哪一级LUT和下一级LUT之间隔了太远。这才是手动布局布线优化的真正依据。盲目的搬移、拆线重布不如先看时序报告确定瓶颈在哪一段再针对性地调整。我以前做过一个设计有一条路径总是差100ps的时序不合格。时序报告里看逻辑延迟占了大头布线延迟反而不高。这说明问题不在位置远近而在逻辑级数太多。这种情况下再怎么在Design Editor里挪位置都是徒劳正确做法是回RTL改逻辑结构减少级数。反过来如果布线延迟占大头那就值得在Design Editor里做布局和布线的调整。5.2 用关键路径高亮直接定位“拐弯过多”的网络PDS的时序分析工具和Design Editor之间一般有联动功能。你可以在时序报告里选中某条违规路径然后右键选择“在Design Editor中高亮”视图会自动聚焦到这条路径涉及的物理单元上并且把单元之间的连接关系用线画出来。这个功能我几乎是每次时序收敛必用。高亮之后观察路径的走线形态很容易发现两类问题第一类是路径整体走向呈Z字形或S形。比如信号从一个区域的左上角出发先跑到右下角再绕回右上角。这种走线说明自动布线工具在某个位置遇到了拥塞只能绕路。这时候最优解往往是把路径沿线上的逻辑单元重新摆放而不是手动去拆线重绕。第二类是路径两端其实离得很近但中间经过的开关节点特别多。这种情况说明虽然没有绕远路但走线通道选得不好经过了太多层次切换。这时候可以考虑手动拆掉这条线重新指定一条经过较少开关节点的路径或者提升这条网络的布线优先级让自动布线工具下次优先为它分配好的通道。5.3 布局布线的约束文件与迭代策略手动布局布线的结果最终要固化下来不能每次重新编译就被自动布局布线覆盖掉。在PDS工程里布局布线的物理约束通常会写入到约束文件里。Design Editor里完成的布局操作保存时会生成对应的位置约束手动锁定的布线路径也会保存为布线约束。这里有一个经验教训保存布局布线约束之后一定要在重新执行布局布线之前确认约束文件已经被正确引用否则跑完自动布局布线你之前辛辛苦苦手动调好的位置全部被覆盖白干一场。另外手动布局布线不要指望一次到位。我通常是采用“小步迭代”的策略第一次先调整一条最关键的路径保存约束然后重新跑布局布线看时序报告评估效果。如果改善了再继续调整下一条路径如果恶化了就用版本管理工具回退分析原因。一次手动调整太多路径出问题了完全分不清是哪个改动引起的排查起来非常痛苦。6. 实战避坑清单这些错误我基本都犯过6.1 布局结果存不住重新实现后全部还原新手最常遇到的一个坑是在Design Editor里辛辛苦苦把逻辑挪好了位置结果重新跑一遍布局布线发现所有逻辑又回到了原来的位置。这个问题十有八九是因为没有把布局结果保存成约束文件或者在工程设置里没有启用物理约束。紫光同创的PDS和主流FPGA工具一样默认情况下的自动布局布线会忽略手动布局结果除非你明确把它们写入约束文件。所以在Design Editor里做完调整之后一定记得保存布局约束并在工程设置里确认这些约束参与实现。如果你用的是版本管理顺手把约束文件也提交上去避免团队协作时其他人拉代码拉到一份没有约束的版本。6.2 按“看起来近”摆放结果越摆越差这个坑我栽过不止一次。有时候觉得一段逻辑放在A位置和B位置看起来距离差不多就随手放到了B位置。结果跑完布线路径延迟反而增加了。原因在于FPGA内部的走线不是所有区域都能等价的水平垂直穿梭。有些区域被BRAM、DSP这些大块资源占据走线通道本来就少穿过这些区域时反而要绕更远的路。正确的姿势是摆位置之前先打开布线资源分布图看看目标区域的走线通道是富裕还是紧张。宁可多花一分钟观察也好过跑完实现花一小时排查为什么延迟变高了。6.3 忽略了时钟与复位的专用通道FPGA内部有一类特殊的布线资源叫全局时钟网络Global Clock Network和局部时钟网络Regional Clock Network。它们是专门为时钟、复位这类高扇出、对skew敏感的信号准备的。普通信号走不了这些专用通道但时钟信号如果走了普通布线资源偏斜Skew会非常大直接导致时序崩溃。在Design Editor里手动布局时有一个隐藏的坑搬移逻辑时没有意识到该逻辑的时钟信号来源于哪个时钟网络搬到了时钟网络覆盖区域之外。这时候工具不一定马上报错但布线完成后时序分析会出现极其异常的skew和路径延迟。所以每次布局调整之后我会专门检查一下关键逻辑的时钟网络覆盖范围确保自己没把逻辑搬到“时钟盲区”。6.4 不规范的检查与核对遗漏Design Editor里手动调整完我最后强制自己走一遍固定的退出检查流程顺序如下运行一遍完整DRC确认无物理规则违例。保存布局/布线约束确认约束文件被工程正确引用。重新跑一遍布局布线对比调整前后的时序报告和资源利用率报告。检查输出网表里手动约束的数量和位置确认它们确实被采纳了。最后回到顶层原理图或模块层次确认调整没有影响未预期的模块。这套流程看起来繁琐但真的能拦住几乎所有的低级错误。尤其是第4步我吃过一次大亏保存的约束格式里写错了一个实例名的层级路径导致约束无效但工程并没有明显报错只是布局结果没变。我当时没仔细核对白白浪费了两天排查时间。现在每次都会强制检查一遍。用Design Editor做手动布局布线本质上是一个“用工具看得懂芯片内部结构”的技能。紫光同创的FPGA器件虽然在资源排布和工具细节上和国外主流器件有所不同但底层逻辑是相通的。建议新手先拿一个小设计练手把自动布局布线的结果打开对照着资源分布图和时序报告亲手拖一拖、挪一挪那些逻辑单元感受一下位置变化对布线延迟的影响。多试几次你就能建立起“时序报告中的数字”和“芯片上的物理距离”之间的直觉。这个直觉比任何工具技巧都值钱。