Files
riscv-ulp-survey/opentitan/OpenTitan代码级综述.md

14 KiB
Raw Permalink Blame History

OpenTitan 代码级综述:一个量产级开源 SoC 仓库的结构解剖

编制日期2026 年 9 月 数据来源:本地克隆仓库实测(HEAD 2026-09 快照,git://lowRISC/opentitan

仓库顶层地图

1. 总览:这不是一个"代码库",而是一条流水线

OpenTitan 的仓库体量为本次综述的 9 个开源项目之最:3,995 个 RTL 文件、约 116 万行 RTL、821 个 FuseSoC .core 包、794 个 Bazel 构建文件、667 个 Python 工具脚本、12 条 GitHub Actions 流水线,全仓库 8,992 个硬件文件与 3,743 个软件文件分布在十几个顶层目录中。

但读完本综述你会发现,单纯罗列数字会误导理解。OpenTitan 真正的结构特征是:仓库里"手写的源"其实很少,大量文件是同一批机器可读规范在不同目的地的投影。看懂三条生成链(寄存器链、模板链、集成链),比记住目录名重要得多。这也是它区别于其他开源项目(包括 PULPissimo 的 Bender 外拉模式)的根本所在——OpenTitan 把"规范、代码、文档、软件接口"全部收敛到一个仓库内,用工具保证一致性,而不是靠人肉同步。

下面按"顶层地图 → 硬件 → 生成体系 → 软件栈 → 验证 → 仓库治理"的顺序逐层展开。

2. 顶层目录地图

仓库顶层共 15 个目录 + 若干根文件(BUILD/Makefile 等)。按职责可归为五类(见图 1):

  • 规范与文档doc/、site/、release/、signing/)——安全架构白皮书、开发者指南、版本化发布快照与签名产物规范;
  • 硬件 hw/——本综述的核心,8,992 个文件,包含 45 个独立 IP、工艺基元层、芯片 top 与参数化 IP 模板;
  • 软件 sw/——从 mask ROM 到主机端 CLI 的完整软件栈,3,743 个文件;
  • 工程基础设施util/、ci/、rules/、third_party/、toolchain/)——491 个 Python 工具、Bazel 规则、内置三方依赖与工具链获取脚本;
  • 质量与 CI.github/、hw/lint、hw/cdc、hw/formal、hw/dv、hw/syn、quality/)——全仓库级静态检查、验证复用环境与质量门禁。

一个值得注意的顶层细节:hw/ 下同时存在 top_earlgrey(主力芯片)、top_darjeeling(第二种芯片配置)与 top_englishbreakfast(用于 Verilator/CW305 快速仿真的精简版),三者共享同一套 hw/ip/ 目录——这就是"多 top 共享 IP"的目录设计,一份 IP 源,多个芯片投影。

3. 硬件 hw/45 个 IP + 基元层 + 三个 top

3.1 hw/ip/:独立 IP 仓库

45 个 IP 子目录,每个都是完整的"小型仓库"(见图 2,以 aes 为例)。按功能可分组:

  • 密码引擎:aes(含掩码实现)、hmac、kmac、otbn(大数/椭圆曲线运算的独立 ISA 协处理器)、ascon(轻量密码);
  • 熵与密钥entropy_src、csrng、edn(熵源三件套)、keymgr、keymgr_dpe(密钥管理);
  • 存储与启动rom_ctrl、flash_ctrl、otp_ctrl、otp_macro、sram_ctrl、rram_ctrl、rram_macro
  • 信任根与安全状态:lc_ctrl(生命周期管理)、alert_handler、racl_ctrl(资源访问控制)、soc_dbg_ctrl
  • 总线与核rv_core_ibex、rv_dm(调试模块)、rv_timer、dma、mbx(邮箱);
  • 通用外设uart、gpio、i2c、i3c、spi_device、spi_host、usbdev、pattgen、sysrst_ctrl、adc_ctrl、aon_timer
  • 基元层 prim/:跨工艺共享的底座(仲裁器、CDC、差分信号、密码原语、LFSR 等 40+ 个 prim_* 子模块),并有 prim_generic(可仿真通用实现)、prim_xilinxFPGA 变体)、prim_asap7(学术工艺变体)等工艺适配层——同一接口,不同工艺的落地实现。

