用 AI 做 RTL 设计:DeepSeek 4.0 pro、GLM-5.1、Kimi-2.6 实测对比

8 阅读11分钟

用 AI 做 RTL 设计:DeepSeek 4.0 pro、GLM-5.1、Kimi-2.6 实测对比

前言

最近在做一个有趣的实验:让不同的 AI 模型,在完全相同的条件下,独立完成同一个硬件设计任务,然后客观对比结果。

任务是什么?用 Verilog 实现国密 SM3 杂凑算法的核心压缩模块。这不是写个 Hello World,而是要完整跑通从架构设计、代码生成、Lint 检查、功能仿真到逻辑综合的 8 级自动化流水线

参赛选手:DeepSeek-4.0-proGLM-5.1Kimi-2.6

先说结论:GLM-5.1 赢了,而且赢得不少。

但过程比结论更有价值。下面是完整的客观数据和分析。


实验设计

控制变量

为了保证公平,我们严格控制了以下条件:

  • 相同的输入:三份一模一样的需求文档(requirement.md)和参考资料(SM3 标准草案)
  • 相同的工具链:VeriFlow 自动化流水线,统一使用 Icarus Verilog + Yosys
  • 相同的流水线配置:8 个阶段完全一致(architect → microarch → timing → coder → skill_d → lint → sim → synth)
  • 独立的执行环境:每个模型独立运行,互不干扰

SM3 算法背景

SM3 是中国国家密码管理局发布的密码杂凑算法标准(GM/T 0004-2012),用于数字签名和验证、消息认证码的生成与验证等场景。其核心是一个 64 轮迭代压缩函数,需要正确实现 FF/GG 布尔函数、P0/P1 置换、消息扩展等模块。

评估维度

我们从 8 个维度评估:仿真通过率、Lint 质量、代码规范、面积效率、测试覆盖、执行耗时、文件整洁度、文档质量。


一、Pipeline 状态:表面都是 "全绿"

先看官方记录——三个模型的 pipeline_state.json 都显示 8/8 阶段全部通过:

维度DeepSeekGLM-5.1Kimi-2.6
完成阶段数8/88/88/8
失败阶段000
总耗时~2h 2min~30min~2h 3min

看起来大家都很完美?但当你打开实际的日志文件,故事就不一样了。

这也是本文最想分享的一个发现:自动化流水线的 "全绿" 可能掩盖真实的质量问题。


二、仿真结果:核心指标,差距明显

仿真是硬件设计的核心验证手段。代码写得再漂亮,仿真不通过等于零。

实际 sim.log 内容

模型sim.log仿真结果测试数失败项
DeepSeek51 行FAIL7 个2 个失败
GLM-5.131 行ALL PASS4 个
Kimi-2.60 行无数据N/A文件为空

DeepSeek 的具体失败

DeepSeek 虽然写了最多的 7 个测试用例,但有 2 个失败了:

Test 3: Non-Last Block
  [FAIL] ready=1 after non-last block: condition is false
  → 处理非 last block 后,ready 信号没有恢复

Test 6: msg_valid ignored when not ready
  [FAIL] expected: 0x66c7f0f462eeedd9...
          got:      0xf13f90dee115a7da...
  → 模块忙时没有忽略 msg_valid,内部状态被污染,hash 结果完全错误

这是一个很典型的硬件协议 bug:当模块正在计算时,外部不应该能通过 msg_valid 端口干扰内部状态。 这就像你在做饭,有人硬往锅里扔了块石头——菜就废了。

Kimi-2.6 的问题更严重

sim.log 文件完全是空的(0 字节)。这意味着:

  • 仿真可能根本没运行
  • 或者运行了但输出丢失了
  • 无论如何,功能正确性没有任何证据

GLM-5.1:唯一真正全通过的

Test 1: Reset Behavior  PASS (3/3)
Test 2: Single Block 'abc' (GM/T 0004-2012)  PASS
Test 3: Ready Recovery After hash_valid  PASS
Test 4: Second Block Processing  PASS

ALL TESTS PASSED

稳扎稳打,4 个测试全绿,正确的 SM3 hash 值:66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0


三、代码质量:GLM-5.1 最规范

代码量对比

模块DeepSeekGLM-5.1Kimi-2.6
sm3_core.v107 行92 行89 行
sm3_compress.v291 行266 行281 行
sm3_fsm.v163 行151 行147 行
sm3_w_gen.v118 行193 行111 行
总计679 行702 行628 行

代码量差距不大,但质量差异显著。

接口设计差异

这里暴露了一个重要问题:三个模型产出的接口居然不一致。

端口/特性DeepSeekGLM-5.1Kimi-2.6
reset 极性active-highactive-lowactive-high
ack 握手
FSM 状态数544

