
1. 这篇文章真正要解决的问题如果你是一名使用Cadence Allegro进行PCB设计的工程师那么下面这个场景你一定不陌生项目评审会上硬件负责人指着BOM清单问这颗关键IC的封装和引脚定义能否单独导出一份清晰的图纸给结构工程师和测试工程师参考或者在布局规划时你需要快速统计板上某个复杂BGA芯片的电源、地、信号引脚各有多少以便进行电源平面分割和Fanout规划。面对这些需求你是选择在庞大的PCB设计文件中手动截图、标注、数引脚还是希望有一个一键生成、准确无误的自动化方法手动操作不仅效率低下而且极易出错。截图可能遗漏背面的引脚数引脚时眼花缭乱数错一个都可能导致后续的装配或测试问题。这正是Cadence SKILL脚本语言大显身手的地方。本文要解决的就是如何利用SKILL脚本实现两个非常实用但官方工具并未直接提供的功能一键导出指定元件的详细封装图纸以及自动统计指定元件的引脚数量及类型。很多人以为SKILL语言高深莫测是Tool开发工程师的专属。实际上对于PCB设计工程师而言掌握一些基础的SKILL脚本就像程序员掌握了Excel宏或Python脚本一样能直接将重复、繁琐的劳动自动化极大提升设计效率和准确性。本文将从一个实际痛点出发手把手带你编写两个实用的SKILL脚本让你不仅“会用”Allegro更能“驾驭”它。2. 基础概念与核心原理SKILL是什么为什么是它在深入代码之前有必要厘清几个核心概念这能帮助你理解为什么SKILL是解决此类问题的最佳选择而不是其他方法。SKILL语言它是Cadence公司为其EDA工具套件包括Allegro、Virtuoso等开发的一种基于Lisp的交互式脚本语言。Lisp语言以其强大的符号处理和表处理能力著称非常适合处理EDA工具中复杂的层次化数据如网表、封装、约束。SKILL脚本可以直接在Allegro的CIWCommand Interpreter Window窗口中运行与设计数据库进行深度交互访问和操作任何设计对象如元件、引脚、走线、形状。与手动操作、Report功能的对比手动截图/标注完全依赖人工不可靠、不标准、无法复用。Allegro自带报告Tools - Reports功能强大但输出的是文本列表不直观。例如你可以生成元件列表报告但无法直接生成一个带有引脚编号和网络的独立图纸。报告功能是“数据分析”导向而非“图纸生成”导向。SKILL脚本可以精准定位到设计数据库中的任何一个对象比如名为“U1”的元件提取其所有属性位置、角度、封装名再进一步遍历其所有引脚获取引脚的编号、坐标、网络名甚至引脚类型通过焊盘名或属性判断。最后脚本可以控制Allegro生成一个新的设计文件.dra只包含这个元件并添加标注或者直接在CIW窗口输出统计表格。它是程序化、可定制、可复用的解决方案。核心原理拆解 我们的两个脚本都遵循一个相似的逻辑流程目标选择通过交互式命令或参数让用户指定一个元件例如通过鼠标点击或输入元件位号。数据提取利用SKILL内置函数如axlDBGetDesignaxlSelectByNameaxlDBGetPad深入到Allegro的设计数据库中获取该元件的所有几何和电气信息。逻辑处理对于导出脚本创建一个新的设计窗口将原元件的几何图形Symbol、引脚Pins、位号Ref Des复制过去并可选地添加引脚编号标注和网络名标注。对于统计脚本遍历元件的每一个引脚根据引脚连接的焊盘名通常包含“PIN”、“BALL”等信息或用户自定义属性将其归类到“电源”、“地”、“信号”等类别并进行计数。结果输出将处理结果以可视化的图纸.dra文件或清晰的文本报告形式呈现给用户。理解了这套“选择-提取-处理-输出”的范式你就能举一反三开发出更多自动化脚本来解决日常工作中的痛点。3. 环境准备与前置条件在开始编写和运行SKILL脚本之前请确保你的工作环境已就绪。软件与版本必需Cadence Allegro PCB Designer。本文演示基于 Allegro 17.4 版本但核心SKILL函数在16.6及以上版本中基本通用。请注意不同小版本间个别函数名或行为可能有细微差异但总体思路一致。推荐具备文本编辑器如Notepad、VS Code或UltraEdit用于编写和修改脚本文件.il文件。设计文件打开一个完整的PCB设计文件.brd。脚本需要在活跃的Allegro设计会话中运行。SKILL脚本加载方式 SKILL脚本文件通常以.il为后缀。要让Allegro识别并运行你的脚本有几种常用方法方法一直接加载在Allegro的CIW窗口中输入命令load(你的脚本路径/script.il)。每次重启Allegro都需要重新加载。方法二自动加载将脚本文件放入Allegro的本地或系统SKILL路径下并在allegro.ilinit文件中添加load语句。这样每次启动Allegro都会自动加载该脚本并可以将其绑定到菜单或快捷键上进阶用法。本文演示为了清晰和便于调试我们将采用第一种方法在CIW中直接加载写好的脚本文件。权限与备份脚本会读取和创建设计数据。在运行任何脚本尤其是涉及创建新文件或修改数据的脚本前请务必保存并备份当前的设计文件.brd。确保你对脚本文件所在的目录有读写权限。4. 核心流程拆解从想法到实现让我们将两个功能拆解成具体的、可执行的步骤。4.1 功能一导出单颗零件图纸这个脚本的目标是生成一个只包含目标元件的新.dra封装文件。用户输入脚本提示用户在PCB上点击选择需要导出的元件。获取元件对象通过选择操作获取该元件在数据库中的唯一标识DBID。提取元件信息从该DBID中提取关键信息如元件位号RefDes、所在的封装名Symbol、位置和旋转角度。创建新设计在内存中创建一个新的设计窗口axlDMOpenDesign。复制几何图形将原元件的封装图形Symbol Geometry复制到新设计中。复制引脚与属性将元件的所有引脚Pins和位号丝印Ref Des Text复制到新设计中。可选添加标注遍历每个引脚在其旁边添加文本标注显示引脚编号和/或网络名称。保存文件将新设计保存为.dra文件axlDMSSave通常以元件位号或封装名命名。清理与提示关闭临时设计窗口并在CIW中提示用户文件保存路径。4.2 功能二统计引脚数量这个脚本的目标是在CIW窗口或一个文本文件中输出目标元件的引脚分类统计表。用户输入同样提示用户选择目标元件。获取元件对象与引脚列表获取元件DBID并进一步获取该元件下的所有引脚对象列表。遍历与分类遍历每一个引脚对象。对于每个引脚获取其焊盘名Padstack Name。根据焊盘名中的关键词如包含“PWR”、“VDD”、“GND”、“AGND”、“PIN”、“BALL”等或引脚的NET属性将其初步归类。更精确的方法检查引脚是否具有PINUSE属性如POWERGROUNDSIGNAL这是最权威的分类依据。计数与汇总为“电源”、“地”、“信号”、“未定义”等类别设置计数器在遍历过程中进行累加。格式化输出将统计结果以清晰易读的表格形式在CIW中打印出来包括总引脚数、各类别引脚数及占比。可选输出到文件将统计结果同时写入一个.txt或.csv文件便于存档和分享。5. 完整示例与代码实现下面我们将提供两个完整的、可运行的SKILL脚本示例。请将以下代码分别保存为两个.il文件例如export_component.il和count_pins.il。5.1 脚本一导出单颗零件图纸 (export_component.il);----------------------------------------------------------------------------- ; 脚本名称: export_component.il ; 功能: 导出当前设计中选中的单个元件到一个新的 .dra 文件 ; 使用方法: 在CIW中输入 load(export_component.il) 然后输入 EXPORT_COMP ;----------------------------------------------------------------------------- (defun EXPORT_COMP () (let (comp compDBID symName refDes newDesignName) ; 步骤1: 提示用户选择元件 (axlClearSelSet) (axlSetFindFilter ?enabled (NOALL COMPONENTS) ?onButtons (COMPONENTS)) (printf 请在PCB上点击选择要导出的元件...\n) (setq comp (axlSelect axlSingleSelectPoint)) (when comp ; 步骤2 3: 获取元件信息 (setq compDBID (car comp)) (setq symName (axlDBGetProperty compDBID SYM_NAME)) (setq refDes (axlDBGetProperty compDBID REFDES)) (setq newDesignName (strcat refDes _export.dra)) (printf 选中元件: %s, 封装: %s\n refDes symName) (printf 正在创建导出文件: %s\n newDesignName) ; 步骤4: 创建新的设计 (axlDMOpenDesign newDesignName nil temp_export_lib t) ; 步骤5 6: 复制元件图形和引脚 (这里简化处理实际需复制symbol) ; 注意: 直接复制一个已放置的元件实例到新设计比较复杂。 ; 更稳健的方法是打开元件原始封装库(.dra)另存为新文件然后添加标注。 ; 以下代码展示核心思路可能需要根据实际情况调整。 (axlDBCopyDesign (axlDBGetDesign) (axlDMGetCurrentDesign) (,compDBID)) ; 步骤7: 添加引脚编号标注 (示例在引脚旁添加文字) ; 这里需要遍历元件的引脚并获取其位置来放置文本。 ; (pinList axlDBGetPins compDBID) ... 遍历pinList添加文本 ; 由于篇幅详细标注代码略可根据需要扩展。 ; 步骤8: 保存文件 (axlDMSSave (axlDMGetCurrentDesign)) (printf 文件已保存至: %s\n (axlDMGetCurrentDesignPath)) ; 步骤9: 清理 (不关闭窗口让用户查看) ; (axlDMCloseDesign (axlDMGetCurrentDesign)) (printf 导出完成\n) ) (printf 未选择有效元件。\n) ) ) ; 将函数注册为Allegro命令 (axlCmdRegister export_comp EXPORT_COMP)代码关键逻辑解释axlSetFindFilter和axlSelect用于设置选择过滤器并让用户交互式选择对象。axlDBGetProperty从数据库对象中获取属性如位号(REFDES)和封装名(SYM_NAME)。axlDMOpenDesign创建或打开一个设计。axlDBGetDesign和axlDMGetCurrentDesign获取源设计和目标设计的数据库对象。axlDBCopyDesign尝试复制设计数据。请注意直接复制一个已实例化的元件到空白设计可能不会完全成功因为缺少库链接。更可靠的方法是直接打开元件的原始封装文件进行操作。此示例提供了核心框架。5.2 脚本二统计引脚数量 (count_pins.il);----------------------------------------------------------------------------- ; 脚本名称: count_pins.il ; 功能: 统计选中元件的引脚数量并按类型电源、地、信号分类 ; 使用方法: 在CIW中输入 load(count_pins.il) 然后输入 COUNT_PINS ;----------------------------------------------------------------------------- (defun COUNT_PINS () (let (comp compDBID pinList totalPins powerPins gndPins signalPins otherPins pin) ; 步骤1: 提示用户选择元件 (axlClearSelSet) (axlSetFindFilter ?enabled (NOALL COMPONENTS) ?onButtons (COMPONENTS)) (printf 请在PCB上点击选择要统计引脚的元件...\n) (setq comp (axlSelect axlSingleSelectPoint)) (when comp ; 步骤2: 获取元件引脚列表 (setq compDBID (car comp)) (setq pinList (axlDBGetPins compDBID)) (setq totalPins (length pinList)) (printf \n 引脚统计报告 \n) (printf 元件位号: %s\n (axlDBGetProperty compDBID REFDES)) (printf 总引脚数: %d\n\n totalPins) ; 初始化计数器 (setq powerPins 0) (setq gndPins 0) (setq signalPins 0) (setq otherPins 0) ; 步骤3: 遍历并分类引脚 (foreach pin pinList (let (padstackName netName pinUse) (setq padstackName (axlDBGetProperty pin PADSTACK_NAME)) (setq netName (axlDBGetProperty pin NET)) (setq pinUse (axlDBGetProperty pin PINUSE)) ; 获取PINUSE属性最准确 ; 分类逻辑优先使用PINUSE属性其次根据网络名或焊盘名关键词判断 (cond ((equal pinUse POWER) (setq powerPins (1 powerPins))) ((equal pinUse GROUND) (setq gndPins (1 gndPins))) ((equal pinUse SIGNAL) (setq signalPins (1 signalPins))) (t ; 如果PINUSE未定义则根据网络名或焊盘名推测 (cond ((netName (rexMatchp “.*[Vv][DdCc][DdAa].*|.*PWR.*|.*PVDD.*” netName)) (setq powerPins (1 powerPins))) ((netName (rexMatchp “.*[Gg][Nn][Dd].*|.*GND.*|.*AGND.*|.*DGND.*” netName)) (setq gndPins (1 gndPins))) ((padstackName (rexMatchp “.*PIN.*|.*BALL.*” padstackName)) ; 假设信号引脚焊盘名含PIN/BALL (setq signalPins (1 signalPins))) (t (setq otherPins (1 otherPins))) ) ) ) ) ) ; 步骤5: 格式化输出 (printf 分类统计结果:\n) (printf 电源引脚 (POWER): %4d (%.1f%%)\n powerPins (* (/ (float powerPins) totalPins) 100.0)) (printf 接地引脚 (GROUND): %4d (%.1f%%)\n gndPins (* (/ (float gndPins) totalPins) 100.0)) (printf 信号引脚 (SIGNAL): %4d (%.1f%%)\n signalPins (* (/ (float signalPins) totalPins) 100.0)) (printf 未分类引脚: %4d (%.1f%%)\n otherPins (* (/ (float otherPins) totalPins) 100.0)) (printf \n) ; (可选) 步骤6: 输出到文件 ; (outfile outport “pin_report.txt” “w”) ; (fprintf outport “Pin Report for %s\n” refDes) ... ; (close outport) ) (printf 未选择有效元件。\n) ) ) ; 将函数注册为Allegro命令 (axlCmdRegister count_pins COUNT_PINS)代码关键逻辑解释axlDBGetPins获取元件下的所有引脚对象列表。axlDBGetProperty用于获取引脚的PADSTACK_NAME焊盘名、NET网络名和PINUSE引脚用途属性。PINUSE属性这是Allegro中用于定义引脚电气类型的标准属性POWER, GROUND, SIGNAL, UNSPEC等。在创建封装时若已正确定义这是最可靠的分类依据。rexMatchpSKILL中的正则表达式匹配函数用于判断字符串是否包含特定模式如“VDD”、“GND”。condLisp中的条件判断语句类似于if-else if-else链。分类策略采用了优先级先检查权威的PINUSE属性若未定义则根据网络名关键词推测若网络名也无特征则根据焊盘名是否为常规信号引脚焊盘含“PIN”来归类最后归为“未分类”。6. 运行结果与效果验证6.1 运行脚本将上述两个.il文件保存到本地目录例如C:\skill_scripts\。打开你的PCB设计文件.brd。在Allegro的CIWCommand Interpreter Window中输入加载命令load(C:/skill_scripts/export_component.il) load(C:/skill_scripts/count_pins.il)注意路径中的反斜杠\在SKILL中可能需要转义或使用正斜杠/。加载成功后CIW会提示t表示成功。运行命令输入export_comp并回车然后根据提示在PCB上点击一个元件如U1。输入count_pins并回车然后根据提示在PCB上点击一个元件如U1。6.2 预期输出与验证对于count_pins脚本 成功运行后你将在CIW窗口中看到类似如下的输出 引脚统计报告 元件位号: U1 总引脚数: 256 分类统计结果: 电源引脚 (POWER): 12 (4.7%) 接地引脚 (GROUND): 20 (7.8%) 信号引脚 (SIGNAL): 220 (85.9%) 未分类引脚: 4 (1.6%) 如何验证准确性交叉核对在Allegro中手动高亮显示该元件的所有电源网络如VCC3V3和地网络GND查看高亮的引脚数量是否与脚本统计的“电源引脚”和“接地引脚”数量大致相符。检查未分类引脚脚本输出的“未分类引脚”值得关注。你可以修改脚本让它在遇到未分类引脚时打印出该引脚的焊盘名和网络名帮助你判断是分类规则不完善还是封装定义本身有问题如PINUSE属性缺失。对于export_comp脚本 成功运行后脚本会提示文件保存路径例如U1_export.dra。你可以在Allegro中通过File - Open打开这个.dra文件进行验证。验证要点打开的文件是否只包含目标元件U1的图形元件的引脚、丝印层Ref Des, Value是否完整如果实现了标注功能引脚编号和网络名标注是否清晰、位置是否合适如果运行失败第一步仔细查看CIW窗口中的错误信息。SKILL的错误提示通常比较直接会指出是哪一行代码出了问题。常见原因文件路径错误、函数名拼写错误、在当前设计环境下某些函数不适用例如在非布局模式下调用布局函数。调试建议可以在脚本中关键步骤后添加printf语句打印出变量的值帮助定位问题。7. 常见问题与排查思路问题现象可能原因排查方式解决方案运行load命令后提示nil或错误1. 脚本文件路径错误。2. 脚本文件编码格式不对如UTF-8 BOM。3. 脚本中存在语法错误。1. 检查路径尝试使用绝对路径。2. 用文本编辑器将文件另存为ANSI或UTF-8无BOM格式。3. 查看CIW中具体的错误行号检查该行及附近的括号、引号、函数名。修正路径或文件编码。逐行检查语法确保括号配对。选择元件时脚本无反应或选不中1. 选择过滤器(axlSetFindFilter)设置不正确。2. 设计处于非编辑模式如仅查看模式。1. 检查axlSetFindFilter参数确保COMPONENTS在?onButtons列表中。2. 确认Allegro处于可编辑状态如Layout模式。调整选择过滤器参数。切换到正确的设计模式。count_pins统计结果全部为“未分类”1. 元件的引脚缺少PINUSE属性。2. 网络名/焊盘名关键词匹配规则不适用于当前设计。1. 在Allegro中查看一个引脚的属性确认是否有PINUSE。2. 打印几个引脚的NET和PADSTACK_NAME属性观察其命名规律。1. 在封装库中为引脚添加PINUSE属性。2. 根据实际命名规则修改脚本中的正则表达式关键词。export_comp导出的.dra文件为空或只有部分内容1.axlDBCopyDesign函数可能无法直接复制实例化元件到空白设计。2. 复制范围设置不正确。1. 查看生成的.dra文件确认缺失什么内容。2. 尝试使用axlDMCreateOpenShape等函数直接绘制或改用打开原始封装库的方法。采用更稳健的方法先通过axlDBGetProperty获取元件的SYM_NAME然后去库路径下找到对应的.dra文件进行复制和修改。脚本在别人的电脑或新版本上不工作1. SKILL函数在不同版本间有变更或废弃。2. 环境变量或库路径不同。1. 查阅对应版本Allegro的SKILL API文档。2. 检查是否有函数被标记为obsolete过时。1. 使用版本兼容性更高的通用函数。2. 在脚本开头添加版本判断逻辑或提供替代方案。8. 最佳实践与工程建议将SKILL脚本从“能用”提升到“好用”和“耐用”需要遵循一些工程化实践。脚本健壮性错误处理使用catch和throw或error处理来捕获异常避免脚本意外崩溃导致Allegro不稳定。例如在文件操作、选择操作外围添加错误判断。输入验证在函数开始处验证输入参数的有效性。例如检查用户是否真的选择了一个元件 (when comp ...)。资源释放如果脚本打开了临时设计或文件确保在函数结束或出错时正确关闭它们。代码可维护性添加注释像示例中那样在文件头、函数定义和关键逻辑处添加清晰注释说明用途、参数和返回值。模块化函数将复杂功能拆分成小函数。例如将“分类引脚”的逻辑单独写成一个函数classifyPin(pin)提高代码可读性和复用性。定义常量将魔法数字或字符串如分类关键词“POWER”、“GND”定义为文件开头的常量便于统一修改。用户交互友好性进度提示对于遍历大量引脚的操作可以使用axlUIWPrint或定期printf来显示进度让用户知道脚本正在运行。结果可视化除了在CIW输出可以考虑用axlMsgPut在图形界面弹出提示框或者将统计结果生成一个简单的文本文件保存在固定位置。参数化允许用户通过对话框输入参数。例如让用户选择导出图纸的层、标注的字体大小或者指定统计报告的输出路径。可以使用axlForm函数创建简单的GUI。集成到Allegro环境菜单集成在allegro.ilinit文件中使用axlMenuInsert等函数将你的脚本命令添加到Allegro的菜单栏中方便点击使用。快捷键绑定为常用脚本分配快捷键进一步提升效率。自动加载将调试好的脚本放入PCENV目录或通过allegro.ilinit自动加载使其成为你的个人定制化工具集的一部分。版本管理与分享使用Git等版本控制工具管理你的SKILL脚本记录修改历史。在团队内部分享脚本时务必附带一个简明的README.txt说明功能、依赖、使用方法及已知限制。9. 总结与后续学习方向通过本文我们不仅完成了“导出单颗零件”和“统计引脚数量”两个具体脚本的编写更重要的是我们建立了一套利用SKILL解决PCB设计自动化问题的通用思路识别重复痛点 - 分析数据对象 - 使用SKILL API访问 - 处理逻辑 - 输出结果。这两个脚本是起点而不是终点。基于这个框架你可以尝试更多自动化任务批量操作修改脚本使其能批量处理多个选中的元件甚至整个BOM中的元件。增强导出功能在导出的图纸中自动添加引脚列表表格、元件尺寸标注、或特定的层叠信息。更智能的统计结合约束管理器Constraint Manager的数据统计特定电压域的引脚数或高速信号如差分对、DDR的引脚数。设计检查编写脚本自动检查常见设计问题如未连接的电源引脚、间距违规的元件、缺失的阻焊桥等。要深入学习SKILL建议查阅官方文档Cadence安装目录下的doc文件夹里通常有SKILL语言参考和API文档如skill.pdfskillref.pdf。这是最权威的资料。利用内置帮助在Allegro CIW中输入help或help ‘function-name可以查看函数说明。分析现有脚本Cadence自带了许多SKILL脚本通常以.il结尾在安装目录中搜索并阅读它们是学习高级用法的绝佳途径。实践与调试从解决身边的小问题开始多写多试。利用CIW的交互模式可以逐行执行代码片段观察结果这是快速掌握SKILL的秘诀。将SKILL脚本融入你的日常工作流就像为Allegro装上了一副“机械外骨骼”能让你从繁琐的重复操作中解放出来专注于更有创造性的设计工作。建议你将本文的示例脚本保存、修改并应用到实际项目中体会自动化带来的效率提升。