
1. 重复模块为什么值得单独花时间研究画PCB这件事最耗神的往往不是布线本身而是那些一模一样却要画很多遍的电路。电源入口的滤波网络、以太网PHY的匹配电路、DDR的某一组数据线、几路一模一样的运放通道、多路继电器驱动……这些模块在原理图上可能只是复制粘贴但在PCB里每一路都要重新摆放器件、重新走线、重新铺铜、重新打孔。如果板子上有8路相同的通道你就要把这套动作重复8次而且每次手抖一下走线长度、过孔位置、铜皮间距就可能不一致最后调试的时候信号完整性问题找上门你都不知道是哪一路的锅。Allegro里其实内置了一个专门解决这个问题的功能叫Place Replicate布局复制配合模块复用Module Reuse的思路可以把一个已经调好的模块完整克隆到板上的其他位置器件位置、走线、过孔、铜皮、甚至丝印都能一起搬过去。这个功能在Cadence的文档里一直有但很多画了几年板子的朋友居然没用过或者用过一次觉得不好使就放弃了。问题通常不在功能本身而在于没搞清楚它的工作前提和边界条件。这篇内容适合三类人看一是手上正在画多通道板子、被重复劳动折磨的PCB工程师二是听说过Place Replicate但一直没跑通的初学者三是想把这套流程固化下来、做成团队规范的人。我会把整个操作链路拆开讲包括前置准备、模块创建、复用执行、常见报错的处理以及什么时候该用Skill脚本兜底。所有步骤都基于Allegro 17.4这个目前装机量很大的版本16.6的操作逻辑基本一致差异我会单独点出来。先说结论Place Replicate用好了一块8通道的板子模块复用部分的工作量能从两天压缩到两小时以内而且一致性是机器保证的不依赖人的手感。但它的前提是——你得先把源模块做对并且理解它到底复制了哪些东西、不复制哪些东西。下面从原理开始拆。2. Place Replicate到底复制了什么又不复制什么2.1 它复制的对象是物理布局信息不是逻辑连接很多人第一次用Place Replicate会有一个误解以为它是把原理图上的某个模块同步到PCB。不是的。它操作的对象是已经存在于PCB中的一组器件及其物理属性。也就是说你必须先在PCB里手动把第一个模块摆放、布线、铺铜全部做好然后告诉Allegro这一坨东西是一个模板请把它复制到那边那几个器件上。它复制的内容包括器件的相对坐标相对于模块内某个基准器件器件的旋转角度和镜像状态器件之间的走线clines路径过孔vias的位置和类型铜皮shapes的形状和网络归属丝印文字的位置如果丝印在模块内器件的固定属性fixed属性它不复制的内容网络连接关系net逻辑——这是原理图决定的Place Replicate只认物理位置器件的封装本身——目标位置的器件必须已经存在且封装与源器件兼容设计规则constraints——规则是全局的不随模块走层叠结构——这是板级设置理解这个边界非常关键。因为Place Replicate的本质是物理布局的模板匹配它要求源模块和目标模块的器件类型和数量必须一一对应。比如源模块有1个电阻、1个电容、1个IC那目标模块也必须是1个电阻、1个电容、1个IC而且封装要能对上。如果目标模块多了一个器件或者封装不同匹配就会失败。2.2 匹配的底层逻辑器件标识与相对位置Allegro怎么知道源模块里的R1应该对应目标模块里的R5而不是R6它靠的是器件标识refdes的匹配规则和相对位置关系。在创建模块Create Module的时候Allegro会记录模块内每个器件相对于模块原点的坐标。在复用Place Replicate的时候它会尝试在目标区域找到一组器件其相对位置关系与源模块一致然后按这个对应关系把物理信息搬过去。这里有个坑如果你的目标模块器件摆放得乱七八糟相对位置和源模块差异太大Allegro可能匹配不上或者匹配错。所以实操中我通常建议先把目标模块的器件大致按源模块的方位摆一下哪怕只是粗略地对齐也能大幅提高匹配成功率。这一点官方文档不会强调但是实战经验。2.3 为什么有时候复制过去的走线会断这是新手最常遇到的困惑模块复用执行完了器件位置对了但走线是断的或者铜皮没跟过来。原因通常有三个第一目标模块的器件没有全部被选中。Place Replicate需要你明确指定哪些器件属于目标模块如果漏选了一个那个器件的走线就找不到归属自然断掉。第二源模块的走线跨越了模块边界。如果源模块里有一根线从模块内连到模块外这根线在复制时会被截断因为模块外的部分不属于模板。解决办法是把这类跨边界的线在创建模块前就处理好或者接受它断掉后手动补。第三铜皮的网络归属在目标位置不存在。比如源模块里有一块GND铜皮但目标位置附近没有GND网络铜皮就铺不上。这个要在复用前确认目标区域的网络环境。提示创建模块前先把源模块的DRC跑一遍确保没有未连接的线、没有孤岛铜皮。带着问题创建模块问题会被一起复制过去而且更难排查。3. 从零跑通一次模块复用的完整操作链路3.1 前置准备让源模块干净且完整在动手创建模块之前有几件事必须先做否则后面会反复返工。第一确认源模块的器件已经全部摆放并布线完成。包括走线、过孔、铜皮、丝印。如果模块内有需要包地的结构包地也要做好。因为一旦创建成模块再想改源模块就得重新创建之前复用出去的实例不会自动更新这一点和某些EDA工具的模块联动不同Allegro的Place Replicate是一次性快照。第二给模块内的器件加上固定属性Fixed。这一步很多人省略但强烈建议做。固定属性可以防止在后续操作中误移动模块内的器件导致模板失效。操作是选中器件右键选择Fix或者在Find面板勾选器件后统一Fix。第三确认模块的基准点。创建模块时会让你指定一个原点origin通常选模块内最角落的一个器件或者模块的几何中心。基准点的作用是定义模块的坐标系复用的时候目标模块会以对应的器件为基准对齐。我习惯选模块内那个最不容易动的器件比如连接器或者主IC。第四检查模块内是否有跨边界的网络。前面说过跨边界的线会被截断。如果模块内有一根线必须连到模块外建议在创建模块前先把这根线删掉复用完成后再手动补。或者把这根线纳入模块但那样模块的边界就扩大了目标模块也要包含对应的器件。3.2 创建模块Create Module的正确姿势准备工作做完开始创建模块。第一步在Allegro的菜单栏找到Place → Create Module17.4里在Place菜单下16.6可能在Tools菜单下路径略有不同。第二步在弹出的对话框里Module name填一个有意义的名字比如PWR_FILTER_01。不要用默认的module1因为后面复用的时候你要在一堆模块里找它名字清晰能省很多事。第三步Origin选择模块的基准点。可以直接在板上点选也可以输入坐标。我通常点选模块内那个主器件的1脚位置。第四步框选模块内的所有器件。注意要框选完整包括走线、过孔、铜皮、丝印。如果漏了铜皮复用出去的模块就没有铜皮。框选的时候建议用Window模式从左上到右下框确保包含所有元素。第五步确认后Allegro会生成一个.mdd文件Module Definition默认保存在当前工程目录下。这个文件就是模块模板后面复用的时候会调用它。注意.mdd文件是二进制格式不能直接编辑。如果模块需要修改只能重新创建覆盖原文件。所以创建模块前一定要确认源模块是最终状态。创建完成后你可以通过Place → Place Replicate来验证模块是否被正确识别。如果模块列表里能看到你刚创建的名字说明创建成功。3.3 复用模块Place Replicate的执行细节复用是重头戏步骤不难但细节多。第一步Place → Place Replicate在弹出的对话框里选择你刚才创建的模块比如PWR_FILTER_01。第二步Allegro会提示你选择目标器件。这时候在板上框选目标模块的所有器件。框选的范围要和源模块的器件集合一一对应。比如源模块有R1、C1、U1目标模块有R5、C5、U5你就框选R5、C5、U5。第三步Allegro会自动进行匹配。如果匹配成功你会看到目标模块的器件瞬间移动到与源模块相同的相对位置走线和铜皮也一起出现。如果匹配失败会弹出错误提示常见的有Cannot find matching component目标器件集合与源模块不匹配检查器件数量和封装。Module origin not found基准点对应的器件在目标集合里找不到检查基准器件是否被框选。Net not found铜皮或走线的网络在目标位置不存在检查网络环境。第四步匹配成功后手动检查一遍。重点看三处走线是否连续、铜皮是否完整、丝印是否重叠。Place Replicate不是万能的有时候它会聪明反被聪明误把走线连到错误的网络上虽然概率低但发生过。检查的方法是打开飞线显示看是否有未连接的飞线。第五步如果一切正常把目标模块的器件也Fix住防止后续误动。3.4 一个完整的实操案例8路运放通道的复用假设你有一块板子上面有8路完全相同的运放电路每路包含1个运放IC、4个电阻、3个电容、1个反馈电容。手动摆8路每路按5分钟算就是40分钟还不算布线和铺铜。用Place Replicate流程是这样的先把第1路完整做好器件摆放、走线、铺铜、丝印全部到位。这一步花15分钟。把第1路的9个器件全部Fix。Create Module命名为OPAMP_CH基准点选运放IC的1脚。对第2路先粗略把9个器件摆到大致方位不用精确只要相对位置和源模块差不多。Place Replicate选OPAMP_CH框选第2路的9个器件。检查、Fix。重复第4-6步处理第3到第8路。实测下来第2路到第8路每路平均2分钟总共14分钟。加上第1路的15分钟整个8路模块的布局布线时间从40分钟压缩到30分钟以内而且一致性是100%。如果模块更复杂比如DDR的一组数据线有几十个器件节省的时间会更夸张。4. 那些让Place Replicate失灵的坑与排查思路4.1 器件封装不一致导致的匹配失败这是最常见的失败原因。源模块里的电阻是0402封装目标模块里有一个电阻是0603封装Allegro就匹配不上。因为Place Replicate要求器件的封装名称完全一致它不看器件的值比如10k还是4.7k只看封装。排查方法在创建模块前用Tools → Reports → Component Report导出源模块的器件清单确认封装。然后在目标模块框选后如果匹配失败逐个核对封装。如果确实有封装差异要么统一封装要么把那个器件排除在模块外单独处理。4.2 基准器件被Fix导致无法移动有时候匹配成功了但目标模块的器件没动。原因可能是目标模块的基准器件已经被Fix了。Fix属性会阻止器件移动Place Replicate也无法覆盖。解决办法是先把目标模块的器件Unfix复用完成后再Fix。4.3 铜皮网络在目标位置不存在源模块里有一块VCC铜皮但目标位置附近没有VCC网络铜皮就铺不上。这种情况通常发生在电源模块复用的时候。解决办法是在复用前先在目标位置铺一块临时铜皮赋予正确的网络然后再执行Place Replicate。或者接受铜皮不复制复用后手动铺。4.4 走线跨越模块边界被截断前面提过跨边界的线会被截断。如果你的模块设计里确实有跨边界的线建议在创建模块时把边界扩大把跨边界的那部分也纳入模块。比如源模块的线从模块内连到模块外的一个电阻那就把这个电阻也纳入模块。这样模块的器件集合变大了但复用的时候目标模块也要包含这个电阻匹配才能成功。4.5 模块文件路径丢失.mdd文件默认保存在工程目录下但如果你换了电脑或者移动了工程目录Place Replicate可能找不到模块文件。解决办法是在Place Replicate对话框里手动指定模块文件路径或者把.mdd文件放在一个固定的库目录下通过环境变量指向它。提示团队协作时建议把常用的模块比如电源滤波、以太网PHY、USB接口做成标准模块库统一放在服务器上通过环境变量MODULE_PATH指向。这样每个人都能调用不用重复造轮子。5. 当Place Replicate不够用时Skill脚本怎么补位5.1 Place Replicate的天然局限Place Replicate虽然好用但它有几个绕不过去的局限第一它是一次性快照。源模块改了已经复用出去的实例不会自动更新。如果板子上有8路模块源模块改了一个电阻的位置你得把8路全部重新复用一遍。第二它要求器件集合严格对应。如果目标模块的器件数量或封装与源模块有差异就匹配失败。这在一些近似但不完全相同的模块上很尴尬。第三它不处理网络逻辑。如果目标模块的网络连接和源模块不同比如源模块是VCC目标模块是VDDPlace Replicate不管它只搬物理位置。第四批量操作效率低。8路模块要手动执行8次如果板子上有32路手动操作就很烦。5.2 用Skill脚本实现批量复用自动更新Skill是Cadence的脚本语言可以操作Allegro的几乎所有对象。针对Place Replicate的局限可以写一个Skill脚本实现批量复用一次性把所有目标模块都复用不用手动一个个框选。自动更新源模块修改后脚本重新创建模块并重新复用所有实例。条件匹配允许目标模块的器件封装有差异脚本自动做映射。下面是一个简化的Skill脚本框架展示批量复用的思路; 批量复用模块的Skill脚本框架 ; 假设模块名为 OPAMP_CH目标模块有8路 procedure(batchReplicateModule(moduleName, targetGroups) let((moduleFile) ; 加载模块文件 moduleFile strcat(axlGetVariable(MODULE_PATH) / moduleName .mdd) ; 遍历每一路目标模块 foreach(group targetGroups ; 选中目标模块的器件 axlClearSelSet() foreach(comp group axlAddSelItem(axlSelectByName(COMPONENT comp)) ) ; 执行Place Replicate axlRunCommand(strcat(place replicate moduleName)) ; 检查结果 when(axlDBGetDesign()-drc-errors axlUIWPrint(nil, strcat(Module moduleName replicate failed on group)) ) ) ) )这个脚本的核心逻辑是先加载模块文件然后遍历每一路目标模块选中器件执行复用命令最后检查DRC。实际使用的时候需要根据你的板子结构定义targetGroups比如把每一路的器件refdes列成一个列表。5.3 什么时候值得写脚本不是所有场景都值得写脚本。我的判断标准是模块数量少于5路手动Place Replicate就够了写脚本的时间比手动操作还长。模块数量5-20路可以考虑写一个简单的批量脚本节省重复操作。模块数量超过20路或者模块需要频繁更新必须写脚本否则维护成本太高。另外如果模块的器件封装有差异或者网络连接有变化Place Replicate搞不定这时候Skill脚本几乎是唯一的选择。因为Skill可以读取器件的属性、网络、坐标然后按你的规则做映射和替换。5.4 一个实战中的脚本应用自动更新所有实例我做过一块板子有16路相同的驱动电路。项目中期硬件工程师改了一个电阻的位置要求所有16路同步更新。如果手动操作16路要重新复用16次每次还要检查至少半天。用Skill脚本流程是修改源模块重新Create Module。运行脚本脚本自动找到16路目标模块的器件集合通过器件名的前缀匹配比如DRV1_*到DRV16_*。脚本对每一路执行Unfix、Place Replicate、Fix。脚本跑完16路全部更新耗时不到2分钟。这个脚本的关键是器件集合的自动识别。我用的方法是给每一路的器件加一个自定义属性比如MODULE_GROUP值设为DRV1、DRV2……然后脚本通过属性筛选器件。这样即使器件位置变了脚本也能找到它们。提示Skill脚本调试的时候建议先在一个小板上测试确认逻辑无误再上大板。因为Skill脚本一旦跑错可能会把整个板子的布局搞乱撤销都来不及。6. 把模块复用做成团队规范几个落地建议6.1 建立标准模块库如果团队里经常画同类板子比如工控板、通信板建议把常用的模块做成标准库。比如模块名称包含内容适用场景PWR_FILTER_01输入滤波、TVS、保险丝所有板子的电源入口ETH_PHY_01PHY芯片、匹配电阻、变压器以太网接口USB3_01USB3连接器、ESD、共模电感USB3接口OPAMP_CH运放、反馈网络、去耦模拟通道标准模块库的好处是新人不用从头画直接调用老手不用重复劳动效率翻倍团队的一致性有保证不会因为不同人画法不同导致信号完整性问题。6.2 模块命名和版本管理模块文件.mdd建议用名称_版本的格式比如PWR_FILTER_01_v2.mdd。每次修改模块版本号加1旧版本保留。这样如果新版本有问题可以快速回退。另外模块文件建议放在版本控制里比如Git和PCB工程一起管理。这样模块的变更历史可追溯谁改的、改了什么、什么时候改的一目了然。6.3 模块复用的检查清单每次复用完成后建议按这个清单检查一遍[ ] 所有目标器件的位置与源模块一致[ ] 走线连续无断线[ ] 过孔位置和类型正确[ ] 铜皮完整网络正确[ ] 丝印无重叠方向正确[ ] DRC无新增错误[ ] 器件已Fix防止误动这个清单看起来简单但能挡住90%的低级错误。我见过太多人复用完不检查结果板子回来发现某一路的走线是断的调试的时候查了半天。6.4 什么情况下不建议用模块复用模块复用不是万能的。以下几种情况我建议手动处理第一模块之间有强耦合。比如两路模块之间有一根线必须连在一起复用的时候这根线会被截断反而麻烦。第二模块的布局需要根据板边调整。比如模块靠近板边需要旋转或镜像Place Replicate虽然支持旋转但旋转后的走线和铜皮可能需要重新调整。第三模块数量只有2-3路。手动摆一下可能比创建模块、复用、检查还快。第四模块的器件封装差异大。如果目标模块的器件封装和源模块不一致匹配会失败不如手动。7. 关于模块复用我踩过的几个真实坑第一个坑创建模块时漏选了铜皮。当时模块里有一块GND铜皮我框选的时候只选了器件和走线铜皮没选上。结果复用出去的7路模块全部没有铜皮只能手动补。补铜皮的时候又发现因为器件位置是复用的铜皮的形状和网络都要重新调整比从头铺还麻烦。教训是创建模块时用Window模式框选确保包含所有元素尤其是铜皮。第二个坑目标模块的器件没有全部Fix。复用完成后我以为万事大吉结果后面调整板框的时候不小心移动了目标模块的一个器件导致那一路的走线断了。因为器件没Fix移动的时候走线跟着变形但变形后的走线可能不符合设计规则。教训是复用完成后第一时间Fix所有目标器件。第三个坑模块文件路径丢失。有一次换电脑工程目录复制过去后Place Replicate找不到.mdd文件因为模块文件默认保存在原电脑的工程目录下复制的时候漏了。后来我把模块文件统一放在一个库目录下通过环境变量指向再也没出过这个问题。第四个坑源模块修改后忘记重新创建模块。有一次硬件改了一个电阻的位置我在源模块上改了但忘记重新Create Module结果复用出去的实例还是旧的位置。后来发现的时候板子已经投出去了。教训是源模块修改后必须重新创建模块并重新复用所有实例。如果模块多用Skill脚本批量处理。第五个坑模块内的网络名与目标位置不一致。源模块里的电源网络叫VCC_3V3目标位置的电源网络叫VDD_3V3虽然电气上是同一个网络但Place Replicate不认铜皮铺不上。解决办法是在原理图里统一网络名或者在复用前手动改目标位置的网络名。这些坑官方文档里不会写但每一个都让我多花了半天到一天的时间。写出来希望后来的人能少走弯路。8. 从模块复用延伸出去的几个效率技巧模块复用只是Allegro效率工具箱里的一件。配合其他功能能把PCB设计的效率再拉高一个档次。技巧一用Copy命令配合模块复用。如果目标模块的器件还没摆放可以先用Copy命令把源模块的器件复制过去然后再用Place Replicate。Copy命令会保留器件的相对位置这样目标模块的初始布局就和源模块接近Place Replicate的匹配成功率更高。技巧二用Groups功能管理模块。Allegro的Groups功能可以把一组器件绑定在一起移动的时候一起动。创建模块前先把源模块的器件做成一个Group这样框选的时候不会漏。复用完成后把目标模块的器件也做成Group方便后续管理。技巧三用Skill脚本自动生成模块。如果模块的器件很多手动框选容易漏。可以写一个Skill脚本通过器件属性比如MODULE_GROUP自动选中模块内的所有器件然后调用Create Module。这样创建模块的准确性和效率都更高。技巧四用Sub-drawing做跨板复用。如果模块需要在不同的板子之间复用Place Replicate的.mdd文件可能不兼容因为板子的层叠、规则不同。这时候可以用Sub-drawing功能把模块导出为.clp文件然后在另一块板子上导入。Sub-drawing的灵活性更高但需要手动处理网络和规则的差异。技巧五用Constraint Manager统一模块的规则。如果模块内有特殊的走线规则比如差分对、等长组建议在Constraint Manager里把这些规则做成模板复用的时候直接套用。这样不用每次手动设置规则减少出错概率。这些技巧单独用可能效果一般但组合起来能让模块复用的效率再提升一个台阶。尤其是Skill脚本一旦写好就是一次投入、长期受益。9. 写在最后的一点个人体会画PCB这件事经验的价值往往体现在知道哪里可以偷懒哪里不能偷懒。模块复用就是一个典型的可以偷懒的地方——前提是你把源模块做对了。我见过太多人源模块本身就有问题走线不合理、铜皮不完整、DRC没清然后复用出去问题被放大N倍最后调试的时候欲哭无泪。所以我的建议是源模块一定要做到无可挑剔再复用。多花15分钟把源模块的DRC清干净、把走线优化好、把铜皮铺完整后面复用出去的每一路都是高质量的。反之如果源模块有隐患复用出去的每一路都是隐患而且因为一致性太高问题会同时爆发排查起来更痛苦。另外Skill脚本这件事不要觉得门槛高就放弃。网上有很多现成的脚本模板改一改就能用。花一个下午学一下Skill的基础语法后面能省下无数个下午。我自己就是从完全不会到能写简单的批量脚本前后也就一周的业余时间但回报是巨大的。模块复用这个功能说到底是一种工程思维的体现把重复的事情标准化把标准的事情自动化。PCB设计里还有很多类似的场景比如规则设置、光绘输出、BOM整理都可以用同样的思路去优化。希望这篇内容能帮你打开这个思路而不只是学会一个功能。