IP模块形式化验证流程与案例分析 - 第4节
4.1 本章学习任务:IP 模块验证需求分析
形式化验证不是凭空写断言,而是从“需求”出发,把自然语言规格转变成可验证的数学属性。本章围绕三条主线展开:规格提取、断言映射、验证计划制定。掌握这三步,就能为任意 IP 模块搭建起形式化验证的骨架。
学习目标:
- 理解规格提取的输入、输出与质量要求;
- 掌握从设计文档到断言映射的拆解方法;
- 学会制定覆盖功能、时序、安全属性的验证计划。
4.2 问题背景:为什么验证需求分析决定形式化效果
实际项目中,形式化验证失败的常见原因并非工具能力不足,而是需求侧出了问题:规格含糊、断言遗漏、验证目标不明确。形式化验证的“穷举”特征决定了它必须首先回答三个问题:
- 证明什么?——属性的精确定义;
- 在什么边界内证明?——输入范围、状态空间约束;
- 证明到什么程度算完成?——覆盖率和属性完备性。
这三个问题全部来自验证需求分析。若跳过该阶段,断言很容易退化为“实现代码的转写”,失去验证意义。
4.3 核心概念:三大关键对象
| 概念 | 定义 | 形式化验证中的角色 |
|---|---|---|
| 规格(Specification) | 对设计行为的精确、无歧义描述 | 断言和验证计划的唯一事实来源 |
| 断言(Assertion) | 用 SVA/PSL 表达的时序或组合属性 | 将规格映射为可证明/可仿真的检查器 |
| 验证计划(Verification Plan) | 验证活动、属性列表、覆盖点与退出准则 | 保证证明工作完整、可量化、可追溯 |
三者关系:规格提取产生高质量规格;断言映射让规格可执行;验证计划确保验证闭环。下图给出整体流程框架。
4.4 原理机制:三层规格模型
规格提取的质量直接决定断言映射的难度。建议采用三层规格模型逐层收敛:
- 行为规格(Behavioral Spec):描述“做什么”,如读操作返回数据、请求必须响应;
- 时序规格(Temporal Spec):描述“什么时候做”,如读请求与读数据之间的周期关系;
- 接口规格(Interface Spec):描述“怎么交互”,如握手协议、总线仲裁规则、跨时钟域约束。
三层规格分别对应不同的断言类型:行为规格映射为组合断言和功能断言;时序规格映射为蕴含断言和序列断言;接口规格映射为协议断言和同步/异步约束。
4.5 流程步骤:从规格到验证计划
标准流程分为六个步骤,每一步都有明确产出物和检查点。
| 步骤 | 输入 | 动作 | 输出 | 质量检查点 |
|---|---|---|---|---|
| 1. 需求收集 | 设计文档、协议标准、变更记录 | 列出所有功能点、时序要求、接口约束 | 需求清单 | 无遗漏、无歧义 |
| 2. 规格抽取 | 需求清单 | 将每一条需求改写为“条件→结果”形式 | 结构化规格表 | 每项可衡量、可验证 |
| 3. 规格优先级排序 | 结构化规格表 | 按风险、复杂度、安全等级划分 P0/P1/P2 | 优先级矩阵 | P0 必须证明,P1 尽量证明,P2 可用仿真补充 |
| 4. 断言映射 | 结构化规格表 | 逐条编写 SVA/PSL 属性,定义输入约束与时钟 | 断言文件(.sva/.psl) | 每条断言可追溯至规格 ID |
| 5. 验证计划编制 | 断言文件、约束文件 | 定义证明策略、覆盖点、超时阈值 | 验证计划文档 | 覆盖点能反映未覆盖行为 |
| 6. 评审与迭代 | 全部上述产物 | 设计人员、验证人员、架构师联合评审 | 评审结论 / 需求变更 | 问题清零或挂起有明确责任人 |
4.6 案例说明:一个简单的 AXI-Lite 从机模块
以 AXI-Lite 从机接口验证需求分析为例,快速展示三个过程的产物。
4.6.1 规格提取(局部)
原始文档描述:
- 当收到 AWVALID 为高时,从机必须保证 AWREADY 在下一个时钟上升沿之前拉高。
- 写数据 WVALID/WREADY 握手必须在 AWVALID/AWREADY 握手完成后发生。
- 写响应 BVALID 必须在 WVALID/WREADY 握手完成后产生。
| ID | 行为规格 | 时序规格 |
|---|---|---|
| AXI-1 | AWVALID 与 AWREADY 握手成功 | AWREADY 在 AWVALID 拉高后不超过 1 拍拉高 |
| AXI-2 | 写数据通道不能早于地址通道完成 | WVALID 不得在 AWREADY 拉高之前持续拉高 |
| AXI-3 | 写响应必须出现在写数据之后 | BVALID 在 WREADY 拉高后 1~N 拍内拉高 |
4.6.2 断言映射(局部)
// AXI-1:AWREADY 不晚于 AWVALID 后 1 拍拉高
property p_awready_no_later_than_1;
@(posedge clk)
$rose(AWVALID) |-> ##[0:1] AWREADY;
endproperty
assert property (p_awready_no_later_than_1);
// AXI-2:写数据通道不能先于地址通道握手
property p_wvalid_after_aw_handshake;
@(posedge clk)
$rose(WVALID) |-> !AWVALID || $past(AWREADY);
endproperty
assert property (p_wvalid_after_aw_handshake);
// AXI-3:写响应在写数据握手后 1~8 拍内拉高
property p_bvalid_after_w_handshake;
int delay;
@(posedge clk)
(WVALID && WREADY) |-> ##[1:8] BVALID;
endproperty
assert property (p_bvalid_after_w_handshake);
注意:上述第 3 条断言的 8 拍上限来自设计规格,若规格中未明确写响应延迟窗口,则不能随意添加“1~8”约束。形式化验证中,任何定时上限都必须能从规格文本中溯源。
4.6.3 验证计划制定(局部)
| 类型 | 描述 | 覆盖点 / 检查项 | 优先级 |
|---|---|---|---|
| 核心协议属性 | AW、W、B 三通道握手顺序 | 覆盖:AW 握手后 W 握手、W 握手后 B 握手 | P0 |
| 响应数据正确性 | 写响应通道返回状态 | BRESP 值合法性检查 | P0 |
| 复位行为 | 复位期间信号默认值 | 检查 ARESETn 拉低时所有输出为 0 | P1 |
| 并发场景 | AW 与 W 同时到达 | 覆盖两通道同时有效;证明不死锁 | P1 |
| 地址越界 | 写地址超出从机地址范围 | SLVERR 响应生成 | P1 |
4.7 表格总结:三种能力对比
| 环节 | 核心能力 | 常用产出 | 常见失败模式 |
|---|---|---|---|
| 规格提取 | 把自然语言转化为结构化、可验证的行为描述 | 规格表、优先级矩阵、时序图 | 规格含糊、缺少边界条件、多时钟交互描述缺失 |
| 断言映射 | 将结构化规格写成语义等价的 SVA/PSL | 断言文件、约束文件、 bind 模块 | 断言与规格语义错位、时序窗口错误、过度约束 |
| 验证计划制定 | 组织证明活动、覆盖指标和收尾标准 | 验证计划表、覆盖率模型、回归清单 | 覆盖点只盯断言数量、遗漏负向场景、退出准则模糊 |
4.8 误区提醒
- 误区 1:规格提取等于“读文档”。
实际需要写出来、评出来、形成版本化产物,否则断言无法追溯。 - 误区 2:断言映射越“严”越好。
过度约束会掩盖真实错误,导致形式化证明通过但不保证功能正确。 - 误区 3:验证计划只关注“断言数量”。
更重要的是覆盖点的结构分布:不同的输入组合、关键内部状态、连续事务间隔等。 - 误区 4:把仿真中用的断言直接拿来做形式化。
形式化需要更精确的输入约束和更严谨的时序窗口,否则会出现反例或证明不终止。 - 误区 5:忽略规格变更后的回归。
版本更新后,要重新检查规格优先级、断言映射和计划覆盖,而不是只重跑工具。
4.9 实践清单:开始 IP 验证需求分析
- 建立规格追踪矩阵,每条规格有唯一 ID,关联原始文档段落。
- 为每个功能点标注验证方式:形式化证明 / 仿真 / 二者组合。
- 列出 P0 属性清单,确认均位于可证明范围(无复杂浮点运算、无未知内部状态)。
- 编写断言命名规范:
p_模块_功能_性质,例如p_axi_awready_handshake。 - 明确输入约束:时钟建模、复位建模、输入随机性范围。
- 定义覆盖点:至少包括关键使能信号翻转、握手完成、FIFO 满/空、异常响应。
- 设定证明超时阈值:例如单属性 30 分钟内未收敛则拆分或给假设。
- 安排评审节点:规格评审、断言评审、验证计划评审,分别由设计、验证、架构三方参与。
工程提示:形式化验证需求分析阶段建议投入总工期的 30%~40%。这一阶段的返工成本最低,但对后续收敛速度影响最大。规格表多写一行明确的时序约束,可能节省工具求解数小时。