首页 / 资讯中心 / 文章详情

Allegro SKILL开发实战:PCB自动化脚本高效解决重复操作

Allegro SKILL开发实战:PCB自动化脚本高效解决重复操作 ★ FEATURED ARTICLE
干过几年 PCB 设计的工程师应该都对 Allegro 又爱又恨。爱的是它在高速板、复杂主板上的统治力恨的是那些没完没了的重复操作改位号文字高度、把丝印翻个面、检查单点网络、导出坐标文件……一件事今天做一遍、明天做一遍、换个板子再做一遍。被逼到一定程度我开始认真琢磨 SKILL 二次开发——这是 Allegro 自家的脚本语言也是摆脱重复劳动、走向 PCB 全流程自动化的最直接路径。这篇文章不打算从安装环境开始啰嗦到高级架构我想反过来从实际工作流里的痛点入手把 SKILL 开发的思路、脚本、踩过的坑一次讲完。无论你是刚入门的 layout 工程师还是已经写过几个脚本但想体系化升级的开发者都可以在里面找到能直接拿去用的东西。代码我会贴关键段思路和避坑建议会比代码本身更长因为这些才是真金白银换来的。1. 为什么是 SKILLPCB 自动化的正确姿势1.1 重复操作的痛点到底有多痛先量化一下。一块 4 层板、500 个器件如果全靠手工整理位号位号居中、调整方向、统一高度熟练工也要 1.5 到 2 个小时。如果是 16 层板、2000 个器件的主板这个工程量直接翻几倍。更要命的是这类活儿往往集中在项目后期板子等着出 Gerber你却在屏幕上一个个点选器件改属性精神和体力的消耗都极大。这不是技术问题这是纯机械劳动。机械劳动最好交给脚本。我见过不少工程师选择硬扛理由是改一次也没多久但一次项目要改十几轮——结构改了调位号器件换封装调丝印评审回来又调一遍。累积下来的时间成本早就够把一套自动化脚本写好写稳了。我自己的分界线是同一个操作如果一周内重复出现三次或者一次要花超过十分钟就值得写脚本。这不是效率洁癖是项目延误赔过钱之后形成的本能。1.2 SKILL 相比其他自动化方案的天然优势做 PCB 自动化有几种技术路线。用外部脚本直接解析.brd文件brd 是 Cadence 内部格式结构复杂且不同版本差异很大解析成本极高改坏了还容易把文件弄废。用界面自动化软件模拟鼠标键盘Windows 窗口位置一变脚本就崩定位全靠猜。用 Allegro 自带的 Scripting 录制回放适合一次性回放操作序列但缺乏逻辑判断能力不能根据设计数据做决策。SKILL 才是正规军。它有几个无可替代的优势原生运行Allegro 启动时自动加载 SKILL 脚本无需额外安装解释器也不依赖任何外部组件。直接操作设计数据库调用axl前缀的 API 就能读取器件、网络、铜箔、文字并修改它们的属性。这是外部脚本永远做不到的。有完整的程序结构支持函数定义、循环、条件判断、递归、文件读写简单说它就是一门完整的编程语言只是长得像 Lisp。交互能力强能调用 Allegro 的绘图、高亮、坐标获取能力比如axlPickPoint可以弹出窗口让用户点选位置然后把坐标传回脚本。SKILL 的语法风格对第一次接触的人可能有点别扭函数调用统一用括号前引比如(axlDBGetDesign)(axlCmdRegister test test_func)。习惯 Python 或者 C 的人刚开始会疯狂配对括号。但用两天就会发现这种统一形式在写复杂逻辑时反而格外清晰顺序、嵌套一目了然。2. 从零搭建 SKILL 开发环境加载、注册、绑定2.1 目录结构与 allegro.ilinit 配置SKILL 脚本一般保存为.il文件纯文本也可以加密成.cxt文件。推荐的目录方案是建立一个独立文件夹比如D:/allegro_skill把不同功能的脚本拆开存放不要所有代码堆在一个大文件里。实测下来单个脚本最好控制在几百行以内维护成本随着文件行数会快速上升。Allegro 启动时会去找环境变量指定的初始化文件allegro.ilinit。这个文件通常在用户目录下的pcbenv文件夹里比如C:/Cadence/pcbenv/allegro.ilinit。如果没有自己新建一个纯文本文件名字必须是allegro.ilinit编码建议用 GBK老版本 Radif 等对 UTF-8 支持不佳后面我也列了这个坑。在allegro.ilinit里写入加载指令; 示例allegro.ilinit 加载自定义 SKILL load(D:/allegro_skill/common_functions.il) load(D:/allegro_skill/text_tools.il) load(D:/allegro_skill/export_tools.il)启动 Allegro 时这些脚本会自动加载。如果在开发调试阶段也可以在 Allegro 的 Command 命令行里直接输入(load D:/allegro_skill/test.il)手动加载不需要重启软件改完代码重载一次即可。路径有个细节非常坑SKILL 字符串里的反斜杠会被当作转义字符所以 Windows 路径必须用正斜杠或者双反斜杠。load(D:/allegro_skill/test.il)才是正确的写成load(D:\allegro_skill\test.il)会直接报错。2.2 命令注册与快捷键绑定.il文件加载进来里面的函数还不能直接在 Allegro 的 Command 栏里执行需要显式注册成命令。注册函数是axlCmdRegister; 注册一个名为 refdes_center 的命令执行 user_refdes_center 函数 axlCmdRegister(refdes_center user_refdes_center)这个refdes_center是你在 Command 栏输入的名字后面单引号括起来的是脚本里定义的函数名。注册完成后在 Allegro 命令行输入refdes_center回车就能执行对应函数。注意axlCmdRegister会覆盖 Allegro 自带的同命令名称注册前先用axlCmdRegister检查或者给命令加项目前缀比如proj_refdes_center避免和别的脚本冲突。快捷键绑定用axlAlias; 把 F6 绑定到 refdes_center 命令 axlAlias(F6 refdes_center)axlAlias可以绑定功能键、字母组合键。常用习惯是把 F2 到 F8 留给高频操作F1 和 F9 不要占容易误触。绑定要放在命令注册之后的代码里否则 Allegro 会提示找不到对应命令。2.3 编辑器的选择与调试辅助SKILL 没有官方推荐的独立 IDE实际开发基本靠文本编辑器加浏览器查 API。我自己的组合是Notepad 或 Sublime配合 SKILL 语法高亮文件括号能自动高亮配对这是保命功能。Lisp 风格代码括号一旦不配对加载报错找不到位置。Allegro 自带的 Command 窗口调试主力。所有printf、axlMsgPut的输出直接显示在这里。一个专门用于测试的板子永远不要拿正在出图的项目板子测试脚本。准备一个复制的测试版或者公司历史项目备份脚本测试通过再上真项目。编辑器方面还有一个隐藏细节老版本 Allegro16.x 系列对 SKILL 文件的编码敏感建议统一用 GB2312 或 GBK 编码写脚本。新版本17.2 之后对 UTF-8 支持好一些如果图省事统一用 GBK 最稳妥。中文字符串出现乱码大概率是编码问题。3. 实战脚本三个高频痛点的自动化实现3.1 批量修改丝印文字高度项目后期最常见的需求之一所有位号文字统一改成指定大小。手工做法是打开 Find 面板过滤器选 Text然后在板上框选文字打开属性对话框逐项修改。板子器件多的时候光框选就手酸。SKILL 的实现思路很直接遍历设计数据库里的所有文本对象筛选出丝印层SILKSCREEN_TOP的位号然后统一赋值。核心代码如下; 功能批量统一顶部丝印层文字高度与线宽 ; 用法Command 栏执行 set_silk_text 1.0 0.1 defun( set_silk_text (height linewidth) let( (texts txt count) count 0 texts axlDBGetDesign()-texts foreach( txt texts when( txt-subclass REF DES/SILKSCREEN_TOP txt-textBlock nil txt-height height txt-lineWidth linewidth count count 1 ) ) axlMsgPut(已修改 %d 个丝印文字高度 %L线宽 %L count height linewidth) ) )同样逻辑改一行subclass条件就能处理 SILKSCREEN_BOTTOM 或者器件型号、标注文字。很多工程师会在脚本里加一个参数控制层别比如set_silk_text 1.0 0.1 t多写一个分支判断即可。有两点要提醒一是textBlock要显式置空再设置 height 和 lineWidth否则有些版本的 Allegro 会优先按 Text Block 字号显示你改了 height 却看不到效果二是如果器件被锁定或者属于某个 Module直接改属性会被拒绝遍历时需要跳过locked或者先执行解锁。这个坑我后面也会提到。3.2 一键居中器件位号位号居中是另一个高频需求。过去我的做法是选中器件右键选择文本编辑瞄一眼器件的中心坐标再手动把位号移过去全靠眼睛校准。一百个器件下来近视度数都要涨。SKILL 可以通过器件的 bounding box包围盒算出外框中心再把位号文本的坐标设置到这个中心点; 功能所有器件的位号文本自动移动到器件包围盒中心 ; 用法Command 栏执行 center_refdes_all defun( center_refdes_all () let( (symbols sym refdes sym_bbox x1 y1 x2 y2 cx cy) symbols axlDBGetDesign()-symbols foreach( sym symbols when( sym-type COMPONENT refdes sym-refdes sym_bbox sym-bBox x1 xCoord(car(sym_bbox)) y1 yCoord(car(sym_bbox)) x2 xCoord(cadr(sym_bbox)) y2 yCoord(cadr(sym_bbox)) cx (x1 x2) / 2 cy (y1 y2) / 2 refdes-xy list(cx cy) ) ) axlMsgPut(位号居中完成) ) )bBox返回两个坐标点car取第一个点cadr取第二个点再用xCoord、yCoord分离横纵坐标。最后refdes-xy直接赋值Allegro 就会把文本移动过去。代码不复杂但我强烈建议加一个过滤条件比如只处理选中的器件而不是全部器件。高频场景往往是这一堆新加的器件位号乱帮我归整一下全板居中反而会把原本手动调好的位号打乱。改造也很简单用axlGetSelSet()获取当前选中对象遍历这个列表而不是全板 symbols。3.3 单点网络与未布线检查单点网络引脚只连了一根线或者网络根本没布线是评审时的必查项。手工检查的方法是在约束管理器里翻网络状态或者用菜单里的报告功能来回切换很费时间。SKILL 直接读数据库属性; 功能列出所有单引脚网络 ; 用法Command 栏执行 check_single_pin defun( check_single_pin () let( (nets n count) count 0 nets axlDBGetDesign()-nets foreach( n nets when( n-isSinglePinNet printf(单点网络: %L\n n-name) count count 1 ) ) printf(共发现 %d 个单点网络\n count) ) )isSinglePinNet是网络对象的内置属性Allegro 会自动维护。配合n-name输出网络名检查结果直接打印到 Command 窗口。批量刷一遍只需要一秒。同类操作还有很多查找未连线的引脚、查找没有放到板框内的器件、查找离板边过近的器件等。这些检查类脚本写得越多评审的时候底气就越足因为你知道问题都提前扫过一遍了。4. 打通全流程从网表导入到光绘输出的自动化框架4.1 全流程拆解哪些环节值得自动化单个脚本只能解决点状问题真正提升效率的是把脚本组织成完整流程。一个典型的 Allegro 设计流程从拿到网表到交付制造文件我把它拆成这几个阶段并标注了自动化优先级阶段典型重复操作自动化方式收益等级前期准备叠层设置、颜色方案、格点、单位环境初始化脚本一次性执行高网表导入Netin、调出未放置器件、确认错误脚本调命令 自动读取报告高布局阶段等间距对齐、按模块摆放、位号调整辅助脚本 排序算法中规则设置差分对、物理间距、网络类分类基于 Excel 配置批量生成高布线检查DRC 更新、单点网络、未连接引脚检查类脚本汇总报告中后期整理丝印统一、文本居中、装配层整理批量处理脚本高输出交付Gerber、钻孔、坐标、BOM脚本录制回放 文件生成高优先级最高的不是看起来最复杂的布线阶段而是前期的环境初始化和后期的输出交付。原因是这两个环节完全规则化几乎没有需要人工判断的地方脚本能覆盖 100% 场景。布局布线阶段信息变数大脚本只做辅助比如对齐、间距调整不可能完全替代人工决策。4.2 一键输出制造文件Artwork、钻孔与坐标输出制造文件是看似简单、实际繁琐的典型。要保证光绘层设置正确钻孔文件格式对坐标文件格式客户认。每次参数不同手工配置一遍就要十几分钟。SKILL 层面没有一个公开的axlArtworkCreate函数能直接生成全部光绘常见的做法是两条路结合第一条路利用 Allegro 的脚本录制。在 Allegro 菜单里File - Script - Record把整个输出光绘的操作录下来得到一个.scr文件。之后在 SKILL 里用axlShell调用; 执行录好回放的输出脚本 axlShell(replay D:/allegro_skill/export_artwork.scr)axlShell的作用相当于在 Allegro 命令行输入命令任何能在命令行执行的指令都能传进去。这个方案对新手最友好不需要懂电影文件和光绘配置的内部结构录制一次就能复用。第二条路用 SKILL 文件 API 直接生成坐标、BOM 等文本文件。比如输出坐标文件到 CSV; 功能导出所有器件中心坐标到 CSV defun( export_centroid () let( (port symbols sym refdes x y name) port outfile(D:/output/centroid.csv) fprintf(port RefDes,Device,X,Y\n) symbols axlDBGetDesign()-symbols foreach( sym symbols when( sym-type COMPONENT refdes sym-refdes name sym-name x xCoord(sym-xy) y yCoord(sym-xy) fprintf(port %s,%s,%d,%d\n refdes name x y) ) ) close(port) printf(坐标文件已输出\n) ) )这段代码展示了 SKILL 文件读写的标准套路outfile打开文件fprintf逐行写入close关闭然后printf在命令行输出提示。DIP、封装类型、旋转角度等信息同理一条条加进 CSV 即可。自动化输出最容易翻车的是路径问题。项目中一定统一约定输出目录脚本里写死一个 BASE_DIR不要每次手动改路径。有人觉得写死路径不够灵活但我实测下来固定路径 项目文件命名规范比灵活的半自动脚本出问题的概率低得多。4.3 用外部数据驱动脚本Excel、文本配置、Python 协同单个 SKILL 脚本能力有限但和外部数据联动之后能发挥出更大的价值。这里说两个我常用的模式。第一个模式是配置文件驱动。开发板类项目的叠层结构、规则要求、器件物料清单一类信息本来就维护在 Excel 里。SKILL 可以读一个约定格式的 CSV 或配置文件把表格里的参数变成变量批量执行; 功能从 CSV 文件读取差分对约束并自动设置 ; CSV 格式net1,net2,width,gap infile(D:/project/diff_pairs.csv) ...实际开发中我更推荐先用 Python 把 Excel 数据清洗成 CSV因为 SKILL 处理 Excel 的 xlsx 格式并不方便而 CSV 是纯文本任何语言都能处理。Python 读 Excel、做规则校验、生成 CSVSKILL 读 CSV、执行设置命令各干各擅长的活儿。第二个模式是脚本生成脚本。想象这样一个需求根据 BOM 表批量放置 100 个同一封装的阻抗测试点。手工做是在 Allegro 里一个个放放到第 20 个就想睡觉。更优雅的解法是写一个 Python 脚本读取 BOM 和坐标规划表生成一个 SKILL 文件# Python 生成 SKILL 放置脚本文本 with open(place_testpoints.il, w, encodinggbk) as f: f.write(axlCmdRegister(place_tp \place_tp_func)\n\n) f.write(defun( place_tp_func ()\n) f.write( let( ()\n) for row in bom_data: refdes row[refdes] x row[x] y row[y] f.write(f axlOpenObject( {refdes} COMPONENT )\n) f.write(f axlMoveObject( list({x} {y}) )\n) f.write(f axlCloseObject()\n) f.write( )\n)\n)然后在 Allegro 里load这个生成的脚本执行一次。用脚本生成脚本的模式投资项目规划、机械坐标导入等需求都能处理本质是把数据转换逻辑放在更熟悉的 Python 环境里SKILL 只做最后一步执行。这种模式很有工程价值因为需求变更时只需要改 Python 侧的数据表不需要动 SKILL 逻辑。比如机械结构改了孔位坐标更新 Excel重新跑一遍 Python再 Allegro 里 load 一次就完成了整个放置更新。5. 常见问题与排查技巧实录5.1 高频报错与解决方案速查表把自己踩过的坑和帮同事排查过的问题整理成一张速查表基本覆盖了 SKILL 开发最常见的故障点症状常见原因解决办法启动后load报错Loading failed路径不对或文件编码错误检查斜杠方向确认文件编码为 GBKCommand 栏执行提示Unknown command脚本加载失败或命令未注册先手动load再看axlCmdRegister是否执行中文注释显示乱码文件编码与版本不匹配老版本统一用 GBK少用生僻字括号不匹配报错定位困难Lisp 风格括号嵌套过多用有括号高亮的编辑器写函数前先用缩进对齐文字高度改了不生效textBlock未置空或器件被锁定先txt-textBlock nil再改 height脚本能跑但没看到预期修改操作被过滤条件挡掉打印筛选条件和对象个数逐层排查Artwork 输出失败输出路径不存在或 film 未设置脚本里先mkdir运行前检查 photoplot 目录17.2 新 API 在 16.6 上报错版本 API 差异查当前版本axlGet是否存在或写兼容分支快捷键没反应axlAlias在注册命令前执行调整allegro.ilinit中注册和绑定顺序脚本运行卡死遍历对象时进入死循环或数据库锁定加计数器打印进度避免在遍历中修改数据库结构5.2 调试技巧与独家避坑经验第一最有效的调试方法是在图纸的 Command 窗口直接敲函数。写完一个函数先手动(load xxx.il)加载再单独执行函数观察输出信息。SKILL 的报错信息经常直接告诉你行号和函数名比如error at line 43 in function center_refdes_all对照代码找就行定位速度比想象中快得多。第二多用printf打日志。很多脚本没反应不是没执行而是执行了但结果不符合预期。在循环里加一行printf(processing %s\n refdes)会立刻暴露出是对象滤光了还是坐标算错了。我自己写的脚本至今还会在关键步骤保留两三个 printf 输出方便出问题时现场排查。第三数清楚你的角标。SKILL 里car取列表第一个元素cadr取第二个caddr取第三个。这个源自 Lisp 的语义是祖传的新手经常把cadr和cdr搞混。不熟的人建议直接用nth(0 list)、nth(1 list)这种更直白的写法减少踩雷。第四不要直接拿项目文件调试。SKILL 脚本出错时最危险的不是报错而是它已经对数据库做了一部分修改然后又中断——整个板子处于一个半修改状态手动恢复很痛苦。我自己的标准流程是先测试版跑通再备份项目.brd文件最后才在正式项目上执行。备份按钮按一下不花时间恢复的时候能救一条命。第五大循环遍历时注意数据库锁定。Allegro 对设计库的访问在脚本执行期间是有锁机制的遍历过程中如果脚本里再调用某些交互函数可能直接卡死。遇到奇怪死机先看是不是在foreach里调用了交互 API这是最常见的坑。第六版本兼容性必须提前规划。16.6、17.2、17.4 三代的axl函数有些行为不一致。比如新版本里axlDBGetDesign返回的对象类型更丰富某些老函数被标记为 deprecated。写脚本时尽量用全局通用的基础 API遇到报错先检查是不是版本差异。条件允许的话把脚本在 17.2 和 17.4 各跑一遍兼容性就有底了。5.3 脚本维护的一些朴素建议一开始写脚本总是能用就行后面项目多了才发现维护才是最花精力的。现在我的每个脚本文件头部都会有统一注释块包括文件名、功能描述、用法示例、适用版本、最后修改日期、修改人。这个习惯看起来费事但半年后回看脚本你会发现这行代码当时为什么这么写真的会想不起来。脚本的组织别贪大。不要在 allegro.ilinit 里塞一大堆加载用时要的就是那几个高频功能。把常用脚本压缩到 8 个以内每个文件只做一类事文字类、对齐类、检查类、输出类、环境设置类按类加载。多年维护下来这个结构比一个大杂烩文件可靠得多。关于加密脚本.cxt是 Cadence 的加密格式可以保护源码不被同事直接拿走。但加密前一定留一份.il源文件一旦源文件丢了加密文件自己也没法再改。我见过不止一个人加密后找不到源文件最后只能重写整个脚本。最后再分享一个一直坚持的小习惯写脚本之前先手工把流程走一遍记录每一步操作背后的判断条件。很多自动化项目的失败不是脚本写得不对而是拍脑袋决定自动化——其实手工流程里含有大量隐性规则只有把规则理清楚脚本才能写对。SKILL 自动化最有价值的部分从来不是快而是把工程师脑子里的经验知识显性化变成团队可复用、可传承的资产。
阅读完成 · 觉得有帮助?
咨询建站