AI 帮我实现的 SKILL 脚本,效果如何?

分享我是如何从一个最简单的想法出发,通过与 AI 的不断对话、迭代和调试,一步步将“批量 DRC一键验证”的工具从 0 到 1 搭建起来的。

兔二思
兔二思
技术博主

Hi,大家好。

上次文章的结尾挖了个坑,说要和大家分享用 AI 辅助编写 SKILL 脚本的实战案例。

今天,我来填坑了!

先不讲过程,直接给大家看下我使用 AI 撰写的脚本成品 —— 一个支持 DRC/LVS/xRC 一键批量验证的工具:

👇👇👇

wxv_4136105736038481941

在今天的文章中,我会以其中的“批量 DRC”功能为例,手把手带你走一遍,从一个模糊的想法开始,我是如何通过向 AI 提出问题,一步步将它变为现实的。

{ “v2.0 Batch DRC SKILL 脚本” & “与 AI 的完整 Chat 记录” 见文末 }

这篇文章,与其说是我的经历分享,不如说是一份给 AI 的“使用说明书”,希望能给你带来一些启发。

Part 1 . 从一个简单的需求开始

🗣️ 如何将一个模糊的需求,通过与 AI 的对话,逐步细化为具体的技术方案?

作为版图工程师,每次画完一个 Cell,都要跑一遍 DRC/LVS 检查,于是你打开 Calibre,配置 Rule 文件,指定输出路径,点击运行…… 等待结果出来后,再打开报告查看错误数量。

进入后仿阶段时,还需要对必要的模块,进行一遍 xRC 的后仿提取流程。如果要验证多个 Cell,那就要重复 N 遍 ……

虽然这个过程已经很熟练了,但我们总是会有偷懒的想法,比如 “能不能把每天重复的 DRC/LVS 流程自动化?”

这个想法很好,但很模糊。

经过长时间的和 AI 对话实践,我知道如果直接把这个模糊的想法丢给 AI,它大概率会回敬你一堆让你怀疑人生的代码。🤨

所以,真要实现起来,第一步不是直接冲上去让 AI 写代码,得先让它帮我把想法,梳理成一份能看懂的需求清单(prd.md)。

第一次对话:向 AI 描述你的目标

我们可以把 AI 当作一名技术顾问,第一次对话时,向它描述你的目标,然后请它帮你梳理实现路径:

{ 第一次对话:我的输入 }

你看,我这个 Prompt 的核心不是让 AI 给我代码,而是帮我理清思路和告诉我你需要什么信息。

然后 AI 就会像一个项目经理,帮你把模糊的想法,拆解成一份结构清晰的需求文档,让你清楚的知道下一步需要做什么,准备什么。

{ 第一次对话:AI 的输出 }

AI 把 DRC 自动化分解为“设计准备”、“DRC环境配置”、“执行参数设置”、“DRC执行阶段”、“结果处理阶段”和“清理和通知”这 6 个主要步骤,以及告诉我需要准备“设计相关的库名、cellName、viewName”、“工艺文件信息”、“输出目录日志位置”和“错误处理策略”。

第二次对话:提供必要的信息

现在我们已经梳理好了思路,下面就得把任务细节信息交代清楚。我当时整理了一份详细的需求清单,一次性“喂”给了它。

{ 第二次对话:我的输入 }

AI 在获取需求后,很快就交付了第一版代码,一个能对单个 Cell 执行 DRC 的脚本就这样诞生了:

{ 第二次对话:AI 的输出 }

Part 2 . 脚本的优化迭代

🗣️ 当需求变更、代码报错时,如何与 AI 沟通?

脚本的功能框架看起来都不错,但当我在 Virtuoso 中测试时,果不其然,代码报错了。😣

我遇到的第一个错是:ERROR: Failure to open input file *.gds

{ 运行脚本后提示错误 }

这时,我的第一反应,不是直接把这个错误丢给 AI 问 “怎么办”,而是想先凭经验分析一下:

