2. 设计规格检查:需求文档与设计实现的一致性检查,功能规格的完整性
好,咱们直接进入正题。设计规格检查,说白了就是两件事:你写的代码,跟需求文档里说的是不是一回事?需求文档自己,有没有漏掉什么?
我见过太多团队,需求文档写得很漂亮,结果流片回来一跑,功能对不上。为什么?因为文档是文档,代码是代码,中间隔着一道“理解偏差”的鸿沟。今天咱们就来填平这道沟。
2.1 一致性检查:文档与代码的“对账”
我个人习惯,拿到一份需求文档,先不看代码,先自己把文档里的功能点列出来。然后拿着这份清单,去跟RTL代码逐条比对。这不是简单的“文档写了A,代码实现了A”就完事了。
举个例子,文档里写“支持突发传输,最大长度256”。你代码里确实实现了突发传输,但突发长度上限是128。这算不算一致?算,但也不完全算。功能上实现了,但规格上打了折扣。这种“软不一致”最容易在后期验证阶段爆雷。
- 接口协议:文档定义的信号名、位宽、时序,与代码中的接口是否完全匹配?
- 功能行为:每个功能模式下的状态跳转、输出响应,是否与文档描述一致?
- 边界条件:文档中提到的“最大/最小值”、“异常处理”,代码里是否都有对应实现?
- 配置寄存器:文档里定义的寄存器地址、位域、默认值,与RTL中的寄存器模型是否一一对应?
我在项目中遇到过一件事:文档里写了一个“保留位”,说必须写0。代码里也确实没用到这个位。但验证工程师发现,如果往这个保留位写1,芯片会进入一个未定义状态。这就是典型的“文档没说清楚,代码也没检查”的坑。
2.2 功能规格完整性:别让“想当然”害了你
完整性检查,说白了就是问自己:“这个功能,在什么情况下会出问题?”
很多需求文档只写了“正常情况”下的行为。但芯片设计,最怕的就是“异常情况”。比如:
- 输入数据全为0时,模块会怎样?
- 时钟频率降到最低时,还能正常工作吗?
- 多个中断同时触发,优先级处理对吗?
- 复位释放后,所有寄存器的初始值是否符合预期?
我曾经吃过一次大亏。一个通信接口的文档,只写了“数据有效时,输出数据”。但没写“数据无效时,输出应该保持还是清零”。我默认保持了上一次的值。结果验证工程师发现,在某些场景下,这个“保持”行为会导致后续模块误触发。最后不得不加一个MUX来清零,白白浪费了面积。
2.3 一个实用的检查框架
我自己总结了一个“三遍检查法”,分享给你:
- 第一遍:通读。从头到尾读一遍需求文档,不纠结细节,只抓大框架。看看有没有明显的逻辑断层。
- 第二遍:细读。对照RTL代码,逐条核对。用表格记录所有不一致的地方。
- 第三遍:反读。从代码反推文档。看看代码里有没有“文档没写,但代码实现了”的功能。这些往往是隐藏的雷。
你想想看,如果这三遍走下来,文档和代码还能有大的出入,那基本就是需求本身有问题了。
2.4 知识体系图:设计规格检查的核心逻辑
下面这张图,是我做规格检查时脑子里的“地图”。你可以参考一下:
这张图的核心逻辑很简单:需求文档和RTL代码通过“一致性检查”对齐,再通过“完整性检查”补漏,最终输出一份可靠的检查报告。每一步都不能省。
2.5 一个简单的检查表示例
最后,给你一个我常用的检查表模板。你可以直接拿去用:
| 检查项 | 需求文档描述 | RTL实现 | 是否一致 | 备注 |
|---|---|---|---|---|
| 突发传输最大长度 | 256 | 128 | 否 | 需修改RTL或更新文档 |
| 中断类型 | 完成、错误 | 完成、错误、过半 | 部分 | 文档遗漏“过半”中断 |
| 保留位处理 | 写0 | 忽略写值 | 是 | 但建议加写0保护 |
| 复位默认值 | 全0 | 全0 | 是 | 无 |
嗯,这个表看起来简单,但每次流片前,我都会带着团队过一遍。别嫌麻烦,流片前多花一小时,流片后能省一周。
公众号:蓝海资料掘金营,微信deep3321