拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Allegro Skill脚本实战:5个高频功能提升PCB设计效率

1. 为什么Allegro老手都在偷偷用Skill脚本画PCB这件事说到底是拿时间换精度的活。一块中等复杂度的板子从导入网表到出光绘中间要经历封装核对、规则设置、布线优化、铜皮处理、丝印调整、DRC排查等十几个环节。每个环节单看都不难但架不住重复操作多。我见过太多工程师一天八小时里有三四个小时在做复制粘贴、手动对齐、逐个改属性这类机械动作。Allegro本身提供了录制脚本的功能但录制的脚本有个致命问题它只认坐标和固定对象换个板子、换个层、换个封装就完全跑不通。真正能跨项目复用的是Skill语言写的程序化脚本。Skill是Cadence给Allegro配的类Lisp解释型语言能直接调用Allegro的底层数据库操作对象、属性、参数而不是死板的坐标。凡亿Skill这个工具集本质上是一批国内PCB工程师在实际项目中沉淀下来的Skill脚本合集把高频操作封装成了菜单命令。我前后用过十几个版本也自己改过不少源码最终稳定留在工具栏里的就五个功能。这五个功能覆盖了封装处理、规则批量修改、丝印自动化、铜皮管理和光绘输出检查基本把日常最耗时的重复劳动都包圆了。这篇文章适合两类人看一类是刚接触Allegro不久、还在被各种重复操作折磨的初中级工程师另一类是用Allegro多年但没系统研究过Skill、想看看别人怎么提效的老手。我会把每个功能的原理、操作步骤、参数含义、踩过的坑都讲清楚代码能贴的贴出来不能贴的讲明白逻辑你照着改也能用。2. 五个核心功能的整体设计思路拆解2.1 为什么是这五个功能而不是别的凡亿Skill里功能很多从快捷键映射到自动标注从BOM核对到阻抗计算少说几十个命令。但我最终只留五个原因很简单判断一个自动化功能值不值得用看三个指标——触发频率、单次耗时、出错代价。触发频率高、单次耗时长、手动做容易出错的操作才值得做成自动化。按这个标准筛下来封装替换、规则批量修改、丝印自动摆放、铜皮轮廓重建、光绘预检查这五个功能得分最高。像自动标注这种功能触发频率其实不高一块板子标一次就完了手动做也就几分钟做成脚本的收益有限。另一个考虑是通用性。有些功能只适用于特定类型的板子比如射频板的阻抗自动计算换到普通数字板就没用了。我留的这五个功能不管你是画两层板还是十六层板是消费电子还是工控板都用得上。2.2 Skill脚本相比录制脚本的核心优势这里要展开说一下因为很多人分不清两者的区别。Allegro自带的录制功能生成的是.scr文件本质上是回放鼠标键盘事件。你录的时候点了哪个坐标回放时就点哪个坐标。板子尺寸一变坐标全错。Skill脚本操作的是数据库对象。比如你要替换封装录制脚本的做法是选中某个元件右键选Replace输入新封装名回车。Skill脚本的做法是遍历所有symbol对象找到refdes等于目标值的那个修改它的device属性然后刷新。前者依赖界面和坐标后者依赖数据结构和属性名。这就是为什么Skill脚本能跨项目复用而录制脚本换个板子就废。注意Skill脚本也不是万能的。它依赖Allegro的版本和数据库结构17.2和17.4的某些API就有差异。写脚本时要先确认目标版本的函数签名不然会报E- *Error* eval: undefined function这类错误。2.3 工具集的组织方式与调用逻辑凡亿Skill的安装方式是把脚本文件放到Allegro的pcbenv目录下然后在allegro.ilinit文件里加载。加载后会在菜单栏或工具栏生成对应的按钮。我习惯把常用功能绑定到快捷键上比如封装替换绑CtrlR规则修改绑CtrlL这样手不用离开键盘就能触发。脚本之间的数据传递靠全局变量。比如丝印自动摆放功能会先读取当前板子的text_block设置把字号、线宽、间距存到全局变量里后续操作都引用这些变量。这样做的好处是改一处就能全局生效坏处是如果某个脚本异常退出全局变量可能残留脏数据导致下一个脚本行为异常。我的做法是在每个脚本开头加一段初始化代码强制重置关键全局变量。3. 封装批量替换与属性同步的实操细节3.1 手动替换封装的痛点在哪里一块板子上有几百个元件其中电阻电容这类被动器件占了大半。项目做到后期经常遇到供应商换料、封装库更新、或者设计规则变更导致某个封装需要整体替换的情况。手动操作的话你要在Find面板里选中Symbols在板上框选所有目标元件右键选Replace输入新封装名然后一个一个确认。如果板子上有五十个这样的元件光确认对话框就能点到手酸。更麻烦的是属性同步。替换封装后元件的refdes、value、tolerance这些属性有时候会丢失或者错位。特别是refdes如果替换后变成?你还得手动重新标注。这些操作单独看都不难但叠加起来一个下午就没了。3.2 Skill脚本的实现逻辑与关键代码脚本的核心逻辑分三步筛选目标元件、执行替换、同步属性。筛选这一步我通常按refdes前缀或者device属性来匹配。比如把所有R开头的电阻替换成R0603封装或者把所有device为CAP_0402的电容替换成CAP_0603。; 按refdes前缀筛选并替换封装 procedure( replaceSymbolByPrefix(prefix newDevice) let( (allSymbols targetSymbols) allSymbols axlDBGetDesign()-symbols targetSymbols setof(sym allSymbols (prefix substring(sym-refdes 1 strlen(prefix))) ) foreach(sym targetSymbols sym-device newDevice axlDBRefresh(sym) ) printf(Replaced %d symbols\n length(targetSymbols)) ) )这段代码里axlDBGetDesign()拿到整个设计数据库-symbols取出所有元件对象。setof是Skill的筛选函数类似其他语言的filter。substring取refdes的前几个字符做匹配。sym-device newDevice直接修改属性axlDBRefresh刷新显示。属性同步要更小心。替换封装后refdes可能会变value可能丢失。我的做法是在替换前先把关键属性存到一个临时列表里替换后再写回去。; 替换前保存属性替换后恢复 procedure( replaceWithAttrSync(prefix newDevice) let( (allSymbols targetSymbols attrList) allSymbols axlDBGetDesign()-symbols targetSymbols setof(sym allSymbols (prefix substring(sym-refdes 1 strlen(prefix))) ) attrList nil foreach(sym targetSymbols attrList cons(list(sym-refdes sym-value sym-tolerance) attrList) ) foreach(sym targetSymbols sym-device newDevice axlDBRefresh(sym) ) foreach(attr attrList foreach(sym targetSymbols when(sym-refdes car(attr) sym-value cadr(attr) sym-tolerance caddr(attr) ) ) ) ) )提示属性同步时要注意refdes本身可能被Allegro自动重命名。如果替换后refdes变了上面的匹配逻辑就会失效。稳妥的做法是用元件的xy坐标做匹配键因为坐标在替换前后不会变。3.3 实操步骤与参数选择实际操作时我一般按这个流程走在Allegro命令行输入skill进入Skill模式或者直接通过菜单调用封装好的命令。输入筛选条件。如果是按前缀输入R就匹配所有电阻如果是按device输入完整的封装名。输入新封装名。这里要注意新封装必须已经在库路径里否则会报Could not find device错误。选择是否同步属性。如果板子已经标注过建议同步如果还没标注可以不同步替换后统一标注。确认执行。脚本会打印替换数量检查一下是否和预期一致。参数选择上text_block的设置会影响替换后丝印的显示。如果新封装的丝印字号和旧封装不一致替换后丝印可能重叠或者太小看不清。我的做法是在替换前先统一text_block把丝印字号、线宽、间距都设成项目标准值。3.4 常见报错与排查方法最常见的报错是E- Cannot find device意思是新封装不在库路径里。排查方法是检查Setup - User Preferences - Paths - Library里的padpath和psmpath是否包含新封装所在的目录。另一个常见问题是替换后元件位置偏移。这通常是因为新旧封装的原点定义不一致。比如旧封装的原点在中心新封装的原点在1脚替换后元件就会整体偏移。解决办法是在替换前先记录元件的xy坐标替换后强制写回。报错信息可能原因解决方法Cannot find device新封装不在库路径检查padpath和psmpathSymbol not refreshed数据库未刷新手动调用axlDBRefreshAttribute lost属性未同步使用带属性同步的替换函数Position shifted封装原点不一致替换后强制写回xy坐标4. 设计规则批量修改与铜皮轮廓重建4.1 规则批量修改为什么让人头疼Allegro的约束管理器功能很强大但操作起来层级太深。改一个线宽规则要点开Setup - Constraints - Constraint Manager找到对应的Net或Class再找到Line Width双击修改确认。如果板子上有二十个网络需要改线宽这个流程要走二十遍。更麻烦的是规则之间的依赖关系。比如你改了Min Line Width但Min Neck Width没改DRC就会报一堆错。手动改的时候很容易漏掉关联规则导致后面排查DRC时浪费时间。4.2 用Skill批量修改规则的实现Skill可以直接操作约束管理器里的规则对象。核心函数是axlCNSGetConstraint和axlCNSSetConstraint。前者读取规则值后者写入规则值。; 批量修改指定网络的线宽规则 procedure( batchSetLineWidth(netPattern minWidth maxWidth) let( (allNets targetNets) allNets axlDBGetDesign()-nets targetNets setof(net allNets (rexMatchp(netPattern net-name)) ) foreach(net targetNets axlCNSSetConstraint(net-name LINE_WIDTH minWidth maxWidth) ) printf(Updated %d nets\n length(targetNets)) ) )rexMatchp是正则匹配函数netPattern可以写DDR_*来匹配所有DDR相关网络。axlCNSSetConstraint的第三个参数是最小值第四个是最大值。设置完后要调用axlCNSRefresh刷新约束管理器。注意修改规则前一定要先备份.brd文件。Skill脚本直接操作数据库改错了没有撤销功能。我一般会在脚本开头加一句axlShell(saveas backup.brd)强制存一个备份。4.3 铜皮轮廓重建的触发场景铜皮在Allegro里是个特殊对象它由轮廓和填充两部分组成。有时候因为DRC或者显示问题铜皮会变成只有轮廓没有填充的状态看起来像空心的一样。手动修复的方法是选中铜皮右键选Shape - Rebuild但如果有几十块铜皮都这样一个个点太慢。还有一种情况是铜皮被误删了填充只剩轮廓。这时候需要重新生成填充。Skill脚本可以遍历所有shape对象检查fill属性是否为空为空就调用重建函数。; 重建所有空心铜皮 procedure( rebuildHollowShapes() let( (allShapes hollowShapes) allShapes axlDBGetDesign()-shapes hollowShapes setof(shape allShapes (shape-fill nil) ) foreach(shape hollowShapes axlShapeRebuild(shape) ) printf(Rebuilt %d shapes\n length(hollowShapes)) ) )axlShapeRebuild是重建铜皮的核心函数它会根据轮廓重新计算填充。重建前要确保铜皮的net属性正确否则重建后可能连到错误的网络上。4.4 实操中的参数计算与注意事项铜皮重建时smooth参数很关键。它控制填充的平滑程度值越大越平滑但计算越慢。我一般设3到5之间太低了边缘会有锯齿太高了跑一次要等好几分钟。另一个参数是thermal relief也就是热焊盘连接方式。重建前要确认Setup - Constraints - Shape里的热焊盘规则是否正确不然重建后焊盘连接可能不符合要求。参数推荐值说明smooth3-5填充平滑度越高越慢thermal width0.3mm热焊盘连接线宽thermal gap0.3mm热焊盘间隙min shape width0.15mm铜皮最小宽度5. 丝印自动摆放与光绘输出预检查5.1 丝印自动摆放的逻辑与限制丝印摆放是个细活。元件密度高的时候丝印很容易重叠手动调整要一个个拖。Skill脚本可以自动把丝印摆到元件旁边但要注意自动摆放只能解决“有没有”的问题解决不了“好不好看”的问题。脚本的逻辑是遍历所有元件读取元件的bounding box把丝印文字放到bounding box的上方或下方避开焊盘和过孔。如果上方空间不够就放下方下方也不够就放左侧或右侧。; 自动摆放丝印 procedure( autoPlaceSilkscreen() let( (allSymbols bbox textX textY) allSymbols axlDBGetDesign()-symbols foreach(sym allSymbols bbox axlSymbolBBox(sym) textX (car(bbox) cadr(bbox)) / 2.0 textY caddr(bbox) 0.5 sym-refdes-xy list(textX textY) axlDBRefresh(sym) ) ) )这段代码把丝印放到元件包围盒上方0.5mm处。实际使用时还要加碰撞检测判断新位置是否和已有丝印或焊盘重叠。碰撞检测可以用axlDBGetOverlaps函数实现。提示自动摆放后一定要人工检查一遍。特别是极性元件丝印方向不能错。我见过脚本把二极管的正极标记摆到负极那边的案例虽然概率低但一旦出错就是批量性的。5.2 光绘输出前的自动检查项出光绘是PCB设计的最后一步也是最容易出问题的一步。常见的错误包括丝印压焊盘、阻焊开窗不对、钻孔文件缺失、层顺序错误。手动检查的话要一层一层看费时费力还容易漏。Skill脚本可以在出光绘前自动跑一遍检查把常见问题列出来。检查项包括丝印层是否有文字压在焊盘上阻焊层开窗是否比焊盘大钻孔文件是否和钻孔表一致光绘层是否齐全是否有未连接的铜皮; 光绘预检查 procedure( preCheckGerber() let( (allSymbols allPads issues) issues nil allSymbols axlDBGetDesign()-symbols foreach(sym allSymbols when( axlDBGetOverlaps(sym-refdes SILKSCREEN_TOP PAD_TOP) issues cons(Silkscreen over pad: sym-refdes issues) ) ) foreach(issue issues printf(%s\n issue) ) printf(Total issues: %d\n length(issues)) ) )这个检查逻辑是遍历所有元件判断丝印文字是否和顶层焊盘重叠。如果重叠就记录到issues列表里。实际使用时还要检查底层丝印和底层焊盘。5.3 光绘参数设置与输出流程光绘参数在Manufacture - Artwork里设置。关键参数包括Format通常选RS-274X这是标准格式Units选Inch或Millimeter要和板子单位一致Integer places和Decimal places控制精度一般设3和5Suppress选Leading Zero或Trailing Zero看板厂要求输出前要确认每一层的Film都正确添加了对应的对象。比如顶层丝印层要包含Silkscreen_Top和Package_Geometry顶层阻焊层要包含Soldermask_Top和Pin。检查项正常状态异常处理丝印压焊盘无重叠调整丝印位置阻焊开窗比焊盘大0.1mm修改阻焊规则钻孔文件与钻孔表一致重新生成钻孔光绘层齐全无遗漏补充缺失层铜皮连接全部连接重建铜皮5.4 实操心得与避坑经验我踩过最大的坑是光绘输出后没有检查Film的Undefined line width设置。这个参数控制未定义线宽的对象用什么线宽输出。如果设成0有些线就会消失。我一般设成0.1mm确保所有对象都能输出。另一个坑是钻孔文件的格式。有些板厂要求Excellon格式有些要求NC Drill格式。输出前一定要和板厂确认不然做出来的板子孔位会偏。注意光绘输出后建议用CAM工具预览一遍。Allegro自带的Viewmate或者第三方工具都可以。预览时重点看丝印是否清晰、阻焊开窗是否准确、钻孔是否齐全。6. 常见问题与排查技巧实录6.1 Skill脚本加载失败的排查思路脚本加载失败通常有三个原因路径不对、语法错误、版本不兼容。路径问题最好排查检查allegro.ilinit里的load语句路径是否正确。语法错误要看Allegro的命令行输出它会提示哪一行有问题。版本不兼容比较麻烦需要查Cadence的API文档确认函数在当前版本是否存在。我一般用二分法排查先把脚本注释掉一半看能否加载如果能问题在另一半如果不能问题在这一半。这样几次就能定位到具体行。6.2 脚本执行后板子异常的处理脚本执行后如果板子显示异常比如元件消失、铜皮变空心、规则错乱第一时间不要保存。先关掉Allegro用备份文件恢复。这也是为什么我反复强调执行前要备份。如果异常不严重比如只是显示问题可以尝试View - Refresh或者axlDBRefresh。如果刷新没用可能是数据库损坏需要用DBDoctor工具修复。6.3 性能优化与脚本运行速度提升Skill脚本跑得慢通常是因为遍历了太多对象。优化方法是缩小遍历范围比如只遍历当前层或者只遍历选中的对象。另一个方法是减少axlDBRefresh的调用次数把多次修改合并后统一刷新。我实测下来一个遍历五千个元件的脚本如果每改一个就刷新一次要跑好几分钟如果改成全部改完再刷新几秒钟就完了。这个差异在大型板子上特别明显。问题现象可能原因解决方法脚本加载失败路径错误检查ilinit文件脚本执行报错语法错误查看命令行输出板子显示异常数据库损坏用备份恢复脚本运行慢遍历对象过多缩小范围减少刷新属性丢失未同步属性使用带同步的函数6.4 独家避坑技巧汇总第一个技巧在脚本开头加axlShell(set noconfirm)这样执行过程中不会弹确认对话框适合批量操作。但要注意这个设置会关闭所有确认包括删除操作所以脚本逻辑一定要严谨。第二个技巧用errset包裹可能出错的代码块防止一个错误导致整个脚本中断。errset会捕获错误并返回nil脚本可以继续执行后面的逻辑。第三个技巧把常用参数写到配置文件里脚本运行时读取。这样换项目时不用改代码改配置文件就行。配置文件可以用简单的keyvalue格式用infile和fscanf读取。第四个技巧脚本执行前先检查当前是否有未保存的修改。可以用axlDBGetDesign()-modified判断如果有修改就先提示保存。这个技巧能避免很多“脚本跑完发现之前的修改丢了”的悲剧。7. 我个人在实际操作中的体会这五个功能我用了两年多最大的感受是自动化不是让你变懒而是让你把时间花在真正需要思考的地方。以前画一块板子光重复操作就占了一半时间现在这些时间省下来可以多想想叠层怎么排、阻抗怎么控、EMC怎么优化。但自动化也有边界。Skill脚本能处理规则明确、逻辑固定的任务处理不了需要审美和判断的任务。比如丝印摆放脚本能摆到不重叠但摆得好不好看、符不符合阅读习惯还得人来调。所以我的做法是脚本做粗活人做细活。另外不要迷信现成的工具集。凡亿Skill里的脚本我改过不少因为每个项目的规则、库、习惯都不一样。别人的脚本拿过来先读懂逻辑再按自己的需求改。改多了你就发现写Skill脚本没那么难核心就是那几个函数axlDBGetDesign拿数据setof筛数据foreach遍历axlDBRefresh刷新。掌握这四个大部分自动化需求都能自己实现。最后分享一个小技巧如果你不确定某个Skill函数怎么用在Allegro命令行输入skill进入交互模式然后输入help加函数名比如help axlDBGetDesign它会打印函数的参数和返回值说明。这个比翻文档快多了。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门