教 AI 写对芯片代码:VerilogCL 如何用对比学习划出 Verilog 的对错边界

教 AI 写对芯片代码:VerilogCL 如何用对比学习划出 Verilog 的对错边界 论文解读 | VerilogCL: A Contrastive Learning Framework for Robust LLM-Based Verilog Generation让大模型写一段 Python 脚本如今已经不是什么新鲜事。但让它写一段真正能用的 Verilog事情就棘手起来。生成的代码看着有模有样编译器一跑就报错的情况比比皆是。更让人头疼的是另一类问题代码顺利通过了编译仿真结果却和设计意图对不上。硬件描述语言留给犯错的余地比软件代码小得多。香港科技大学广州校区微电子学域的研究团队提出了一个思路不同的框架 VerilogCL。它没有延续生成完再修补的老路而是用对比学习让模型在表示空间里分清正确与错误的 RTL 代码再在生成过程中实时筛查高风险片段。在 VerilogEval 和 RTLLM 两个公开基准上这套方法让一个 7B 参数的模型在编译成功率和功能正确性上超过了参评的商业大模型与 Verilog 专用模型。一、AI 写 Verilog为什么比写 Python 难得多大模型在软件代码上的成功很大程度上是数据堆出来的。GitHub 上海量的 Python 和 C 代码为模型提供了充足的学习材料。Verilog 的处境完全不同。公开可得的 Verilog 语料规模有限质量参差不齐很多代码还缺少配套的验证信息模型很难从中学到可靠的监督信号。数据上的贫富差距直接反映在了生成质量上。数据稀缺只是问题的一半。Verilog 不是一门描述顺序计算的语言它描述的是硬件结构、时序行为和并行信号之间的交互。软件代码按行执行一行写错程序往往直接崩溃错误暴露得很痛快。硬件世界里所有信号同时变化赋值方式、时钟沿、位宽声明任何一个细节都会改变电路的实际行为。Verilog 里一个局部的小偏差后果要隐蔽得多。论文里举了两个典型例子。在时序逻辑中混用阻塞赋值和非阻塞赋值或者把逻辑运算符和按位运算符搞混代码照样能通过编译直到仿真或综合时才暴露出功能错误。这类错误不会亮红灯却实实在在改变了电路的行为。编译器查的是语法查不出设计意图这是 Verilog 生成比软件代码生成更难做对的根本原因。错误的代价也不在一个量级。软件有 bug改完重新部署就行。硬件设计里的错误会顺着 EDA 流程一路向下传钻进昂贵的制造迭代里。一轮返工的代价足以让任何团队对 AI 生成的 RTL 保持警惕。可靠性成了大模型进入芯片设计流程的第一道门槛。现实中的使用流程也放大了这种不可靠。工程师把一句自然语言描述扔给模型比如设计一个 4 位加法器模型返回一段 module 定义接着送交编译器和测试平台验证。通过了皆大欢喜。失败了就把报错信息喂回去让模型改改完再验证如此循环。这个生成、编译、排错的环路转上好几轮是常态效率低还容易把设计意图越改越偏。二、现有方法的两条路线和它们共同的盲区面对这道门槛已有研究大致走出了两条路线。第一条是数据路线。VerilogEval 提供了经过筛选的监督基准RTLCoder 构造了对齐的自然语言与 Verilog 配对数据让模型见到更多带标注的样本OriGen 引入代码到代码的增强和自我反思机制进一步扩充训练信号。这些工作让模型更熟悉 Verilog 的领域知识生成质量确实在提升。第二条是修补路线。AutoChip、RTLFixer 等工作把编译器的报错信息反馈给模型让它一轮一轮地改。还有研究引入检索增强、多阶段调试和多智能体协作提高修复效率。也有方法把错误处理挪进解码阶段比如根据有效性动态调整采样温度或者用抽象语法树引导投机解码在生成时避开明显不合法的续写。两条路线都有成效论文则指出了它们共同的盲区。数据路线把 Verilog 生成当成普通的文本生成任务模型见过大量正确代码却没人明确告诉它错误代码长什么样、和正确代码的界线在哪里。修补路线的纠错全部发生在生成之后代码写完了、编译报错了才回头修本质上是输出层面的补救。在模型的内部表示里正确和错误的 RTL 依然混在一起。解码阶段的约束同样只是压制错误并没有教模型理解错误。论文对此有一个明确的判断。反复出现的生成错误根源不只是训练数据不足更在于模型对 RTL 有效性边界的表示不够清晰。打个比方模型就像一个刷了很多题却从没对过答案的学生题量不小对错误选项长什么样缺乏直观认识。生成、编译、排错的循环之所以低效正因为错误是在流程末端才被发现的。图 1现有基于大模型的 Verilog 生成流程。模型生成代码后交由外部验证工具检查错误反馈再驱动修复纠错发生在生成完成之后。来源原论文 Figure 1换个角度看这件事在别的领域早有成熟工具。对比学习在视觉表示和代码表示里被反复验证过思路是让相似样本的表示靠近、不相似的拉远。代码领域的 UniXcoder 用它对齐自然语言、代码和结构信号提升了模型的代码理解能力。但在 Verilog 生成里此前没有人用对比学习来刻画有效性边界。已有工作关注的多是代码语义相似不相似而不是代码合法不合法。VerilogCL 要补的正是这一课。三、VerilogCL 的总体思路把错误处理前移VerilogCL 的核心想法是把一部分错误处理从生成后提前到生成中。整个框架由三个环节构成。第一个环节是最小错误数据增强。给每条经过验证的正确代码配上若干语义等价的正确变体和只改动一处的错误变体构成一组组对照样本。第二个环节是对比学习。用这些对照样本训练模型让正确代码在表示空间里聚在一起错误代码被推远两者之间形成清晰的边界。第三个环节是主动错误筛查。一个轻量级分类器读取模型的内部信号在生成过程中实时评估当前片段的风险发现可疑的续写就拦下来重新采样。这套组合的分工很清楚。对比学习负责把边界刻画出来筛查模块负责在解码时利用这条边界。错误不再等到编译器那里才暴露而是在刚刚冒头的时候就被处理掉。用论文的说法框架把一部分错误处理从事后修补转移到了生成阶段的风险识别。图 2VerilogCL 框架总览。最小错误数据增强、对比学习和主动错误筛查三部分配合把部分错误处理从事后修补前移到生成阶段的风险识别。来源原论文 Figure 2四、第一招给正确代码配一个最小错误的镜像对比学习的效果很大程度上取决于对照样本的质量。VerilogCL 在数据构造上花了不少心思。研究团队选取了 15 类有代表性的 RTL 模块覆盖组合逻辑和时序逻辑两大类。组合逻辑部分包括布尔门电路、半加器和全加器、比较器、多路选择器、编解码器。时序逻辑部分包括 D 触发器、计数器、RAM 和 ROM以及以交通灯控制器为代表的有限状态机。基本覆盖了入门到中等难度的数字电路设计场景。每个模块的样本由三种角色组成。锚点是经过验证的正确实现。正样本是对锚点做语义保持变换得到的变体比如改变量名、等价地重组逻辑结构每一条都用 Yosys 做等价性检查确认变换前后功能一致。负样本是往锚点里注入一个受控错误得到的变体错法来自预先定义好的五大类。这些错法不是凭空想象的它们来自基座模型在前期生成中真实暴露的失败模式以及以往 RTL 生成研究的总结。五大类错误值得展开看看它们几乎就是 AI 写 Verilog 的翻车清单。标点错误漏分号、列表里漏逗号、列表末尾多逗号、位宽声明里漏冒号。关键字错误关键字拼错、begin 和 end 等块定界符不配对、括号不配对。运算符误用赋值运算符混淆、逻辑运算符误用、按位运算符误用、相等判断混淆。声明错误信号漏声明、信号类型声明错、同一信号重复声明、端口方向漏声明或声明错。结构错误assign 语句写出模块作用域之外、同一个信号出现多个驱动源。负样本的筛选相当严格。每类错误生成十个候选全部经过编译和仿真验证只有稳定复现编译失败或功能不匹配的才被保留下来。这道工序保证了负样本错得真实不是纸面上捏造出来的假错误。还有一点运算符误用、声明不一致、位宽相关错误这几类不只引起编译失败还常常导致功能层面的偏差。学会辨认它们对功能正确性也有直接帮助。最小错误四个字是这套数据策略的关键。每个负样本只比锚点错一处语义上几乎相同合法性上截然相反。普通训练数据里正确和错误之间往往隔着巨大的语义鸿沟模型学不到精细的判别能力。而 Verilog 真实的翻车现场恰恰都是这种只差一点点的小错。用这种样本训练相当于把易错题单独整理成册让模型反复辨认。最终得到的数据集约含 3000 组对比三元组。对动辄上亿 token 的训练语料来说这个规模小得可怜但胜在每一组都经过严格验证。后面会看到数据不在多在于每一组都恰好打在边界上。要点负样本只比正确代码错一处且全部经过编译和仿真验证。模型要学的不是正确的代码长什么样而是对与错之间那条极窄的缝在哪里。五、第二招在表示空间里划出对错边界有了对照样本下一步是让模型真正学会区分。VerilogCL 采用的是三元组间隔损失。具体做法是这样的。一条 Verilog 序列输入模型后取骨干网络最后一层的隐状态沿序列维度做最大池化得到一个固定长度的向量作为这段代码的语义表示。对每一组三元组损失函数要求锚点与正样本的表示距离比锚点与负样本的表示距离至少小一个间隔 m。不满足就产生损失推着模型朝正确方向调整。这条规则的直觉很朴素。正确的代码不管变量名怎么改、逻辑结构怎么等价变换在表示空间里都应该挨在一起。错了哪怕一处的代码必须被推到间隔之外。间隔 m 的存在让模型不能满足于分得差不多必须把两类样本拉开到足够的距离。模型在训练中逐渐明白哪些局部细节是有效性的命门动一个运算符、漏一个分号代码的身份就变了。这种细粒度的区分能力靠记忆有限的训练语料是学不来的。工程实现上团队没有全量微调而是用 LoRA 做参数高效适配。低秩矩阵只插在注意力投影层秩为 32丢弃率 0.05训练精度 bfloat16优化器 AdamW学习率 3e-5批大小 8训练 10 轮。轻量适配在小数据上更稳也降低了过拟合风险。对比学习阶段和后续筛查阶段使用同一个池化表示保证了训练与推理之间的一致性。图 3最小错误对比学习的三元组构造。正确实现作为锚点语义保持变换产生正样本注入单一错误产生负样本训练目标是拉近锚点与正样本的距离、推远负样本。来源原论文 Figure 3训练效果如何论文给出了一张直观的证据。用 PCA 把正确和错误代码的语义表示投到二维平面上对比学习之前两类样本的点完全搅在一起肉眼分不出任何规律。对比学习之后它们各自聚成一团中间出现了明显的分界。语义相近但合法性不同的代码在表示空间里被有效地分开了。表示空间确实被重塑了这正是后续筛查模块可靠工作的基础。图 4对比学习前后语义嵌入的 PCA 可视化。训练前正确与错误样本高度混杂训练后两类样本形成清晰可分的簇。来源原论文 Figure 4六、第三招生成过程中的实时安检表示空间分清了对错还需要一个机制在生成时把这条边界用起来。这就是主动错误筛查模块。先看它要解决的问题。自回归解码是一个词元一个词元往外生成的局部的小错会一路累积。开头声明错了一个信号后面几十行代码全都建立在沙滩上。等整段代码生成完送交编译器错误早已扩散。事后修补要付出额外的编译轮次功能层面的错误编译器还经常发现不了。筛查模块的核心是一个轻量级二分类器输入是两类特征的拼接。一类是语义特征就是上一节最大池化得到的隐状态表示刻画代码的整体结构和上下文。另一类是统计特征从模型输出的词元概率里提取共分三组。第一组是聚合不确定性包括平均和最大负对数似然、平均和最大熵、负对数似然的标准差、低置信词元的数量。第二组刻画不确定性尖峰统计尖峰个数、尖峰值的均值和离散程度、最大尖峰对应词元的不确定性。第三组针对特定词元包括标点符号的平均负对数似然、关键字的平均负对数似然以及末尾若干词元的平均不确定性。为什么需要统计特征因为语义相近不代表代码合法。两段代码表达的设计意图几乎一样差别可能只是一个分号或一处位宽光靠语义特征分不开。而模型在出错位置的概率分布往往会露馅不确定性会突然升高。把两类信号拼在一起等于同时看代码写了什么和模型写得有多心虚。分类器本身结构简单。一个投影头把拼接后的高维向量压缩成紧凑表示再接一个带 sigmoid 激活的线性层输出当前片段合法的概率。训练数据就是最小错误数据集里的正负样本合法代码为正错误变体为负用二元交叉熵优化训练时骨干模型的参数保持冻结。筛查的介入时机也有讲究。模型每生成到一个语句边界也就是分号、end、endcase、endmodule 这些位置分类器就评估一次。分数高于阈值解码照常继续。分数低于阈值说明这段续写风险高解码器丢弃它从当前边界按同样的采样配置重新生成一次。整个过程不依赖编译器干预的是错误刚刚发生的现场避免局部小错扩散成整段代码的编译失败。在框架内部筛查和对比学习是互补关系。对比学习改善表示空间里正确与错误样本的可分性筛查模块则利用改善后的表示加上不确定性线索降低局部错误累积成无效输出的概率。一个管练好眼睛一个管站好岗。阈值的选取经过了实验。在验证集上扫描不同取值F1 分数在 0.507 附近达到峰值 92.58%并且在 0.2 到 0.9 的宽阔区间内表现都相当平稳说明分类器对阈值并不敏感。后续实验统一取 0.5。还有一组数字能说明对比学习的价值。用同一个分类器架构和训练流程分别接在原始模型和对比学习后的模型上分类准确率从 79.5% 跳到 92.5%精确率从 80.91% 升到 92.80%F1 从 79.96% 升到 92.58%。表示空间被拉开之后筛查模块的判断力跟着上了一个台阶。图 5不同筛查阈值下验证集 F1 分数的变化。虚线标出最优阈值 0.507分类器在很宽的阈值区间内表现稳定。来源原论文 Figure 5要点筛查分类器同时读取语义特征和词元不确定性特征在语句边界实时打分。对比学习把表示空间拉开后分类器的 F1 从 79.96% 提升到 92.58%。七、实验7B 模型交出的成绩单聊完方法看疗效。实验的基座模型是 DeepSeek-Coder-7B-Instruct-v1.5全部训练在单张 NVIDIA A30 上完成推理时温度取 0.7top-p 采样取 0.95。评测使用两个公开基准VerilogEval 和 RTLLM 的 v1.1 与 v2.0 版本全部跑官方测试平台仿真在 Synopsys VCS 上执行。每个问题生成 10 个候选用 passk 指标衡量功能正确性即从候选中随机取 k 个时至少一个通过功能验证的期望概率。先看功能正确性。在 VerilogEval 的人工题目集上完整模型的 pass1 达到 55.3%比基座模型的 31.7% 高出 23.6 个百分点pass5 和 pass10 分别为 60.3% 和 65.2%。在机器生成的题目集上pass1 为 74.5%提升 18.8 个百分点pass5 和 pass10 达到 85.4% 和 87.4%。RTLLM 两个版本报告的 pass5 分别为 70.5% 和 61.9%对应提升 32.6 和 16.9 个百分点。横向对比更有说服力。参评的商业模型里GPT-4 在人工和机器题目集上的 pass1 分别是 43.5% 和 60.0%Claude3-Sonnet 是 46.1% 和 58.4%。Verilog 专用模型中表现靠前的 OriGen 是 54.4% 和 74.1%。同为 7B 量级的开源代码模型差距更明显CodeLlama-7B-Instruct 只有 18.2% 和 43.1%。这个 7B 小模型在这些指标上全部跑到了前面在 RTLLM 两个版本上同样位列第一。再看成功率。RTLLM v1.1 上VerilogCL 的编译成功率达到 0.94在所有参评方法中最高。作为参照专用解码框架 DecoRTL 是 0.80OriGen 是 0.78基座模型只有 0.71比它高出了 23 个百分点。功能成功率方面所有方法的数字都明显低于各自的编译成功率这本身就说明能编译和能跑对之间隔着一条鸿沟。VerilogCL 以 0.57 排在首位高于 DecoRTL 的 0.54 和 GPT-4 的 0.52比基座模型的 0.32 提升了 25 个百分点。图 6RTLLM v1.1 上各方法的编译成功率与功能成功率对比。VerilogCL 在两项指标上均位列第一。来源原论文 Figure 6消融实验回答了两个组件各自贡献多少的问题。RTLLM v1.1 上单独加对比学习编译成功率和功能成功率从基线的 70.7% 和 32.1% 升到 78.8% 和 39.4%。单独加筛查分类器升到 74.5% 和 36.2%。两者一起启用直接来到 94.0% 和 56.6%。RTLLM v2.0 上趋势一致从 69.8% 和 36.4% 提升到 89.3% 和 49.8%。两个组件不是简单叠加对比学习改善表示质量分类器借助更好的表示做拦截组合起来的收益明显大于各自为战。论文把收益归因于两个互补因素。一方面对比学习使用的多类变异错误比如运算符误用、声明不一致和位宽问题本身就与下游功能失败高度相关把这些案例在表示空间里与正确代码分开模型自然学到了功能层面的对错边界。另一方面筛查模块结合隐状态语义和词元不确定性把解码引向更可靠的续写低质量候选在半路就被拦下不再消耗后续的编译验证资源。八、冷静看待这项工作的边界成绩亮眼局限也要说清楚。数据集约 3000 组三元组来自 15 类模块覆盖的都是相对基础的单元电路。真实芯片设计是多模块协作的复杂系统方法在更长跨度、更复杂设计上的表现如何论文还没有给出答案。作者也把多模块设计和长序列生成列为下一步方向。功能成功率 0.57 这个数字值得多看一眼。它意味着即使经过数据增强和生成时筛查候选里仍有四成以上通不过功能验证。大模型生成可靠 RTL 的问题远没有被解决VerilogCL 是把成功率往前推了一大步而不是画上句号。方法层面也有约束。全部实验基于同一个基座模型 DeepSeek-Coder-7B框架迁移到其他骨干网络上效果如何文中没有验证。筛查机制在语句边界处提取特征并运行分类器增加了推理开销被拒绝后的重采样目前只进行一次遇到模型持续拿不准的场景效果会打折扣。阈值在本文设置下对取值不敏感换到别的模型和任务上是否依然如此同样需要更多检验。作者在结尾提到两个延伸方向。一是把形式化验证融入框架用更强的正确性信号替代编译和仿真检查。二是引入功耗、性能、面积这些设计层面的目标让生成的代码不仅对而且好用。这两个方向决定了这类方法最终能离真实设计流程有多近。结语VerilogCL 给 Verilog 生成带来的启发不只是榜单上几个百分点的提升。它指出了一个容易被忽视的问题模型反复犯同类错误往往是因为内部表示里根本没有对错的界线。靠生成之后的外部修补治标难治本。用最小错误的对照样本教会模型辨认界线再在生成过程中实时把关这个思路不依赖海量数据也不依赖更大的模型单张 A30 上的 7B 模型就能跑起来。对数据稀缺的硬件设计领域来说这种精打细算的做法或许比单纯堆规模更有参考价值。把眼光放长AI 辅助芯片设计要真正落地可靠性是绕不开的考题。把错误处理从流程末端前移到生成现场是朝这个方向迈出的扎实一步。参考资料本文基于论文 VerilogCL: A Contrastive Learning Framework for Robust LLM-Based Verilog Generation 撰写论文 arXiv 编号为 2604.18162作者 Yan Tan、Tong Liu、Xiangchen Meng、Yangdi Lyu 来自香港科技大学广州校区微电子学域。文中部分图片改编自原论文 Figure 1 至 Figure 6仅用于论文解读与学术交流。文中所有数据与结论均出自原论文。