零成本做一颗芯片:我用 OpenLane 把 SHA-256 从 Verilog 做到了 GDS

31 阅读4分钟

在线速览页:1ouxilisi.github.io/sha256-open… ——六代演进、三 PVT corner 签核全表、六张版图、四层验证证据与边界说明,一页可读完。

一键复现:clone 后两条命令自己跑 —— bash scripts/verify.sh 编译 RTL + testbench 跑 abc / empty / fox 三锚点、输出 ALL TESTS PASSED,python3 scripts/check_vectors.py 用 Python hashlib 独立核对期望值;同一套步骤跑在 GitHub Actions 上,每次 push 自动重跑(已绿)。

TL;DR:OpenLane 1.1.1 + SkyWater sky130A,六代迭代。v4 做到 56.72 MHz / 0.41 mm² / 40.65% 利用率;v5 把时钟约束从 10 ns 改成 26 ns,三 PVT corner 签核 WNS 0.00 / TNS 0.00 / setup 余量 +3.12 ns 起 / hold +0.43 ns,功耗 6.31 mW;v6 只把周期压到 24 ns,三 corner 仍全通过、最紧余量 +1.25 ns,反推可达周期约 22.75 ns(43.9 MHz),功耗 6.84 mW。六份 GDS 与全部指标已开源。v1–v4 签核不合格(v4 WNS -7.63 ns),已如实写入 VERIFICATION。

1. 环境与约束

  • 流程:OpenLane 1.1.1(Yosys → OpenROAD → TritonRoute → Magic/KLayout)
  • 工艺:SkyWater sky130A,130nm,唯一可零成本产出真实 GDSII 的开源 PDK
  • 成本:0(无商业 EDA、无流片费用)
  • 运行环境:云主机 Ubuntu 22.04,chroot 内跑 OpenLane rootfs

2. 六代指标

版本频率周期面积利用率单元数违例签核 WNSGDS
v138.58 MHz25.92 ns0.64 mm²20.99%9,5120-15.9238.9 MB
v253.45 MHz18.71 ns0.49 mm²33.53%12,2450-8.7143.3 MB
v358.17 MHz17.19 ns0.49 mm²33.59%12,2880-7.1941.6 MB
v456.72 MHz17.63 ns0.41 mm²40.65%12,2880-7.6341.2 MB
v538.46 MHz26.00 ns0.41 mm²45.18%12,28800.0043.4 MB
v641.67 MHz24.00 ns0.41 mm²45.18%12,28800.0043.3 MB

3. 架构演进

  • v1:单块组合 + 773 并行 IO
  • v2:32-bit 串行接口 + 两级流水,压缩核拆分 W 扩展与 t1/t2 更新
  • v3:三级流水,phase0 只算 wc,phase1 并行算 t1p/t2p,phase2 更新 E/A
  • v4:不改架构,收 die 至 640×640,冲利用率
  • v5:不改架构,只把 CLOCK_PERIOD 10.0 → 26.0,加 setup 0.30 / hold 0.40 ns resizer 余量
  • v6:不改架构,只把 CLOCK_PERIOD 26.0 → 24.0,其余配置逐项相同(单变量对照,用于测余量边界)

4. 关键判断:58 MHz 是工艺上限,不是设计偷懒

v3 的级内组合逻辑只有约 6.6 ns,signoff 周期 17.19 ns,差额来自寄存器 CK-to-Q 与布线 RC。这解释了为什么第三级之后频率只涨 9%:瓶颈已经不在逻辑深度,而在工艺本身。继续加流水级不会带来收益,只会增加面积与功耗。

4.1 v5 的反证:负余量是约束错,不是设计差

四代跑完 flow 都显示 optimized WNS = 0,但那是布线后 resizer 的估算值。RCX/SPEF 重签核后 setup 全负(v4 nom -7.63 ns)。根因是 CLOCK_PERIOD 从第一天就写成 10.0 ns(100 MHz),而实际只能跑到 56.72 MHz——约束比工艺激进一倍多。v5 只改约束到 26.0 ns 并加余量,三 corner 立刻全正。同一份 RTL、同一个 die,说明问题在约束设定,不在设计能力。代价是 38.46 MHz。

4.2 v6 的定量边界:43.9 MHz

v6 在 v5 的全部配置上只动 CLOCK_PERIOD(26.0 → 24.0),三 corner 仍全为正,setup 余量收窄为 +3.08 / +2.12 / +1.25 ns,hold 稳定 +0.43 ns。最紧角余量 1.25 ns 加回 24.0 ns 得 22.75 ns ≈ 43.9 MHz,即这条 RTL 在 sky130A 上的可达上限。功耗从 6.31 升到 6.84 mW(+8.4%),频率 +8.3%,基本线性跟随,说明该设计功耗由频率主导而不是布线扰动——这同时解释了为什么继续优化组合逻辑(仅占 2.8%)既不提频也不省电。

5. 工程坑位清单

  1. flow 必须 chroot 内从 /designs 根目录启动,否则 prep 报 Design not found
  2. 环境变量 TERM/NO_COLOR/LC_ALL/LANG/PDK_ROOT 缺一不可,漏 LC_ALL=C 会让 STEP 0 verilator lint 因 locale 崩掉
  3. chroot 内 KLayout 必崩(tlFileUtils.cc:979),渲染与 XOR 校验改到宿主 KLayout 0.30.x
  4. GRT-0119 拥塞不要靠放大 die 解决,用 GRT_ALLOW_CONGESTION="1" + GRT_OVERFLOW_ITERS="200"
  5. flow_status: failed 是工具崩溃,STEP 36 的 GDS 与指标均有效

6. 验证

  • L1 逻辑对照 Python hashlib:11/11 PASS
  • L2 iverilog 12 组测试向量:12/12 PASS
  • L3 顶层握手时序:2/2(v3 后 3/3)PASS
  • 物理一致性:Magic/KLayout 双 GDS 逐层 XOR,40 层共同层 0 差异(v1–v6 全部 PASS)
  • 时序签核:v5 三 PVT corner WNS 0.00 / TNS 0.00 / setup +5.00 / +4.03 / +3.12 ns / hold +0.43 ns;v6 WNS 0.00 / TNS 0.00 / setup +3.08 / +2.12 / +1.25 ns / hold +0.43 ns;v1–v4 为负(v4 nom -7.63 ns)

7. 边界与后续

作品集性质,非量产;v5/v6 的 38.46–41.67 MHz 不代表性能强,是在该工艺下"真能签核"的工作点,按余量反推可达 22.75 ns(43.9 MHz);v1–v4 签核不合格已公开;未做 DFT、ECO,也未继续下压到 22 ns(该区间须改 RTL 才能收敛)。

仓库