1. 从验证被堵到AI入场:EDA正在经历一场底层变革
我是在一次回归测试堵了快十二个小时之后,开始认真对待“大模型正在改变EDA”这句话的。那天晚上,仿真队列一直跑不完,我盯着日志里的同一个语法报错,突然意识到:如果机器能理解自然语言描述的设计意图,那么它至少能替我干掉大量重复性验证工作。这不是未来故事,而是过去一两年里已经实实在在发生的事。
EDA,全称电子设计自动化,是芯片设计从架构到流片的整套工具链。过去三十年,这个领域的核心逻辑是“人写代码,工具跑流程”,工程师写RTL、写约束、写脚本,工具做综合、仿真、布局布线。现在,大模型开始介入这条链路,它带来的不是某一款工具的升级,而是工程师与工具之间的交互方式、问题定位方式、代码生成方式,乃至整个设计流程的组织方式,都在被重新定义。
这篇文章不打算给你灌概念。我想根据自己把大模型塞进日常芯片设计工作流的实际经历,聊聊它目前在EDA里到底能干什么、不能干什么、怎么用才不翻车,以及一个普通数字前端工程师如何从零开始把大模型接入自己的验证与设计流程。无论是刚接触芯片设计的学生,还是已经写了多年RTL的工程师,这篇文章里应该都能找到可直接落地的思路。
2. 拆解大模型进入EDA的三个切入点
2.1 EDA流程里最痛的三块“硬骨头”
要理解大模型为什么能改变EDA,得先看清EDA流程里哪些环节最耗人。芯片设计流程大致包括架构设计、RTL编写、功能验证、逻辑综合、时序分析、物理实现、可测性设计等环节。其中最耗费人力的三块是:RTL代码编写、验证环境搭建、时序与约束问题排查。
RTL代码编写看似是“设计”的核心,但日常工作里,数不清的模块其实是在重复写接口逻辑、状态机骨架、寄存器配置块。验证环境搭建更是体力活,搭testbench、写断言、配覆盖率模型,本质上是在跟验证语言和工具API打交道。而时序与约束问题排查,则是典型的“大海捞针”:几百条violation路径里,只有一两条是真正需要改代码的。
这三块硬骨头有一个共同特征:高度依赖语言表达能力、模式识别能力和大量历史经验积累。恰恰是这类任务,对大模型来说天然比“做数学题”更合适。
2.2 大模型带来的是“人机交互范式”的切换
传统的EDA交互模式是“命令行加脚本”,工程师必须把意图翻译成工具能理解的精确语法。比如为了检查某个信号是否在特定时钟沿之后稳定,你得写一条SVA断言,语法错了连编译都过不去。
大模型改变了这一层。它让工程师可以用接近自然语言的方式描述意图,再由模型把意图转换成工具链能执行的东西。你可以直接说“帮我在valid拉高后三个周期内检测ready必须保持稳定”,模型帮你生成对应的SVA断言。这个过程看似只是多了一层翻译,实际上是交互范式从“人迁就工具”变成“工具迁就人”。
这个切换的意义非常深远。芯片设计领域人才门槛高,一部分原因就在“工具语言”极其陡峭。如果大模型能把这个门槛往下拽一大截,更多工程师能把精力从语法细节转移到设计本身上来。
2.3 三类任务最适合被大模型接管
在踩了一年的坑之后,我总结出三类大模型在EDA里最值得用的任务。
第一类是纯转化类任务:把一种表达形式变成另一种。SystemVerilog转Verilog、把波形描述转换成SVA断言、把C模型翻译成行为级RTL、把文档描述整理成寄存器列表,这类任务几乎没有歧义,大模型的成功率非常高。
第二类是脚手架类任务:搭验证环境、生成模块骨架、自动补全接口逻辑。这类任务生成的代码即便不是最终版本,也能让工程师省掉四十分钟的“搭台子”时间。
第三类是搜索与解释类任务:给出一段未经注释的老代码,让模型解释它的功能;抛出数百行仿真日志,让模型帮忙定位根本原因;或者在一堆时序报告里,用对话方式层层追溯,直到找到可疑的顶层设计决策。
这三类任务有个共性:它们在传统工作流里占据大量时间,但本身不产生“新的设计知识”,更像是“已知规则的搬运工”。大模型做搬运工,比人快得多。
3. 实操落地:大模型辅助RTL设计与验证的完整过程
3.1 选型与部署:本地模型还是云端API
想在工作流里用上大模型,第一关是选模型。我建议根据数据的敏感程度做区分。
如果做的是预研项目或教学场景,数据脱敏后可以直接用云端API,优点是模型强、不占本地资源,缺点是延迟不稳定。如果做的是公司内部项目,设计数据不能出内网,就得在本地部署开源模型。实测下来,7B到13B参数的代码类模型,在生成RTL和SVA断言上已经够用;再往上到30B级别,效果有明显提升,但对硬件资源要求也成倍增加。
一个比较现实的折衷方案是“本地小模型加云端大模型”双轨制:日常简单代码补全用本地小模型保证隐私和速度,遇到复杂架构设计讨论就把关键代码段脱敏后交给云端大模型。
3.2 搭建一条“自然语言到SVA断言”的流水线
我真正花时间做的第一件事,是搭了一条“自然语言描述到SVA断言”的小工具链。这里写一个简化版思路,你可以直接参考。
流程是这样:把自然语言描述输入大模型,让它输出SystemVerilog断言代码,同时生成对应的模块接口示意。我用的提示词大致如下:
你是一个SystemVerilog验证专家。 请根据以下自然语言描述,生成SVA断言代码,同时解释每一条断言检查的是什么场景。 描述: 信号a_pulse是一个单周期脉冲。 当a_pulse拉高后的下一拍,b_valid必须在高电平,且保持至少3个周期。 所有信号都以posedge clk采样。异步复位信号为rst_n,低有效。模型输出的结果通常已经可以直接用了。下面是我实际拿到过的一段输出,贴出来供你感受水平:
property p_b_valid_after_a_pulse; @(posedge clk) disable iff (!rst_n) $rose(a_pulse) |=> $rose(b_valid) and (b_valid throughout $past(b_valid, 2)); endproperty assert property(p_b_valid_after_a_pulse);这段代码如果人写,大概需要三分钟。模型生成,十秒内就完成了。更关键的是,在我需要覆盖几十条类似断言时,提示词只需要批量替换描述里的信号名和行为,一次能省掉半天工作量。
3.3 用模型推理仿真日志的错误根因
仿真日志排查是我个人觉得性价比最高的大模型应用场景。过去遇到大量类似“testbench挂了但不知道哪一层的逻辑错了”的情况,人工去翻几千行日志,往往要花一个多小时。
现在的做法是:把仿真日志截取最近两百行,连同对应的RTL代码片段一起抛给大模型,并给出上下文描述。我会在提示词里加一句约束:“请先给出最可能的三类原因,再给出验证步骤,暂时不需要改最终代码。”
这个“先给原因再给方案”的约束非常关键。如果不加这句,模型往往会直接给出一个看似合理的“修复代码”,但如果基于的根因判断是错的,反而会浪费时间。先让它定位方向,工程师再针对方向去验证,效率高得多。
下面是我记得很清楚的一次实际案例。某次仿真报错显示“信号一直处于X态”,我把波形导出的日志和代码段整理好,喂给了模型。它给出的三类原因里,第一类是“跨时钟域的同步器缺失或复位不完全”,第二类是“case分支未覆盖导致寄存器未初始化”,第三类是“仿真器对initial块的解析时序与预期不一致”。我沿着第一条去查,果然发现某一个子模块在上电阶段接收到了来自不同时钟域的复位信号。这是真实节省了将近两小时的排查时间。
3.4 让模型帮你搭“验证环境脚手架”
验证环境里有一种很烦的工作:搭一个新的测试用例时,要把一堆标准的组件路径、宏定义、接口配置全部拼一遍。这些内容不复杂,但有一大堆重复约定。
我用大模型的做法是,先把一个已存在的成熟测试用例文件发过去,说明“这是一个标准用例结构”,再把新用例的需求描述发过去,让模型基于结构模板生成新用例。实测下来,生成的框架代码里接口信号名以及文件的include关系都对得上,只有少数参数需要手动修正。
这个用法也解释了为什么大模型在EDA里的价值不只是“写代码”,还在于“模式延展”。它看过足够多同一项目的代码后,能非常准确地抓住这个项目的代码风格和架构约定,生成的东西马上能用,而不是需要大改。
4. 工具链集成:把大模型组装进已有的EDA环境
4.1 命令行里的“AI助手”封装
想要在日常流程里用上大模型,字符串式网页对话并不方便。我习惯把模型封装成一个命令行工具,这样在终端里随时可以用。
做法很简单,用脚本包一层提示词模板,加上历史对话记录缓存,然后以子进程方式批量处理文件。
llm_eda "帮我给data_valid信号加一条sva断言: 它在req_valid拉高后的2拍内必须拉高"底层逻辑是:第一条提示词被拼接到系统预设语境中,模型输出的内容直接追加到当前目录下的一个日志文件里,方便回头查看。我顺手把输出结果也格式化一份,以便直接复制进验证环境去编译。
这一步带来的改变是:我不需要切换窗口去网页对话框,可以直接在编译报错后立刻把报错信息丢给模型。对于高频小任务,这个“即时响应”体验比任何花哨的功能都实际。
4.2 与仿真相面的自动化回调
比起“我自己去问大模型”,更有价值的集成是“工具主动把信息喂给模型”。目前部分EDA平台已经开始做AI助手嵌入,但距离人人都能顺畅使用还有距离。我的实践是写一个基于脚本仿真的回调函数:一旦编译报错,自动抓取当前文件和报错行;一旦仿真失败,自动抓取失败日志的尾部片段。
把这些文本拼成预设的提示词模板,用脚本调用大模型接口,然后把回复输出到终端。整个流程跑下来,人要做的事情就只剩:看模型给的原因分析,然后决定下一步动作。
这个“环境主动呼叫AI”的思路,是真正把大模型装进流程的开始。它不需要你去思考“什么时候该问大模型”,而是让工具在失败点自动问。
4.3 版本管理里的“AI注释生成器”
还有个实用小工具是“代码变更说明自动生成器”。在每次提交代码前,用脚本把Git的diff内容发给大模型,让它生成一段变更说明。它给出的说明通常比我自己敲的提交信息要准确细致得多,对于需要写详细改动记录的场合非常有用。
有一点要提醒:大模型并不清楚你这次提交背后的“真实原因”,它只能根据代码差异推断。所以在提交说明里,我只会把模型生成的“客观差异描述”作为草稿,再补充一句“为什么要这么做”的主观说明。两者一拼,提交信息质量提升明显。
5. 避坑指南:大模型介入EDA的四大典型问题
5.1 幻觉:看着对,实际上错得离谱
大模型在EDA领域最危险的问题就是幻觉。它经常会生成“看似存在但实际并没定义”的信号名、模块名,或者在状态机里加一个根本不存在的状态。这种错误不像语法错误那样有编译器拦截,它会被集成到代码里,然后在仿真阶段造成更隐蔽的问题。
我的经验是:凡是模型生成的内容,必须编译,必须仿真,必须过lint,三步缺一不可。尤其在时钟域、复位逻辑、跨模块信号这些容易“埋雷”的地方,宁可多花点时间人工审查,也不要信任模型的“我觉得”。
5.2 上下文窗口有限,长代码理解能力受限
很长一段代码,或者一个拥有数百个文件的大模块,大模型的上下文窗口通常覆盖不了。硬塞进去会导致它只关注片段,忽略全局。
应对策略是“分而治之”。把一个大文件拆成“接口声明区”、“逻辑实现区”、“约束描述区”,分别分析,再把分析结果整合。这相当于逼着模型先从局部建模,再在更高层级汇总。从实践结果看,拆解后的分析质量远高于一次性投入完整代码。
5.3 风格不一致:个人偏好无法通过单次对话固化
每个芯片设计团队都有自己的代码规范,比如命名风格、注释要求、状态机写法约定。大模型对这类“潜规则”没法单靠几个提示词完全掌握。
我建议建立一个“风格示例文件夹”,里面放三到五个团队公认的优秀实现。每次让模型生成代码时,附上一个示例文件作为风格参考。实测效果显著,生成的注释习惯和代码排列方式会更贴近团队预期。
5.4 敏感数据合规:不能为了省力把设计核心传出去
芯片设计数据几乎都是企业核心资产。使用云服务大模型时,千万要仔细确认发送的内容是不是已经脱敏;如果项目保密等级高,就必须走本地部署方案。
我在这件事上吃过亏。早期图省事直接用了云端服务,虽然传输的是测试用例,后来还是被安全同事约谈。从那以后,我给自己定了一条铁律:所有设计代码一律进本地模型,涉及跨团队保密内容的一律不传云端。
6. 常见问题排查实录与经验速查表
6.1 生成代码编译不过,先查这五个点
模型生成的SystemVerilog代码编译不过,我按频率排序的排查清单如下,你可以直接参考:
| 问题类型 | 典型现象 | 快速检查方式 |
|---|---|---|
| 信号名张冠李戴 | 编译报no such signal | 对照模块接口声明逐一核对 |
| 数据类型错误 | 位宽不匹配、逻辑/位混合 | 检查声明的logic/reg/wire类型 |
| 时钟沿写错 | posedge误写成negedge | 搜索代码里所有@(posedge/negedge) |
| 宏未定义 | 报unknown macro | 检查include的是哪个头文件 |
| 数组越界 | 仿真时index out of range | 检查循环边界和数组声明位宽 |
我遇到过最多的情况是第二种和第四种。特别是宏未定义,模型很可能会假设某个宏是标准库自带的,而你的项目根本没包含这个头文件。
6.2 模型答非所问,可能是提示词的问题
有段时间我发现大模型给的建议总是“答非所问”,仔细排查后发现是提示词表达太模糊。比如“帮我看看这段代码有没有问题”——这个描述太宽泛,模型不知道你是要查功能逻辑还是查语法错误还是查可综合性。
后来我把请求都改成了结构化格式,用回答效果明显改善:
# 任务:代码审查 # 检查重点:跨时钟域同步、复位完整性、状态机跳转 # 输出格式:先列问题清单,再给出修改建议 # 背景:这是一个用于PCIe接口的接收侧状态机,时钟频率250MHz这种结构化的提示词引导模型聚焦,而不是天马行空乱猜。如果你发现模型输出质量忽高忽低,大概率不是模型变了,而是提示词没有给足上下文。
6.3 打开编辑器插件就卡顿,别高估本机资源
有一阵子我推荐项目组同事用某个编辑器里的AI补全插件,结果低配工作站的代码提示反应慢得没法用。排查下来发现,默认配置下插件会给每个文件建立索引,在大型RTL工程里会占用很高的内存。
解决办法是调整插件配置,把自动索引改成手动触发,同时只在打开核心模块文件时才启用深度分析。在拿到专用硬件资源之前,建议代码补全类功能跑在轻量模型上,把复杂分析留给服务器端。
6.4 数据脱敏最容易被忽略的细节
做数据脱敏的核心原则是“能不给就不给”。如果只是让模型帮忙搭验证环境框架,根本不需要给它完整RTL,你只要给模块的端口列表和接口描述就足够。
以下是我自己的脱敏清单:
- 项目名和模块名:替换为无意义代号;
- 信号命名:保留逻辑含义,删掉项目特定前缀;
- 参数和宏常量值:改成占位符或随机量;
- 注释中的所有具体情景描述:改成泛化表达。
养成“默认全员脱敏”的习惯,比事后补救稳妥得多。
7. 我个人的一些体会和后续规划
做了半年多的尝试之后,我最大的感受是大模型没有“一下子就颠覆EDA”,但它确实在每一个环节都潜移默化地改变了时间和精力的分配。以前我花两小时完成一个测试用例的搭建,现在二十分钟搞定;以前遇到异常仿真信号,我要在波形和日志之间来回切换,现在可以让模型在几秒内给出几个高概率的排查方向。节约出来的时间,我基本都投去看架构文档和设计规格——这对一个数字前端工程师成长的价值,远超出“代码写得快”。
踩过几次坑之后,我现在更愿意把大模型定位成“一个极其熟悉项目代码风格、但偶尔会胡言乱语的新人同事”。它为我省下了大量体力活,同时它给出的每一条内容都必须被检查、仿真和验证。与其说大模型替代了EDA里的哪个岗位,不如说它在逐步改变每个EDA从业者每天醒着的那十几个小时怎么分配。
我自己的下一步计划,是继续把大模型嵌得更深:让它在综合阶段帮助解析时序报告、在物理实现阶段辅助分析拥塞和布线密度、在跨时钟域检查阶段自动生成CDC验证断言。这些方向不像“写代码”那么直接见效,但一旦跑通,价值会更大。如果你也在做类似的事情,欢迎一起交流各自的落地路径,一个人踩坑总是慢的,几群人一起踩,路才能越来越平。