GLM-5.1 用了 active-low reset(rst_n),另外两个用 active-high(rst)。更关键的是,GLM-5.1 没有 ack 握手端口——它的 hash_valid 只维持 1 个时钟周期就消失了。如果下游模块恰好在那个周期没采样到,hash 值就永远丢了。

这在真实的 SoC 环境中是个严重的可靠性问题。

编码风格的关键差异:阻塞赋值 vs 非阻塞赋值

这是 Verilog 设计中的经典问题。DeepSeek 和 Kimi-2.6 都在 posedge clk 时序逻辑块中使用了阻塞赋值(=)来处理数组元素:

// DeepSeek / Kimi-2.6 的写法(有时序逻辑中使用阻塞赋值的风险)
always @(posedge clk) begin
    if (update_v_en) begin
        v_reg[0] = v_reg[0] ^ a_reg;  // 阻塞赋值
        v_reg[1] = v_reg[1] ^ b_reg;
        // ...
    end
end

GLM-5.1 用命名标量寄存器代替数组,全程使用非阻塞赋值(<=):

// GLM-5.1 的写法(更规范)
always @(posedge rst_n or posedge clk) begin
    if (!rst_n) begin
        V0_reg <= 1'b0;
        // ...
    end else if (update_v_en) begin
        V0_reg <= V0_reg ^ A_reg;  // 非阻塞赋值
        V1_reg <= V1_reg ^ B_reg;
        // ...
    end
end

在仿真中两种写法可能表现相同,但在综合工具中行为可能不一致。GLM-5.1 的写法更安全、更符合 Verilog 最佳实践。

ROL(Tj, j) 的实现:三种思路

SM3 算法中需要计算 ROL(Tj, j)——一个可变位数的循环左移。三个模型给出了完全不同的实现:

DeepSeek——移位拼接法:

