2. 设计规格检查:需求文档与设计实现的一致性检查,功能规格的完整性

好,咱们直接进入正题。设计规格检查,说白了就是两件事:你写的代码,跟需求文档里说的是不是一回事?需求文档自己,有没有漏掉什么?

我见过太多团队,需求文档写得很漂亮,结果流片回来一跑,功能对不上。为什么?因为文档是文档,代码是代码,中间隔着一道“理解偏差”的鸿沟。今天咱们就来填平这道沟。

2.1 一致性检查:文档与代码的“对账”

我个人习惯,拿到一份需求文档,先不看代码,先自己把文档里的功能点列出来。然后拿着这份清单,去跟RTL代码逐条比对。这不是简单的“文档写了A,代码实现了A”就完事了。

举个例子,文档里写“支持突发传输,最大长度256”。你代码里确实实现了突发传输,但突发长度上限是128。这算不算一致?算,但也不完全算。功能上实现了,但规格上打了折扣。这种“软不一致”最容易在后期验证阶段爆雷。

核心检查项:
  • 接口协议:文档定义的信号名、位宽、时序,与代码中的接口是否完全匹配?
  • 功能行为:每个功能模式下的状态跳转、输出响应,是否与文档描述一致?
  • 边界条件:文档中提到的“最大/最小值”、“异常处理”,代码里是否都有对应实现?
  • 配置寄存器:文档里定义的寄存器地址、位域、默认值,与RTL中的寄存器模型是否一一对应?

我在项目中遇到过一件事:文档里写了一个“保留位”,说必须写0。代码里也确实没用到这个位。但验证工程师发现,如果往这个保留位写1,芯片会进入一个未定义状态。这就是典型的“文档没说清楚,代码也没检查”的坑。

我的小技巧: 做一个“需求-代码”交叉矩阵表。横轴是文档里的功能点,纵轴是RTL模块。每个交叉点打勾或打叉。一目了然。

2.2 功能规格完整性:别让“想当然”害了你

完整性检查,说白了就是问自己:“这个功能,在什么情况下会出问题?”

很多需求文档只写了“正常情况”下的行为。但芯片设计,最怕的就是“异常情况”。比如:

  • 输入数据全为0时,模块会怎样?
  • 时钟频率降到最低时,还能正常工作吗?
  • 多个中断同时触发,优先级处理对吗?
  • 复位释放后,所有寄存器的初始值是否符合预期?

我曾经吃过一次大亏。一个通信接口的文档,只写了“数据有效时,输出数据”。但没写“数据无效时,输出应该保持还是清零”。我默认保持了上一次的值。结果验证工程师发现,在某些场景下,这个“保持”行为会导致后续模块误触发。最后不得不加一个MUX来清零,白白浪费了面积。

避坑指南: 我曾经在检查一个DMA控制器的规格时,发现文档里只写了“传输完成”和“传输错误”两种中断。但实际应用中,还有“传输过半”和“描述符链空”两种场景。如果没加,软件工程师就得轮询状态寄存器,性能大打折扣。所以,完整性检查一定要拉上软件团队一起过。

2.3 一个实用的检查框架

我自己总结了一个“三遍检查法”,分享给你:

  1. 第一遍:通读。从头到尾读一遍需求文档,不纠结细节,只抓大框架。看看有没有明显的逻辑断层。
  2. 第二遍:细读。对照RTL代码,逐条核对。用表格记录所有不一致的地方。
  3. 第三遍:反读。从代码反推文档。看看代码里有没有“文档没写,但代码实现了”的功能。这些往往是隐藏的雷。

你想想看,如果这三遍走下来,文档和代码还能有大的出入,那基本就是需求本身有问题了。

2.4 知识体系图:设计规格检查的核心逻辑

下面这张图,是我做规格检查时脑子里的“地图”。你可以参考一下:

设计规格检查核心逻辑 需求文档 RTL代码 一致性检查 完整性检查 接口协议匹配 功能行为一致 边界条件覆盖 寄存器模型对齐 输出:检查报告 + 修改建议

这张图的核心逻辑很简单:需求文档和RTL代码通过“一致性检查”对齐,再通过“完整性检查”补漏,最终输出一份可靠的检查报告。每一步都不能省。

2.5 一个简单的检查表示例

最后,给你一个我常用的检查表模板。你可以直接拿去用:

检查项 需求文档描述 RTL实现 是否一致 备注
突发传输最大长度 256 128 需修改RTL或更新文档
中断类型 完成、错误 完成、错误、过半 部分 文档遗漏“过半”中断
保留位处理 写0 忽略写值 但建议加写0保护
复位默认值 全0 全0

嗯,这个表看起来简单,但每次流片前,我都会带着团队过一遍。别嫌麻烦,流片前多花一小时,流片后能省一周。


公众号:蓝海资料掘金营,微信deep3321