“这个打开 GDS 的步骤是在哪个阶段发生的?”

所以,我手动使用命令行运行了一遍 Calibre 命令,执行后 Calibre 也出现了报错信息。

我这才发现我漏掉了一个关键步骤,目前我本地的 DRC 规则文件是初始配置,Calibre 运行时并不知道要去检查哪个 GDS。平时手动操作时需要修改 Rule 当中的 GDS 和 Cell 名称这些信息,而我没有把这些提供给 AI,自然是会出错的。

第三次对话:完善 DRC Rule 文件配置

分析清楚后,我向 AI 解释了具体情况:

{ 第三次对话:我的输入 }

以及提出了解决方案的想法:创建临时规则文件,配置具体的 GDS 路径信息。

{ 第三次对话:我的输入 }

AI get 到了我的意思,它加上了创建临时文件的功能:

{ 第三次对话:AI 的输出 }

好了,问题解决。

{ 脚本成功运行 }

有时候我们在遇到脚本错误,可先凭自己的经验分析错误。如果能定位问题,将分析过程提供给 AI,能提高解决效率。

第四次对话:实现批量处理能力

单个 Cell 的 DRC 验证成功后,我开始考虑更实用的场景:批量处理。

我想要实现“批量处理”功能,但还是只有零散想法,不确定哪种实现方式更好,我拿不定主意。

这时与其自己苦思冥想,不如把这个开放性问题抛给 AI:

{ 第四次对话:我的输入 }

它像一个架构师一样,为我设计了三种设计方案,还分析了各个方案的优缺点:

{ 第四次对话:AI 的输出 }

这能打开你的思路,帮你从一个更高维度审视问题,做出决策。

最后我采用了它推荐的“混合方案”:

  1. 创建两个专门的函数,分别处理不同的批量模式

runDrcOnCells(libName cellList drcRulesFile layerMapFile)

runDrcOnLibrary(libName drcRulesFile layerMapFile)

  1. 创建一个内部通用函数,统一批量处理逻辑

  2. 提供一个配置接口,用于未来复杂需求

方案敲定,AI 也很快生成了第一版批量处理的代码:

{ 第四次对话:AI 的输出 }

然而,又被一个错误拦住:Error* return: return can only be used within a prog . 这次问题出在了 SKILL 语言的语法细节上。AI 在一个 let 代码块里,想当然的用了 return() 函数,但这在 SKILL 里是不允许的。

这里,我直接把“具体的错误信息”和“对问题的分析”发给了 AI,希望它能快速定位问题修复代码:

{ 第四次对话:我的输入 }

解决了语法问题后,批量 DRC 功能也能跑通了。

{ 批量验证的脚本成功运行 }

第五次对话:文件组织优化

随着功能的完善,我发现了新的问题:所有生成的 GDS 文件、日志、报告都散落在当前目录,几十个文件混在一起。

当即给它提了个新需求:把每个 cell 生成的文件,都归档到各自独立的文件夹里:

{ 第五次对话:我的输入 }

AI 理解了需求后,询问了一些细节:环境类型、目录创建失败的处理策略、Calibre 命令的工作目录切换等。

我们最后一起敲定的目录结构设计如下:

当前工作目录/
├── myDrcDir/                  # 批量DRC总工作目录
│   ├── INV/                   # cell专属子目录
│   │   ├── INV.gds            # 该cell的GDS文件
│   │   ├── INV.strmout.log    # STRMOUT日志
│   │   ├── INV.drc.results    # 该cell的DRC结果数据库
│   │   └── INV.drc.summary    # 该cell的DRC总结报告
│   │   └── tmp_drc.rul        # 临时规则文件
│   ├── TIE1/
│   │   ├── TIE1.gds
│   │   └── ...
│   └── NAND2/

这听起来是个很简单的文件操作,对吧?AI 很快就重构了代码。但当我再次运行时,一个诡异的事情发生了。

