大型语言模型(LLM)在寄存器传输级(RTL)设计自动化领域展现出巨大潜力,但直接生成 Verilog 或 CIRCT IR 的方式存在根本性缺陷:语法正确率虽高,功能正确性却难以保证,且生成的代码难以与现有硬件编译流程集成。CPPL(Circuit Prompt Programming Language)提出了一种编译器介导的生成范式,通过结构化的前端 DSL 和 JSON 中间表示,将 LLM 的生成能力约束在编译器可验证的范围内,从而在保持自然语言编程便利性的同时,显著提升硬件设计的可靠性。
问题:端到端 RTL 生成的三重困境
当前主流的 LLM4RTL 流程采用端到端生成模式:模型直接输出最终 RTL 文本,再由仿真器或综合工具进行验证。这种模式面临三个核心问题。首先,生成的 RTL 可能存在语法错误或工具兼容性问题,这些问题只能在下游编译阶段才能发现。其次,功能行为、位宽一致性和结构层次被纠缠在单一的文本生成任务中,导致失败难以定位 —— 模型需要同时推理行为、结构、位宽和边界条件。第三,端到端生成几乎不向硬件编译基础设施暴露中间结构,使得类型化表示、合法性检查、规范化和优化等编译器能力无法被利用。
硬件编译基础设施如 CIRCT(Circuit IR Compilers and Tools)提供了类型化的中间表示、合法性检查和优化通道,能够将格式良好的中间表示降级为可综合的 Verilog。理论上,LLM 可以直接生成 CIRCT IR 以利用这些能力。然而实验数据显示,即使是最强的商业模型,在生成 CIRCT IR 时的功能正确性也远低于生成 Verilog—— 直接 CIRCT IR 生成的 pass@1 功能正确性普遍低于 50%,部分模型甚至低于 10%。这表明原始编译器 IR 对当前 LLM 而言仍是不可靠的生成目标。
方案:三层架构的编译器介导设计
CPPL 的核心洞察在于:LLM 擅长理解电路结构和语义(这从它们生成 Verilog 的能力可以得到证明),但难以掌握 MLIR 的 SSA 形式、方言特定操作约束和严格类型要求。因此,CPPL 设计了一个三层架构,在 LLM 生成能力与编译器验证能力之间建立桥梁。
Python 前端 DSL采用函数式风格定义硬件模块。每个模块是一个用@module装饰器标记的 Python 函数,参数使用In和Out类型注解声明输入输出端口及位宽。这种显式的接口声明约束了 LLM 生成固定且类型正确的端口,减少了缺失、多余或位宽不匹配的接口问题。函数体通过文档字符串描述实现意图,可以混合自然语言描述和结构化 CPPL 构造(如模块实例化和连接)。
**JSON 中间表示(CPPL IR)** 是 LLM 实际生成的目标格式。它采用 JSON Schema 定义,包含模块声明、端口映射、操作序列和实例化信息。与 CIRCT IR 相比,CPPL IR 避免了 MLIR 语法、SSA 命名和方言特定操作约束,同时保留了编译器可见的结构信息 —— 模块、端口、实例、操作标识符和操作数都是显式字段而非非结构化文本。
编译器后端负责将 CPPL IR 验证并降级到 CIRCT。编译器执行宽度推断(从声明的模块端口传播位宽)、语法验证(检查标识符符号表、终止符覆盖、实例图连通性)、死代码消除和组合循环检测。每个识别出的问题被包装为 Python 异常,反馈给 LLM 进行迭代优化(默认最大迭代次数 Nmax=3)。验证通过的 CPPL IR 被确定性地降级到 CIRCT IR,再经过标准优化通道(常量折叠、死代码消除、公共子表达式消除)生成 Verilog。
实现:从自然语言到门级网表
CPPL 的编译流程体现了 "接口由 DSL 约束,行为由 LLM 生成" 的分工原则。以 ALU 模块为例,开发者首先用 Python DSL 声明模块签名:
@module
def ALU(op_code: In[2], op_a: In[8], op_b: In[8]) -> {"res": Out[8], "zero": Out[1]}:
"""基于op_code选择运算:00=加法(使用Adder8实例), 01=减法, 10=AND, 11=OR"""
前端解析器从函数签名提取模块边界,从文档字符串提取实现意图,并将格式化模块调用(如{Adder8(op_a, op_b)})解释为显式结构指令。这些结构信息在 LLM 生成前就已确定,避免了模型自由发明不兼容接口的风险。
LLM 根据文档字符串生成 CPPL IR 的 JSON 表示,包含操作序列(如add、sub、and、or、mux)和模块实例。编译器对生成的 IR 执行类型检查:算术和逻辑操作保持位宽,比较和归约操作产生 1 位结果,多路选择器要求分支等宽。类型检查通过后,编译器将 CPPL IR 降级到 CIRCT IR,应用优化通道,最终生成 Verilog。
这种架构的关键优势在于早期错误检测。宽度不匹配、未定义标识符、组合循环等错误在 JSON 层面即可捕获,无需等待 CIRCT 或综合工具报错。实验数据显示,CPPL 流程下所有评估模型都能生成语法有效的 CIRCT IR 和 Verilog,消除了直接 CIRCT IR 生成的主要失败来源。
评估:功能正确性与综合质量的双重提升
在 RTLLM 基准(29 个涵盖组合逻辑、时序逻辑和存储器设计的硬件问题)上的评估验证了 CPPL 的有效性。
功能正确性方面,直接 Verilog 生成虽然语法 pass@1 可达 90% 以上(GPT-5.3-codex 达 95.7%),但功能 pass@1 仅约 70%(最佳模型 Claude-opus-4.6 为 72.5%)。直接 CIRCT IR 生成功能正确性更低,Claude-opus-4.6 仅 50%,GPT-5.3-codex 仅 31.8%,Qwen-3.6-plus 仅 8.2%。相比之下,CPPL 流程下各模型功能正确性显著提升:Claude-opus-4.6 达 80%,GPT-5.3-codex 达 78.2%,Qwen-3.6-plus 达 76.8%。这表明编译器介导的表示能够将原本难以生成 CIRCT IR 的模型转化为可靠的硬件设计助手。
综合质量方面,使用 Yosys 测量 post-aigmap AIG 节点数。CPPL 生成的 Verilog 在多数设计上比直接 LLM 生成的 Verilog 和 RTLLM 参考设计具有更少的节点。更重要的是,启用 CIRCT 优化通道后,几何平均节点数从 439.88 降至 368.16,减少 16.3%。这验证了 CPPL 的核心设计选择:一旦 LLM 输出被表示为编译器可检查的电路 IR,传统硬件编译器优化就能改善生成的 RTL,而无需模型直接实现这些转换。
工程实践建议
对于希望采用 CPPL 进行硬件设计的团队,以下参数和策略可作为起点:
- 模型配置:温度设为 0.1 以平衡多样性与正确性,最大 token 长度 4096 以覆盖推理轨迹和代码生成,采样数 n=10 用于 pass@k 评估。
- 迭代策略:设置最大精炼迭代次数 Nmax=3,编译器将语法错误、宽度不匹配、组合循环等问题反馈给 LLM 进行修正。
- 模块库建设:预定义常用模块(如 Adder8、Multiplier)并在 DSL 中通过格式化字符串引用,利用层次化设计降低单模块复杂度。
- 验证流程:CPPL 生成的 Verilog 应通过 iverilog 进行功能仿真验证,再用 Yosys 进行综合评估资源占用。
局限与展望
CPPL 当前实现依赖 CIRCT 的 Python 绑定,存在版本兼容性问题 ——CIRCT 作为活跃开发项目,其 IR 语法和方言定义持续演进。此外,CPPL IR 尚未涵盖所有 CIRCT 方言特性,复杂时序逻辑和存储器建模仍有扩展空间。
长远来看,CPPL 代表了一种更广泛的范式转变:将 LLM 从 "直接生成最终代码" 的角色转变为 "在编译器约束下生成结构化中间表示"。这种范式不仅适用于硬件设计,也可推广到其他需要严格语义和优化的代码生成领域。随着 LLM 能力的提升和编译器基础设施的完善,编译器介导的生成有望成为可靠 AI 辅助软件工程的标准模式。
资料来源
- Yin, S., et al. "CPPL: A Circuit Prompt Programming Language." arXiv:2605.17892, 2026. https://arxiv.org/abs/2605.17892
- CPPL 开源实现:https://github.com/SawyDust1228/CPPL
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。