3.2 单个 IP 的标准解剖(以 aes 为例)

每个 IP 目录都有惊人一致的结构(这是 OpenTitan 治理强约束的结果):

hw/ip/aes/
├── data/           ip_block.hjson —— IP「身份证」:寄存器/中断/告警/参数规范
├── rtl/            aes.sv、aes_core.sv、aes_cipher_core.sv…(手写 RTL
├── reg/            ← util/regtool.py 从 data/ 生成的寄存器 RTLaes_reg_top.sv 等)
├── dv/             tb/UVM testbench+ env/ + tests/ + sva/(断言)+ cov/(覆盖率)
├── model/          aes_model_dpi —— C 参考模型(DPI 接口,与 RTL 逐周期比对)
├── pre_sca/        侧信道攻击预研平台
├── pre_dv/         轻量 mini-DV 环境
├── syn/ · pre_syn/ 综合脚本与约束(面积/时序评估)
├── lint/           IP 级 lint 配置
├── doc/            IP 说明文档
├── aes.core        FuseSoC 包描述(全仓 821 个 .core 之一)
└── BUILD + defs.bzl Bazel 构建规则

关键理解:rtl/ 与 reg/ 的分界线就是"手写"与"生成"的分界线。工程师修改寄存器定义时只改 data/ip_block.hjson,然后运行 util/regtool.py -r 重新生成 reg/,寄存器 RTL、DIF 头文件、寄存器文档三者同步更新——这是"单一事实来源"Single Source of Truth)在 RTL 层的落地。

3.3 hw/ip_templates/ 与 hw/top_earlgrey/ip_autogen/:参数化 IP

13 个 IP 在仓库中以模板形式存在(clkmgr、rstmgr、pwrmgr、pinmux、otp_ctrl、alert_handler、rv_plic、gpio、pwm、flash_ctrl、rv_core_ibex、ac_range_check、racl_ctrl),由 util/ipgen.py 依据各 top 的参数集(如 Earl Grey 的时钟树/复位树/引脚配置)实例化到 hw/top_earlgrey/ip_autogen/,生成 9 个 top 专属 IP 实例。这一机制解决了"同一 IP 在不同芯片配置下需要不同参数"的问题——模板写一次,每个 top 生成自己的实例,避免手工 fork 出多个不同步的副本。

3.4 hw/top_earlgrey/:芯片集成层

这是芯片的"组装车间":

  • ip/:top 专属手写模块(ast 模拟传感器抽象、sensor_ctrl、xbar 主互连);
  • ip_autogen/:ipgen 生成物(9 个参数化 IP 实例,约 11.8 万行 RTL);
  • data/top.hjson 等芯片级规范——整颗芯片的 IP 清单、xbar 连接图、引脚复用、时钟/复位树、存储器映射全部在这份机器可读文件中声明
  • chip_earlgrey_asic.core / chip_earlgrey_cw340.core / chip_earlgrey_verilator.core:同一芯片的三种顶层变体(ASIC 综合 / CW340 FPGA 板 / Verilator 仿真),共享同一套 IP 源;
  • dv/:芯片级 UVM 环境(目标:验证 IP 集成正确性、XBAR 压力、地址空间自动化检查、FPV 连接性检查);
  • bitstream/(含 cw340、vivado、universal):FPGA 比特流构建。

3.5 hw/vendor/:被"锁版本"收纳的三方 IP

Ibex 处理器核、PULP common cells、PULP riscv_dbg 三方代码以 vendored 方式内置在本仓库中(.lock.hjson 固定上游 commit.vendor.hjson 描述拷贝规则,patches/ 存放本地补丁)。这就是综述第 7 节所说"内置+锁版本"的机制实体——上游更新不会自动流入,必须走显式的 vendor 更新流程,保证任意时点 checkout 都能复现同一份构建。