CIW 窗口打印出了 “✓ 目录创建成功”,但下一行却又报错 “✗ 无法创建目录,停止处理”

这次我不知道问题出错在哪了,因为现在的脚本内容已经很庞大了,靠我自己去定位有点难。所以,我将 CIW 窗口中的完整日志输出直接发给了 AI,让它来调试和修复脚本。

{ 第五次对话:我的输入 }

它在获得了完整的上下文后,准确定位到了问题:一段 if 语句因为 SKILL 语言的‘隐式返回’特性,在成功执行后却返回了 nil,导致了后续的逻辑判断失败。

第六次对话:统计 DRC 错误的单元和个数

到这个阶段,脚本的核心功能已经很完善了,但我希望能获得更直观和准确的验证结果。仅仅知道 DRC 检查是否“成功”是不够的,我还需要知道每个 Cell 是 PASS 还是 FAIL 以及具体的错误数量。

这次,我向 AI 提出了一个详细的需求,我将这个版本定义为 v1.4。核心思路是:

  1. 在执行 DRC 时,将完整的命令行输出保存到一个日志文件里。

  2. 脚本执行完毕后,自动读取这个日志文件。

  3. 从文件中找到包含“TOTAL RESULTS GENERATED”的关键行,并解析出错误数量。

  4. 在最终的报告中,汇总所有单元的错误统计。

{ 我对 v1.4 版本需求的完整描述 }

这次协作的很顺利,脚本运行后没有出现错误。最终输出的统计报告,内容和格式,都非常满意。😄

{ AI 交付的 v1.4 版本的报告 }

我跑下整个库的 DRC 验证,给大家看下实际运行的结果:

{ 跑整个库的运行过程展示 }

Part 3 . 为脚本加入图形用户界面 (GUI)

🗣️ 从“能用”到“好用”的 GUI 设计之旅

在完成了核心功能的开发后,脚本虽然已经“能用”,但它还是一个需要通过命令行参数来运行的工具。

对于不熟悉 SKILL 语言的伙伴来说,还是有着使用门槛,他需要记住命令的格式、理解每个参数的含义、再手动输入长长的文件路径。像这样的路径设计,会增加他们的使用阻力。

所以,为了让这个工具能真正地在团队中推广开来,我进入了脚本开发的第三阶段:

为脚本创建一个图形用户界面 (GUI)。

我的目标,并非简单地加一个“外壳”,而是要与 AI 协作,设计出一个易用的交互界面。

下面,我会通过三次对话,来介绍 GUI 的设计过程:

➊ 与 AI 展开头脑风暴,共同构思 GUI 的界面布局。

➋ 让 AI 将我们的设计讨论,沉淀为一份正式的技术规范。

➌ 要求 AI 严格依据设计文档,完成最终的代码实现。

第七次对话:共同构思 GUI 界面布局

刚开始使用 AI 辅助 GUI 设计时,我那会儿的工作流是:先手动绘制一份界面草图,抓头挠耳的构思老半天,直到把所有细节都想清楚后,才交给 AI 去完成脚本编写。但慢慢的协作经验变多,其实更应该选择快速开始,而不是纠结于完美方案。

所以这一次,我跳过了绘制草图的步骤,选择直接与 AI 开启关于界面设计的讨论:“根据现有脚本的参数,请帮我设计一个 GUI 界面。”

它提供了具体的组件建议,交互逻辑和一个文本输入框和单选框的基础布局:

