硬件描述语言存在了几十年,Verilog 和 VHDL 一直是数字芯片工程师的"母语"。
后来出现了 HLS——High-Level Synthesis,高级综合。它的核心思路是把 C/C++ 这类高级语言描述的算法,自动转换成 RTL 电路。 这在当时已经算是一大步:工程师终于可以用更接近算法思维的方式写硬件,而不是从第一个 always 块开始一点点搭。
但 HLS 终究还是编程语言。它有严格的语法,有复杂的 pragma 指令,写一个加速器模块要配合 pipeline、dataflow、array partition 这些关键字,稍有不慎就是综合出来的时序一塌糊涂,面积超标。对于不熟悉 C++ 的芯片工程师来说,HLS 的学习曲线并不比 RTL 低多少。
现在,事情开始变了。
大型语言模型(LLM)正在成为硬件设计的强力工具,近期研究正在探索它们直接从自然语言规格说明生成 RTL 代码的能力。 这不是说说而已,学界已经有可以量化的 benchmark 来评估这件事做得有多好。
基于 LLM 和自然语言指令的 RTL 自动生成,在敏捷电路设计领域展示出相当大的潜力。受 ChatGPT 等大模型成功的启发,研究者们开始探索用 LLM 做敏捷硬件设计,包括从自然语言指令生成设计 RTL。
举个具体的例子,如果你想要一个 8 位的循环移位寄存器,过去的流程是:打开编辑器,写 Verilog,仿真,调 bug。而现在可以这样对模型描述:
设计一个8位的循环左移寄存器(barrel shifter), 支持移位量0到7,组合逻辑实现, 输入为data[7:0]和shift[2:0],输出为out[7:0]。模型直接给出可综合的 Verilog 代码。这个输入不是伪代码,不是 C++,就是人话。
这里有个问题值得认真想一下。
编程和硬件设计,本质上是高度确定性的过程——每一行 RTL,每一个时序约束,都必须精确无歧义。人类语言天然不是这样的,"移位量0到7"这句话,机器如何知道是循环移位还是逻辑移位?"面积优先"是什么意思?这些歧义,在传统 EDA 工具里是绝对不被允许的。
返回的指令应该包含详细且无^_^歧义的要求,以确保 LLM 只能基于该指令生成功能唯一的 Verilog 代码。 这句话说得很直白:自然语言转 RTL,最难的不是生成代码,而是消除歧义。
早年的软件工程研究者也尝试过类似的路:DSL(领域特定语言)、伪代码、甚至形式化数学语言,都是想找一个介于人类语言和机器指令之间的"桥"。这条路走了几十年,效果有限——语言越严谨,越接近代码本身,普通工程师用起来还是别扭。
芯片设计领域的 HLS,本质上也是在做这件事。只是这个"桥"是 C++,离人的思维还是有一段距离。
LLM 做到的,是真正把这个桥拆掉了。
当然,现实没有那么美好。当前基于 LLM 的方法在满足真实硬件设计需求方面还存在明显不足,尤其在处理复杂设计和保证代码正确性上。评估结果显示,随着设计复杂度的增加,LLM 生成的 HDL 代码功能正确率会显著下降。
换句话说,生成一个 FIFO 或者简单的 ALU,现在的模型已经相当可靠;但如果是一个完整的流水线处理器或者带复杂握手协议的 AXI 接口模块,功能正确性就开始打折扣了。
研究者也在应对这个问题。AutoSilicon 框架提出了一套 agent 系统,可以把大规模复杂的代码设计任务分解成更小、更简单的子任务,同时提供编译和仿真环境,让 LLM 能够编译和测试每一段代码。 这个思路和软件工程里"分而治之"的逻辑是一样的——复杂的不行,就拆小了再来。
HLS 方向也出现了类似的探索,C2HLSC 和 HLSPilot 展示了 LLM 如何将 C/C++ 代码重构为兼容 HLS 的实现,包括 pragma 插入和设计空间探索。
自然语言输入,到底改变了什么?
它改变的不只是"写代码的方式",改变的是谁能参与硬件设计。过去,写 Verilog 需要几年的积累。HLS 把门槛降了一点,但还是需要懂 C++ 和综合工具。自然语言输入之后,一个算法工程师,一个系统架构师,甚至一个刚入行的实习生,都可以开始描述他们想要的硬件行为。
门槛的下降,历史上每一次都会带来参与者的爆炸式增长。
从 RTL 到 HLS,再到自然语言,每一步抽象级别的提升,都是把人从"怎么写"中解放出来,让人去想"写什么"。这条路的方向是确定的,只是现在走到了哪一步,还需要诚实地看清楚。