4. 「规范 → 生成」管线:OpenTitan 的灵魂

见第 3 节图 2/图 3。仓库内四大生成器构成三条生成链:

生成器 输入 输出 一致性作用
util/regtool.py ip_block.hjson reg/*.sv 寄存器 RTL + DIF 头文件 + 寄存器文档 寄存器三方一致
util/ipgen.py ip_templates/ + top 参数 hw/top_*/ip_autogen/ 模板→实例一致
util/topgen.py top.hjson xbar_main/xbar_peri 互连 RTL + pinmux + 芯片级 RTL + 芯片级 DIF/头文件 集成层一致
util/dtgen.py 同 top 数据 设备树 APIdt_api.h 等 C 模板实例化) 硬件↔软件视图一致

配套的文档生成器(util/mdbook_* 系列)把同一批 spec 渲染进 mdbook 文档站。修改一个寄存器的完整成本 = 改一行 spec + 跑一遍生成器,硬件 RTL、软件 DIF、文档三者同步更新,不会出现"文档落后于代码"的经典问题。这种机制在其他 8 个开源项目中无一具备——PULPissimo 用 Bender 解决的是"依赖从哪来",OpenTitan 用这些生成器解决的是"内部一致怎么保"。

5. 软件栈 sw/:从 mask ROM 到主机 CLI

sw/ 共 3,743 个文件,分为设备侧(device/)与主机侧(host/)两大阵营(见图 5):

  • sw/device/silicon_creator/ROM 安全启动代码——不可变第一级引导,含启动策略、密钥校验、防回滚(lib/ 子目录);
  • sw/device/silicon_owner/ROM_EXT——芯片所有者二级引导;
  • sw/device/lib/dif/85 个 DIFDevice Interface Functions——每个 IP 一份寄存器级 C APIdif_aes.c/h 等),并带 unittest.cc 单元测试;其中相当一部分由 autogen_dif + regtool 从 spec 生成;
  • sw/device/lib/runtimehart/print 等)、crypto(密码库)、arch、base、peripherals、ujsonRPC 序列化);
  • sw/device/tests/ · examples/ · sca/:芯片级测试、示例、侧信道采集(含 aes_serial、ecc384_serial、kmac_serial、otbn_vertical 等串行化采集专用实现);
  • sw/device/tock/TockOS 移植;
  • sw/otbn/:OTBN 协处理器的汇编/驱动配套(crypto、kmac、mai、wfi 等子目录);
  • sw/host/opentitantool / opentitanlib——主机端统一 CLI(烧写、调试、UART/SPI/I2C/JTAG 传输),配套 hsmtool、provisioning(量产_prov 流程)、penetrationtests(渗透测试框架)、ot_certs(证书)。

设备侧 + 主机侧在同一个仓库是 OpenTitan 软件布局的关键决策:ROM/ROM_EXT/DIF 的任何修改都能同步反映到主机工具与测试中,"硬件在环"三载体(DV 仿真、FPGA、硅片)用同一套工具驱动。

6. 验证与质量体系

OpenTitan 的验证资产按"IP 级 → 芯片级"两层组织:

  • IP 级(每个 IP 的 dv/):UVM testbench、SVA 断言、覆盖率收集计划(cov/)、dvsim 仿真配置(*_sim_cfg.hjson,声明测试集/仿真器/回归策略)、部分 IP 配 C 参考模型(aes、otbn、kmac 等 DPI 模型);
  • 芯片级hw/top_earlgrey/dv/):SV/UVM chip-level testbench,目标包括 IP 集成验证、XBAR 压力测试、地址空间自动化校验、时钟/复位域跨域检查、以及 FPV 连接性检查(验证 DV 中被排除的信号连接点 A→B 正确);
  • 形式验证hw/formal/ + util/fpvgen.py 为每个 IP 自动生成 FPV 配置;
  • 静态检查hw/lintVerilator/Verible 规则)、hw/cdc(时钟域)、hw/rdc(复位域);
  • 侧信道/安全评估:各密码 IP 的 pre_sca/ 平台 + sw/device/sca 串行化采集 + sw/host/penetrationtests
  • CI12 条 GitHub Actions 流水线(含 cherrypick、pr_change_check、monthly 等),配套 util/dvsim.py 作为本地/CI 统一的仿真调度入口。