+-------------------------------------------------------------+
|              批量 DRC 验证工具 v1.0                       |
+-------------------------------------------------------------+
|                                                         
| 库名 (Library):      [______________________________]       
|                                                         
| DRC 规则文件:        [______________________________] [浏览]
|                                                             
| Layer Map 文件:      [______________________________] [浏览]
|                                                             
|-------------------------------------------------------------|
|                                                             
| 运行模式 (Mode):                                            
|    (o) 处理整个库                                           
|    ( ) 处理指定单元格                                       
|                                                             
| 单元格列表 (Cells):                                         
|    +---------------------------------------------------+    
|    | INV,NAND2,                                     |    
|    | TIE1                                           |   
|    | (每行一个或用逗号分隔)                            |    
|    +---------------------------------------------------+    
|                                                             
+-------------------------------------------------------------+
| [ 运行 DRC ]                      [ 关闭 ]      [ 帮助 ]  |
+-------------------------------------------------------------+

在这个基础版本中,我发现库和 Cell 列表依旧需要用户手动输入,这点和我们追求的友好界面不符。于是,我继续和它讨论改进方向:能否让用户“选择”而非“输入”?

这整个过程中我们的对话一来一回,通过纯文本沟通,将一个模糊的界面想法逐步细化,最终敲定了界面的整体布局和组件类型:

