IC项目Spec文档Markdown模板:一份可直接复制的章节骨架与填写要点
芯片项目里最容易被低估的文档就是 Spec(规格书)。RTL 写得再漂亮,接口语义、寄存器地址、时序预算没落在纸面上,验证和软件就只能靠猜。这篇给一份 IC项目Spec文档Markdown模板:整段骨架可以直接复制进你的仓库,每一节都带「填写要点」注释,末尾用一个虚构的 UART 收发模块示范填好以后长什么样。如果你还没想清楚 Spec 写完后怎么拆模块,可以先看姊妹篇从需求 spec 到架构:怎么把「做个 U 盘控制器」拆成模块。
上面这张卡把八个章节按读者分成三摞:管理者只看定位和交付,设计同事关心功能与时序,验证和软件盯着接口与寄存器表。写 Spec 时每落一笔都问一句「这行是给谁看的」,位置错了就挪,这比追求辞藻重要得多。
本文要回答的问题
- 一份能直接开工的 IC 模块 Spec 至少要有哪些章节?
- 每一节应该写到什么颗粒度,哪些是必填项?
- 有没有一份完整可复制、改改就能用的 Markdown 模板?
- 真实填写时有哪些常见坑(比如寄存器表和接口信号表打架)?
一、使用场景与写作原则
这份模板适用于模块级 Spec:一个 UART、一个 SPI 控制器、一个 DMA 通道这个粒度的 IP。SoC 顶层 Spec 章节更多(还要电源域、引脚复用、安全启动等),但骨架相通。
三条写作原则:
- Markdown 纯文本入库:跟 RTL 放同一个 git 仓库,review 走同一条 PR 流程,谁改了规格一目了然。Word 文档最大的问题是二进制无法 diff,改了个比特位没人知道。
- 每个数字只能有一个权威出处:波特率列表写在功能规格里,寄存器表就只引用、不复述,两处写两遍必然漂移。
- 先写接口和寄存器,再写内部行为:接口是契约,内部实现是承诺的实现方式,读者关心的顺序就是这个顺序。
二、完整可复制的模板
把下面整段复制为 doc/<模块名>-spec.md,把尖括号占位符替换掉即可。注释行(<!-- --> 包裹的「填写要点」)填写完成后删掉。
# <模块名> 设计规格书
- 版本:v0.1(草稿)/ v1.0(冻结)
- 作者 / 评审:<姓名>
- 状态:草稿 / 评审中 / 已冻结
<!-- 填写要点:版本冻结后任何改动必须升版本号并写修订记录,
验证与软件以「冻结版」为准。 -->
## 1. 概述
<!-- 填写要点:三句话以内——模块做什么、挂在哪个总线上、
关键指标一行(速率/面积/功耗数量级)。 -->
<一句话功能定位>。<总线/系统集成方式>。<关键指标>。
## 2. 功能规格
<!-- 填写要点:逐条编号 FG-1、FG-2……每条可验证;
避免「支持高速传输」这种无法写断言的措辞。 -->
- FG-1:<可验证的功能点>
- FG-2:<可验证的功能点>
## 3. 接口定义
<!-- 填写要点:信号名/方向/位宽/时钟域/复位值/一句话语义;
与 RTL 端口逐一对齐,评审时 diff 端口表。 -->
| 信号 | 方向 | 位宽 | 时钟域 | 说明 |
|---|---|---|---|---|
| <sig> | input | 1 | <clk> | <语义> |
## 4. 寄存器表
<!-- 填写要点:地址偏移/名称/权限(RW/RO/W1C)/复位值/字段;
这是软件驱动的唯一契约,冻结后不得改地址。 -->
| 偏移 | 名称 | 权限 | 复位值 | 说明 |
|---|---|---|---|---|
| 0x00 | <REG> | RW | 0x0 | <说明> |
## 5. 时钟与复位
<!-- 填写要点:时钟个数与频率范围、复位极性与同步/异步、
跨时钟域信号列表及同步方式。 -->
## 6. 时序要求
<!-- 填写要点:输入建立/保持、输出延迟、关键路径预算;
数字必须给测量条件(电压/温度/工艺角)。 -->
## 7. 验证策略
<!-- 填写要点:验证方法(仿真/形式验证/FPGA)、覆盖率目标、
每条 FG-* 对应的测试点编号。 -->
## 8. 交付物清单
<!-- 填写要点:RTL、本 Spec、验证环境、综合脚本、
寄存器头文件(.h/.json)各自的路径与完成标准。 -->
## 修订记录
| 版本 | 日期 | 改动 | 作者 |
|---|---|---|---|三、填写示范:虚构的 UART 模块
光看骨架没感觉,下面摘几节真实风格的填写示范(模块名为虚构的 uart_lite,一个挂在 APB 总线上的精简 UART):
概述:
uart_lite 是一个全双工 UART 收发器,挂在 32 位 APB 从接口上,最高波特率 3 Mbaud,收发各带 16 字节 FIFO,目标面积 8 kGE(NAND2 等效门)以内。
功能规格(注意每条都能写成断言):
- FG-1:支持 8N1 / 8E1 / 8O1 三种帧格式,由 CTRL[3:2] 选择。
- FG-2:接收 FIFO 深度 16,溢出时置 STATUS.OVERRUN 并丢弃新字节,已存数据不丢。
- FG-3:波特率分频比 = round(f_clk / (16 × baud)),误差超过 ±2% 时 BAUDERR 告警。
寄存器表(节选):
| 偏移 | 名称 | 权限 | 复位值 | 说明 |
|---|---|---|---|---|
| 0x00 | CTRL | RW | 0x0000_0000 | bit0 TXEN,bit1 RXEN,bit[3:2] 帧格式 |
| 0x04 | STATUS | RO | 0x0000_0002 | bit0 TXBUSY,bit1 RXEMPTY,bit2 OVERRUN(W1C) |
| 0x08 | BAUDDIV | RW | 0x0000_0036 | 16 倍过采样分频系数 |
| 0x0C | TXDATA / RXDATA | WO/RO | — | 写=压发送 FIFO,读=弹接收 FIFO |
寄存器表的写法细节(权限缩写、W1C 语义、地址规划)在寄存器表与地址解码:软件怎么靠一组寄存器驱动硬件里有专门展开,这里不复述——这本身就是「单一权威出处」原则的示范。
时序要求(节选):
APB 侧寄存器读数据在 PENABLE 拉高后一拍内有效;TXD 输出相对 pclk 上升沿延迟 < 2 ns(tt 角、25 ℃、0.9 V)。RXD 输入要求相对 pclk 建立时间 ≥ 3 ns,模块内部做两级同步。
四、使用注意事项
- 接口表与寄存器表不要互相抄写:信号表讲引脚级语义,寄存器表讲软件视图,两份内容天然不重叠;如果发现同一信息写两遍,删掉一份。
- 时序数字必须带条件:裸写一个「延迟 < 2 ns」没有意义,工艺角、电压、温度三个条件缺一个就是吵架的种子。
- 冻结后走修订记录:验证环境搭起来以后再改寄存器地址,代价是验证代码和驱动全返工——所以 v1.0 之后的改动必须在修订记录里出现,让下游有迹可查。
- 功能条目编号别重排:FG-3 被删就让它空着或标「废弃」,不要把 FG-4 改名 FG-3,验证报告里的引用会全部错位。
- 章节留空写「N/A」而不是删掉:结构稳定,读者不用每收到一版 Spec 重新适应目录。
五、修改示范:从 UART 改到 SPI
模板复用的正确姿势是「改内容不改骨架」。把 uart_lite 换成一个 SPI 主机模块时的典型改动:
- 接口定义:信号从 TXD/RXD 换成 SCLK/MOSI/MISO/CS_N,并新增「CS 到首个 SCLK 的建立时间」这类 SPI 特有参数。
- 寄存器表:BAUDDIV 改名 CLKDIV,语义从「16 倍过采样」改成「SCLK 分频比」,CPOL/CPHA 两个模式位进 CTRL——注意新增字段优先用保留位,不挪动已有比特。
- 功能规格:FG 条目换成「支持模式 0-3」「支持连续片选与手动片选两种时序」等,编号体系原样保留。
- 时序要求:新增 MISO 建立/保持窗口,与 datasheet 手册的阅读方法对照可参考怎么读芯片手册:datasheet、user guide、register map 各看什么。
骨架八节一节不动,改的全是单元格里的内容——这就是模板存在的意义:评审者每次看新模块 Spec,永远知道第 4 节是寄存器表。
这一篇在知识体系里的位置
本篇属于 chip-design 入门系列的「工程方法」支线:Spec 是设计流程的第一个交付物。向上承接从需求 spec 到架构(Spec 写完后怎么拆模块),向下衔接寄存器表与地址解码(寄存器表那一节的深化)与怎么读芯片手册(看别人写的成品规格书长什么样)。
总结
这份 IC项目Spec文档Markdown模板把模块规格书收敛成八节骨架:概述、功能规格、接口定义、寄存器表、时钟复位、时序要求、验证策略、交付物清单,外加修订记录。核心纪律只有三条:Markdown 入库可 diff、每个数字单一权威出处、骨架冻结只改内容。复制模板、按 UART 示范的颗粒度填写、守住这五条注意事项,就能得到一份验证和软件不约你开会也能开工的 Spec。