wire [5:0] rot_amt = round_cnt[5:0];
wire [31:0] T_rotated = (T_sel << rot_amt) | (T_sel >> (6'd32 - rot_amt));

GLM-5.1——5 级桶形移位器(MUX 级联):

// stage 4: shift by 16
wire [31:0] s4 = rot_amt[4] ? {t[15:0], t[31:16]} : t;
// stage 3: shift by 8
wire [31:0] s3 = rot_amt[3] ? {s4[23:0], s4[31:24]} : s4;
// ... 逐级递减

Kimi-2.6——32 路全枚举 case 语句:

function [31:0] rol32;
    input [31:0] x;
    input [5:0] n;
    case (n)
        6'd0:  rol32 = x;
        6'd1:  rol32 = {x[30:0], x[31]};
        // ... 32 个 case ...
        6'd31: rol32 = {x[0], x[31:1]};
    endcase
endfunction

三种实现功能都正确。GLM-5.1 的桶形移位器在综合后面积最优、时序最好;Kimi-2.6 的 32-case 写法虽然正确,但综合工具需要展开所有分支,代码量也大得多。


四、Lint 检查:GLM-5.1 唯一零警告

模型结果警告
DeepSeek日志为空N/A
GLM-5.1PASS0 errors, 0 warnings
Kimi-2.6PASS21 warnings

Kimi-2.6 的 21 个警告全部是同一类型:

warning: @* is sensitive to all 16 words in array 'w_reg'.
warning: @* is sensitive to all 8 words in array 'v_reg'.

这是因为 always @* 在遇到数组时,会将数组的所有元素加入灵敏度列表。虽然功能上通常没问题,但可能影响仿真性能和综合结果。


五、综合结果:面积差异 12%

三个模型都用 Yosys 综合到通用门级:

指标DeepSeekGLM-5.1Kimi-2.6
总 cell 数4,6474,420(最小)5,017(最大)
compress cells3,3323,1143,701
w_gen cells1,2491,2491,249
FF 数~1,038~1,038~1,040
Synth Warnings103

直观对比:

面积对比 (Yosys cells):

DeepSeek  ████████████████████████████████████████████  4,647
GLM-5.1   ██████████████████████████████████████████    4,420  ← 最小
Kimi-2.6  ██████████████████████████████████████████████ 5,017  ← 最大

有意思的是,sm3_w_gen(消息扩展模块)三个模型都是 1,249 cells,完全一致。差异全部来自 sm3_compress(压缩函数)——GLM-5.1 的命名标量寄存器写法和桶形移位器在综合时确实更紧凑。


六、调试效率:看 testbench 文件就知道

这个维度最能体现模型的"思考方式"差异。

模型Testbench 文件数总行数
DeepSeek1 个397 行
GLM-5.11 个223 行
Kimi-2.620 个1,601 行

Kimi-2.6 的 tb/ 目录长这样:

debug_tb.v, debug_ready.v, debug_fsm.v, debug_fsm2.v,
debug_compress.v, debug_w_gen.v, debug_integrated.v,
debug_quick.v, tb_debug.v, tb_monitor.v, tb_trace.v,
tb_compare.v, tb_rounds.v, tb_rounds2.v,
tb_debug_test3.v, tb_debug_test4.v, tb_debug_test4b.v,
tb_final.v, tb_sm3_core.v ...

这不是精心设计的测试套件,这是调试过程的化石。每遇到一个问题就写一个新的 testbench,编译、运行、看输出,再写下一个。19 个调试文件背后,是一次次的"盲试"。

与之对比,GLM-5.1 只有一个 223 行的 testbench,4 个测试全通过,干净利落。不产生调试垃圾文件本身就是效率的证明。


七、文档质量:各有所长

文档DeepSeekGLM-5.1Kimi-2.6
micro_arch.md443 行,最详细272 行,简洁286 行
behavior_spec.md429 行367 行~393 行
development_log389 行中文658 行英文

DeepSeek 的文档最详尽,且用了中文撰写开发日志,记录了 7 个 bug 的定位和修复过程。Kimi-2.6 甚至把完整 RTL 源码贴进了开发日志。GLM-5.1 的文档风格最干净——"不需要 debug log 因为没有 bug 要记"。


八、综合评分

维度 (权重)DeepSeekGLM-5.1Kimi-2.6
仿真通过 (30%)3/1010/102/10
Lint 质量 (10%)5/1010/107/10
代码规范 (15%)7/109/106/10
面积效率 (15%)8/109/106/10
测试覆盖 (15%)8/107/104/10
耗时 (10%)4/1010/104/10
文件整洁 (5%)8/1010/103/10
加权总分6.159.154.45

排名总结

第一名:GLM-5.1(9.15 分) — 仿真全通过,lint 零警告,面积最小,30 分钟完成。但接口设计有不足:无 ack 握手,hash_valid 仅单周期有效。

第二名:DeepSeek(6.15 分) — 测试最全面(7 个测试、ack 握手),但核心逻辑有 2 个 bug 导致仿真失败。"想得多"不等于"做对了"。

第三名:Kimi-2.6(4.45 分) — sim.log 为空是致命伤,功能正确性无从谈起。20 个调试 testbench 暴露了低效的"试错式"工作模式。


九、经验教训(重点)

1. 自动化流水线的 "全绿" 可能是假象

这是本次实验最值得警惕的发现。三个模型在 pipeline 状态中都标记为"全部成功",但实际检查 log 发现:

  • DeepSeek 有 2 个仿真测试失败
  • Kimi-2.6 的仿真日志是空的
  • 只有 GLM-5.1 是真正全通过

原因可能是 hook 只检查了命令的退出码,而没有解析日志中的 PASS/FAIL 关键字。

对任何 CI/CD 流水线的启示:不要信任 exit code,要解析实际输出。

2. "一次做对" 比 "反复修补" 重要得多

GLM-5.1 用 30 分钟一次通过,其他两个用了 2 小时还在修 bug。在硬件设计中,一个模型能一次性生成正确的 RTL,远比它能写出多少调试测试更重要。

选模型时,优先看"首次通过率",而不是"最终修复能力"。

3. 调试残留物是效率的反向指标

如果 AI 完成一个任务后留下了大量中间文件(debug TB、临时编译产物、多次迭代的日志),说明它的调试过程是低效的。好的 AI 应该在写代码之前就想清楚,而不是写完了靠试错来验证。

4. 接口规范必须在第一步就锁定

三个模型产出的接口不一致(reset 极性、握手协议),这在团队协作中是灾难性的。应该在架构设计阶段就把接口契约写死(比如 spec.json),后续所有阶段严格遵守。

5. 一个测试向量不够

三个模型都只用了 GM/T 0004-2012 标准中的 "abc" 测试向量。这就像你声称你的 SHA-256 实现正确,但只测了一个输入——说服力有限。

至少需要覆盖:空消息、边界长度、多块链式、其他官方测试向量。

6. 代码规范 ≠ 工程完整

GLM-5.1 代码最规范,但缺少 ack 握手是个工程缺陷。DeepSeek 有 ack 握手但代码用了阻塞赋值。规范性和工程完整性需要同时追求。


写在最后

这次实验让我对 AI 做硬件设计有了更务实的认识:

  1. AI 确实能完成有一定复杂度的 RTL 设计(SM3 压缩核心),不是玩具 demo
  2. 不同模型之间的差距是真实存在的,而且体现在多个维度
  3. 自动化验证流水线本身也需要被验证——"全绿"不代表真没问题
  4. 目前所有模型都还不够"工程化"——接口不一致、测试覆盖不足、调试效率低等问题普遍存在

如果你也在做 AI 辅助硬件设计的探索,欢迎交流。