+-------------------------------------------------------------------+
| Batch DRC Verification Tool v2.0                                
+-------------------------------------------------------------------+
| [ hiCreateVerticalBoxLayout ('mainLayout) ]       
|                                                    
|   +-----------------------------------------------------------+   
|   | [ hiCreateGridLayout ('configGrid) ] - 3行×3列完美对齐   
|   |                                                       
|   |   DRC Rule File:  [________________] [Browse...]        
|   |   Layer Map File: [________________] [Browse...]        
|   |   Library Name:   [下拉框_________] [Run Mode: 循环选择] 
|   |                                                   
|   +-----------------------------------------------------------+   
|                                                      
|   +-----------------------------------------------------------+  
|   | [ hiCreateVerticalBoxLayout ('targetLayout) ]         
|   | ?frame "Execution Target"                            
|   |                                                  
|   |   Execution Target: (when mode is 'Specified Cells')     
|   |   +-----------------------------------------------------+ 
|   |   | [ hiCreateHorizontalBoxLayout ('selectionLayout) ] |  
|   |   | +-----------------+ +-------+ +-------------------+| 
|   |   | | Source Cells    | | [>>]  | | Target Cells       |
|   |   | | [sourceCells]   | | [>]   | | [targetCells]      | 
|   |   | | (ListBox)       | | [<]   | | (ListBox)          |
|   |   | | - 8行高度       | | [<<]  | | - 8行高度           | 
|   |   | | - 多选支持      | |       | | - 最终执行清单       |
|   |   | +-----------------+ +-------+ +-------------------+  |
|   |   +-----------------------------------------------------+ 
|   |                                                    
|   +-----------------------------------------------------------+   
|                                                                  
+-------------------------------------------------------------------+
|                                             [ OK ] [ Cancel ] |
+-------------------------------------------------------------------+

第八次对话:让 AI 撰写 GUI 设计文档

以上这些关于讨论界面布局的对话,都散落在各个对话框中。在团队里协作过的人都知道,这种沟通方式像极了我们用聊天工具去敲定一个技术方案,这些临时的共识是脆弱的。它们很容易被遗忘,或是在后续的执行中被曲解。

如果我现在直接让 AI “根据我们的讨论写代码”,它很可能会基于对我们对话的模糊印象去自由发挥,最终交付一个偏离我们共识的版本。

所以,我多走了一步,让 AI 把这些零散的对话,沉淀下来:“请将我们刚才的对话内容,整理成一份详细的 GUI 设计方案文档。”

{ AI 生成的 GUI_DESIGN.md 文档 }

这份文档就像一份给 AI 的 “README”,把我们在对话中敲定的界面布局,和实现这个布局所需的技术细节,都明确的规定了下来。

有了这份设计文档,下一步就简单了:让 AI 严格按照这份文档,把代码写出来。

第九次对话:加入 GUI 界面功能

我将我们最终的设计文档 GUI_DESIGN 和上一版不带界面的脚本 runDrcBatch.il 一起发给了它:

{ 要求 AI 实现 GUI 的完整指令 }

这个 Prompt 的核心就是“约束”,给到 AI 的任务就是将设计文档 1:1 的“翻译”成代码。

AI 交付的代码在核心功能和布局上符合预期。尽管在最终运行成功前,我还是遇到了几个 SKILL 语法错误,但得益于我们的设计规范,整个过程并未发生大的返工。

Part 4 . 成果展示

经过多轮对话的反复打磨,最初那个“让 DRC 流程自动化”的模糊想法,终于变成了一个人人都能轻松上手的实用工具。

现在,我来展示一下最终的使用效果:👇👇👇

wxv_4136106790284951564

两种模式,兼顾效率与易用

为了满足大家的使用习惯,这个工具同时保留了两种操作模式:

⑴ 为“效率党”准备的命令行模式:

如果习惯了命令行的简洁高效,可以直接调用核心函数,一行命令搞定所有事。

; 对指定 Cell 列表进行 DRC 验证
runDrcOnCells("myLib" "INV,TIE1" "/path/to/drc.rules" "/path/to/layer.map")

; 对整个库进行 DRC 验证
runDrcOnLibrary("myLib" "/path/to/drc.rules" "/path/to/layer.map")

⑵ 为“所有人”设计的图形界面(GUI):

对于不熟悉 SKILL 的伙伴,GUI 提供了零门槛的操作体验。

; 启动图形界面
batchDrcGUI()

同时,你还可以将脚本绑定到 Toolbar 工具栏,创建一个专属按钮,彻底告别命令输入方式。

一目了然的验证报告

无论是哪种模式,当任务执行完毕后,脚本都会在 CIW 窗口打印出一份清晰的总结报告。你一眼就能看出哪些单元通过了检查,哪些单元需要你进一步关注。

========================================
 BATCH DRC PROCESSING SUMMARY
========================================
Total cells processed: 5
           Successful: 5
               Failed: 0
========================================
  DETAILED RESULTS BY CELL:
----------------------------------------
  TIE1                 : 0 errors
  INV                  : 2 errors
  NAND2                : 0 errors
  NOR2                 : 1 errors
  BUFFER               : 0 errors
========================================

实际应用场景

这个工具的价值,就是把我们从重复性的操作中解放出来:

➊ 新设计快速验证

过去,每完成一个新 Cell 的设计,都需要手动打开 Calibre,配置,运行,查看报告。现在,一键执行。

➋ 批量 Cell 的例行检查

当项目中包含几十个 Standard Cell 时,可以直接对它们进行批量验证。

➌ 设计变更后的回归测试

当 FAB 工艺规则或团队设计规范发生变化时,可以对整个库进行一次完整的测试,确保这次变更没有引入意料之外的新问题。

功能扩展

虽然这次我们主要实现了 DRC 功能,但因为我们在一开始就和 AI 一起打好了模块化的基础,整个框架很容易扩展。

扩展到 LVS 验证?

只需替换 Calibre 的命令参数(calibre -lvs),调整一下规则文件模板和错误解析逻辑。

扩展到 LPE 验证?

也许需要引入不同的工具链(如 PVS),我只需适配新的输出格式,并在界面上增加相应的配置选项即可。

Part 5 . 方法论

🗣️ “Prompt Engineering” 有哪些值得分享的 AI 协作方法论?

至此,我们已经完整回顾了工具从 0 到 1 的开发故事。但故事背后,更值得分享的是“方法”。

如何与 AI 对话,一步步转化为稳定可靠的代码?

小步快跑,快速迭代

你不可能通过一个 Prompt,就让 AI 直接给你最终的完美脚本。容易成功的路径,是应该把一个大目标分解成一系列小任务,然后逐一攻克。

我的开发路径是这样的:

单cell验证 → 修复规则文件 → 批量处理 → 文件组织 → 错误统计 → GUI界面

V0.1 : 先让单 Cell 验证跑起来
V0.2 : 修复 Calibre 规则文件的 Bug
V1.0 : 从单 Cell 升级为批量处理
V1.1 : 优化文件组织
V1.2 : 加入错误统计
V2.0 : 最后,为它穿上 GUI 的“外衣”。

每一步都建立在上一步的稳定版本之上。这样即使某一步出现问题,我们修复起来也相对轻松,不会推倒重来。

对话的质量,决定了产出的质量

🗣️ “Garbage In, Garbage Out.”

与 AI 的每次交互,都是在用你的输入换取它的输出。你输入给 AI 的对话质量,直接决定了它输出成果的质量。

在我们的实践中,这主要体现在两个方面 ——

➊ 当你提出需求时:提供“结构化的指令”,而不是“模糊的想法”。

在增加 GUI 功能时,我们没有直接说“给我做一个 GUI”,而是通过讨论,将需求沉淀为一份详尽的设计文档。

多花几分钟,把你的需求、上下文、约束条件思考清楚,远比拿到一堆不符合预期的代码再去修改要高效得多。

➋ 当 AI 犯错时:提供“可复现的线索”,而不是“无效的抱怨”。

AI 写的代码会出错,这再正常不过。关键在于你如何向它反馈错误。无效的抱怨,比如“你的代码跑不通”,对解决问题毫无帮助。

有效的反馈,应该包含:具体错误信息、你的分析和期望的修复方向。

当你把这些信息一起交给 AI 时,它能基于这些线索,快速定位问题并给出精准的修复方案。

把 AI 的“错误”变成项目规则

在合作中,我发现 AI 对于 SKILL 这种小众语言,它会反复在同一个语法点上栽跟头,比如混淆 let 和 prog 的区别、when 语句的用法,甚至一本正经的编造出一些根本不存在的函数。

一次又一次地纠正同一个错误,是低效的。我意识到,简单的纠错是不够的,需要一种方法,让 AI 从自己的错误中学习,并记住这些教训。

在开发结束后,可以让 AI 对之前的对话历史进行了一次复盘,让它梳理并总结出自己犯过的所有语法错误,并形成一份《SKILL 编程错误总结与规范指南》,供后续的开发遵守。

这样,通过引导 AI 复盘和总结,你可以将它的错误转化为项目的知识资产,构建一个越来越可靠的合作伙伴。

你才是项目的主导者

AI 的强项在于规划代码结构、提供技术方案、语法纠错以及生成文档。而你的强项是在于定义目标和方向、提供垂直领域的专业知识、以及对最终方案进行决策。

你需要发挥自己的专业经验,去弥补 AI 的认知局限。比如,AI 不知道 SKILL 处理中文字符有 Bug,也不知道 Virtuoso 环境的具体限制。这些都需要你来提供关键信息,并纠正它的“幻觉”。

写在最后

回顾整个开发过程 ……,AI 让我把时间花在了更有意思的地方 —— 比如琢磨下一个该“偷”什么懒,以及,如何更优雅地偷懒。

它不会替代我们的经验判断,不会替代我们对业务的理解,也不会替代我们的创新思考。但它能帮我们快速实现想法,高效解决问题。

对于我们来说,关键是要学会如何与 AI 协作,如何发挥各自的优势。

最后再给大家几个我的建议:

➊ 不要害怕尝试

从一个小需求开始,体验 AI 协作开发的过程。

➋ 保持批判思维

AI 的建议不一定都是对的,要结合实际情况判断。

➌ 注重实践验证

代码能跑起来才是硬道理,要在真实环境中测试。

➍ 持续总结优化

每次协作都是学习机会,要总结经验和教训。

希望今天分享的这套工作流,能帮助你把 AI 变成你的 “SKILL 编程” 伙伴。

⋅ END ⋅

本文演示的 v2.0 DRC SKILL 脚本和完整的对话记录,我已经把它整理好,放到了我的知识库中。感兴趣的朋友,可以在公众号后台回复 “AI SKILL” 获取。