util/dvsim.py 值得单独一提:它是整个验证体系的"调度中枢"——IP 级 *_sim_cfg.hjson 与芯片级 testplan 都由它解析调度,同一入口覆盖 Verilator/VCS/Xcelium 等不同仿真器与 FPV/lint/cdc 各类工具,是"验证即代码"的工程化体现。

7. 仓库治理:让 116 万行代码不散架的机制

综合上述结构,OpenTitan 的"可治理性"来自五个机制:

  1. 单一事实来源(SSOT:寄存器、互连、引脚、时钟复位树全部声明在 hjson 规范中,代码与文档都是投影;
  2. 生成式一致性:四大生成器保证"改 spec → 全链同步",无手工同步环节;
  3. vendored 依赖 + 锁版本:三方代码全部内置固定 commit(含 patches/),无外拉不确定性;
  4. 多 top 共享 IP 池:45 个 IP 独立于 top 存在,earlgrey/darjeeling/englishbreakfast 三个 top 共用,避免 fork
  5. 模板化 + 参数化:13 个 IP 模板按 top 参数实例化,同一逻辑不同配置不再手工复制。

这五个机制共同回答了综述第 7 节提出的问题——为什么 OpenTitan 是 9 个仓库中唯一达到"可量产交付"成熟度的项目:它不是把代码放进仓库,而是把"生产代码的能力"放进了仓库。克隆下来缺的不是文件,是理解这套流水线的视角;一旦理解,116 万行代码的组织方式反而比许多几万行的项目更清晰。

8. 快速导航:按目的找代码

你想做什么 去哪里看
理解某个 IP 的功能与寄存器 hw/ip/<ip>/doc/ + data/ip_block.hjson
读某 IP 的手写 RTL hw/ip/<ip>/rtl/(跳过 reg/,那是生成物)
看某 IP 怎么被验证 hw/ip/<ip>/dv/ + dvsim*_sim_cfg.hjson
理解整芯片构成与地址映射 hw/top_earlgrey/data/top.hjson
找 xbar/pinmux/时钟树实现 hw/top_earlgrey/ip_autogen/(生成物)+ util/topgen.py(生成逻辑)
找 Ibex 处理器本体 hw/vendor/lowrisc_ibex/vendored,含 patches/
看安全启动怎么写 sw/device/silicon_creator/rom/
写软件驱动某外设 sw/device/lib/dif/dif_<ip>.h + 对应 .md
主机端烧写/调试 sw/host/opentitantool/
给新 IP 建模板/加寄存器 参照 hw/ip_templates/ + util/make_new_dif.py + util/regtool.py
复现完整仿真/构建 util/dvsim.py(验证)+ Bazel(软件)+ FuseSoCRTL 综合)

9. 小结

OpenTitan 仓库的结构可以用一句话概括:"规范驱动、生成器实现、供应商版本锁定、多 top 共享 IP 池、验证与软件同仓治理"。它把开源硬件从"共享源代码"推进到"共享完整生产体系"——这既解释了它 116 万行的体量(大量是生成物与验证资产),也解释了它为什么能成为第一个走到商用量产的开源 SoC 设计。对于想学习"如何组织一个可信开源硬件项目"的团队,这个仓库本身就是最好的教材;对于想直接使用它的工程师,建议从第 8 节的导航表入手,先建立"规范 → 生成 → 代码"的映射习惯,再深入具体模块。


附:本综述的架构图由 make_figs.py 生成(matplotlib + Noto Sans CJK),原始扫描数据与可复现脚本见同仓库 analysis/ 目录。