Quick Start
- 准备环境:安装 Vivado 2024.2 或更高版本(支持 SystemVerilog Assertions 完整语法)。
- 创建工程:新建一个 Verilog 顶层模块,包含待测设计(DUT)和断言模块。
- 编写断言:在断言模块中使用
assert property描述关键时序属性(如握手协议、FIFO 满/空标志)。 - 绑定断言:使用
bind语句将断言模块连接到 DUT 实例,无需修改 DUT 代码。 - 运行仿真:在 Vivado Simulator 或第三方仿真器(如 ModelSim/Questa)中运行至少 1000 个时钟周期。
- 查看结果:在仿真日志中搜索
assertion或FAIL;若出现失败,定位时间戳并分析波形。 - 迭代修复:根据断言失败信息修改 RTL 或测试激励,重复步骤 5-6 直至所有断言通过。
- 验收:断言在随机测试中持续通过,覆盖率(功能覆盖率)达到 90% 以上。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件/板卡 | Xilinx Artix-7 XC7A35T | 入门级 FPGA,支持 SVA 仿真 | 任何支持 SystemVerilog 仿真的 FPGA(如 Cyclone V) |
| EDA 版本 | Vivado 2024.2 | 内置仿真器支持 SVA 全部关键字 | QuestaSim 2023.4 / VCS 2024.03 |
| 仿真器 | Vivado Simulator (xsim) | 免费、与 Vivado 集成 | ModelSim SE / Riviera-PRO |
| 时钟/复位 | 100 MHz 时钟,异步低有效复位 | 断言需要时钟驱动采样 | 其他频率需调整断言采样边沿 |
| 接口依赖 | 标准 AXI4-Stream 或自定义握手 | 断言验证协议时序 | 任何具有明确时序关系的接口 |
| 约束文件 | 无(仿真不需要 XDC) | 断言仅在仿真中生效 | 若需综合后仿真,需保留断言 |
目标与验收标准
- 功能点:断言覆盖 DUT 的所有关键协议时序(如握手信号、FIFO 满/空、状态机跳转)。
- 性能指标:仿真运行时间不超过 10 分钟(100 万时钟周期),断言检查不引入额外延迟。
- 资源/Fmax:断言不消耗 FPGA 逻辑资源(仅仿真),不影响综合后 Fmax。
- 验收方式:运行回归测试,断言通过率 100%;功能覆盖率(若收集)≥ 90%。
实施步骤
工程结构
创建顶层目录 sva_fpga_demo/,包含以下子目录:
rtl/:DUT 文件,例如axis_fifo.v(一个简单的 AXI4-Stream FIFO)。sva/:断言文件,例如axis_fifo_assert.sv(使用 .sv 后缀以启用 SystemVerilog 语法)。tb/:测试台,例如tb_top.v,实例化 DUT 并绑定断言。scripts/:运行脚本。
关键模块:断言编写
// axis_fifo_assert.sv
// 断言模块:检查 AXI4-Stream 握手协议
module axis_fifo_assert (
input wire clk,
input wire rst_n,
input wire s_axis_tvalid,
input wire s_axis_tready,
input wire m_axis_tvalid,
input wire m_axis_tready,
input wire fifo_full,
input wire fifo_empty
);
// 属性 1:当 tvalid 和 tready 同时为高时,必须发生传输
property p_handshake;
@(posedge clk) disable iff (!rst_n)
s_axis_tvalid && s_axis_tready |-> ##1 1;
endproperty
assert_handshake: assert property (p_handshake)
else $error("AXI4-Stream handshake failed at time %0t", $time);
// 属性 2:FIFO 满时,s_axis_tready 必须为低
property p_full_no_ready;
@(posedge clk) disable iff (!rst_n)
fifo_full |-> !s_axis_tready;
endproperty
assert_full_no_ready: assert property (p_full_no_ready)
else $error("FIFO full but tready high at time %0t", $time);
// 属性 3:FIFO 空时,m_axis_tvalid 必须为低
property p_empty_no_valid;
@(posedge clk) disable iff (!rst_n)
fifo_empty |-> !m_axis_tvalid;
endproperty
assert_empty_no_valid: assert property (p_empty_no_valid)
else $error("FIFO empty but tvalid high at time %0t", $time);
endmodule逐行说明
- 第 1 行:注释,说明文件用途。
- 第 2 行:模块声明,名称为
axis_fifo_assert。 - 第 3-10 行:输入端口列表,包括时钟、复位、DUT 的关键信号。注意端口名与 DUT 信号名保持一致,便于绑定。
- 第 13-16 行:定义属性
p_handshake。使用@(posedge clk)指定时钟采样边沿;disable iff (!rst_n)在复位期间禁用断言;s_axis_tvalid && s_axis_tready |-> ##1 1表示“如果 tvalid 和 tready 同时为高,则下一周期必须为真”(这里用##1 1表示无条件通过,实际可检查数据有效)。 - 第 17-18 行:实例化断言
assert_handshake,失败时打印错误消息。 - 第 21-24 行:属性
p_full_no_ready,检查 FIFO 满时 tready 必须为低。 - 第 25-26 行:对应断言实例。
- 第 29-32 行:属性
p_empty_no_valid,检查 FIFO 空时 tvalid 必须为低。 - 第 33-34 行:对应断言实例。
- 第 36 行:模块结束。
绑定断言到 DUT
// tb_top.v 中的绑定语句
bind axis_fifo axis_fifo_assert u_assert (
.clk(clk),
.rst_n(rst_n),
.s_axis_tvalid(s_axis_tvalid),
.s_axis_tready(s_axis_tready),
.m_axis_tvalid(m_axis_tvalid),
.m_axis_tready(m_axis_tready),
.fifo_full(fifo_full),
.fifo_empty(fifo_empty)
);逐行说明
- 第 1 行:注释。
- 第 2 行:
bind axis_fifo将断言模块axis_fifo_assert绑定到 DUT 模块axis_fifo的每个实例上。u_assert是断言实例名。 - 第 3-10 行:端口连接,将 DUT 内部信号连接到断言模块的端口。注意信号名必须与 DUT 内部一致。
仿真运行与调试
- 运行仿真:在 Vivado Tcl 控制台执行
launch_simulation -mode behavioral,或使用脚本xsim tb_top -R。 - 查看日志:在 Tcl 控制台或仿真输出窗口搜索
Error或FAIL。 - 调试失败:点击失败消息中的时间戳,在波形窗口中查看对应时刻的信号状态。
- 常见坑:断言模块必须使用 .sv 后缀,否则 Vivado 会按 Verilog 解析,导致语法错误。
- 常见坑:
disable iff条件必须覆盖所有异步复位场景,否则复位期间可能误报失败。
原理与设计说明
SVA(SystemVerilog Assertions)是 SystemVerilog 语言的一部分,用于描述设计的行为属性。其核心机制是“时钟驱动的序列匹配”:在每个时钟边沿,评估前提(antecedent)是否成立,若成立则检查结论(consequent)是否在指定周期后成立。这种机制使得断言能够精确描述时序协议,如握手、流水线、FIFO 状态等。
为什么使用 bind 而非内嵌断言?
内嵌断言需要修改 DUT 代码,可能引入综合问题;bind 将断言模块“粘”到 DUT 上,不修改原始 RTL,便于复用和分层验证。此外,bind 支持在仿真时动态启用/禁用断言,对综合无影响。
关键 trade-off
- 资源 vs Fmax:断言仅用于仿真,不占用 FPGA 逻辑,因此不影响 Fmax。但若在综合后仿真中使用,需确保断言代码被综合工具忽略(通常使用
ifdef或综合 pragma)。 - 吞吐 vs 延迟:断言检查本身不引入延迟,但复杂的序列(如多周期匹配)可能增加仿真时间。建议将断言数量控制在 50 个以内,避免仿真速度显著下降。
- 易用性 vs 可移植性:SVA 语法在主流仿真器中基本一致,但某些高级特性(如
$past的深度、immediate assertion 的行为)可能存在细微差异。建议使用 IEEE 1800-2017 标准子集,避免工具特定扩展。
验证与结果
| 指标 | 测量值(示例) | 测量条件 |
|---|---|---|
| 断言通过率 | 100%(5000 个随机测试向量) | Vivado 2024.2, 100 MHz, 100 万时钟周期 |
| 仿真时间 | 3.2 秒 | Intel i7-12700, 32 GB RAM, 无波形转储 |
| 功能覆盖率 | 95%(握手、满/空、复位场景) | 使用内置覆盖率收集 |
| 资源占用 | 0 LUT, 0 FF(仅仿真) | 综合后无断言 |
波形特征:在断言失败时刻,波形显示 tvalid 和 tready 同时为高,但 FIFO 满标志也为高,违反了属性 p_full_no_ready。修复后,tready 在 FIFO 满时保持低电平,断言通过。
故障排查(Troubleshooting)
- 现象:仿真报错
syntax error在断言文件。原因:文件后缀为 .v 而非 .sv。检查点:确认文件扩展名为 .sv。修复建议:重命名文件或使用-sv编译选项。 - 现象:断言从未触发(既无通过也无失败)。原因:
disable iff条件始终为真(如复位信号极性错误)。检查点:在波形中观察rst_n电平。修复建议:修正复位极性或移除disable iff调试。 - 现象:断言在复位期间误报失败。原因:
disable iff未包含所有复位场景。检查点:确认复位信号在断言属性中正确使用。修复建议:添加disable iff (!rst_n)或使用$asserton/$assertoff控制。 - 现象:仿真速度极慢。原因:断言数量过多或使用了复杂的
$past深度。检查点:统计断言数量,检查$past调用。修复建议:减少断言数量,简化序列。 - 现象:
bind语句报错module not found。原因:断言模块未编译或路径错误。检查点:确认断言文件被包含在编译文件列表中。修复建议:在 Vivado 中添加 .sv 文件到仿真文件集。 - 现象:断言失败但设计功能正确。原因:断言属性描述错误(如时序边界不匹配)。检查点:对照协议规范检查属性逻辑。修复建议:修正属性中的前提或结论。
- 现象:在综合后仿真中断言不工作。原因:综合工具忽略了断言模块。检查点:确认综合设置中未禁用 SVA。修复建议:使用
pragma translate_on/off包裹断言代码。 - 现象:断言报告
multiple drivers错误。原因:断言模块中错误地驱动了 DUT 信号。检查点:检查断言模块端口方向(应为 input)。修复建议:确保断言模块只读取信号,不驱动。
扩展与下一步
- 参数化断言:使用
generate块和参数,为不同位宽或深度的 FIFO 自动生成断言。 - 功能覆盖率:结合
cover property收集协议场景覆盖率,如“tvalid 和 tready 同时为高”的覆盖点。 - 形式验证:将断言作为形式验证工具(如 Synopsys VC Formal)的属性输入,证明设计在所有可能输入下都满足属性。
- 跨平台复用:将断言模块封装为 UVM 序列,集成到 UVM 验证环境中,实现仿真与形式验证的统一。
- 断言覆盖率分析:使用
assertion coverage命令生成报告,识别未覆盖的协议场景。 - 自动生成断言:利用脚本(如 Python + pySVA)从协议规范自动生成断言代码,减少手动编写错误。
参考与信息来源
- IEEE Std 1800-2017: SystemVerilog Language Reference Manual
- Xilinx UG900: Vivado Design Suite User Guide: Logic Simulation (2024.2)
- Mentor Graphics: Assertion-Based Verification with SystemVerilog (2023)
- “SVA: The Power of Assertions in SystemVerilog” by Eduard Cerny (Springer, 2022)
技术附录
术语表
- SVA: SystemVerilog Assertions,用于描述设计行为的属性语言。
- bind: 将断言模块绑定到 DUT 实例的语句。
- property: 属性,描述一个时序条件。
- assert: 断言语句,验证属性是否成立。
- disable iff: 在特定条件下禁用断言。
- $past: 系统函数,返回前 N 个时钟周期的信号值。
检查清单
- [ ] 断言文件后缀为 .sv。
- [ ] 所有断言使用
disable iff处理异步复位。 - [ ] 断言模块端口方向为 input,不驱动 DUT 信号。
- [ ]
bind语句在测试台顶层,不在 DUT 内部。 - [ ] 仿真日志中搜索
Error确认无断言失败。 - [ ] 功能覆盖率报告已生成并审查。
关键约束速查
- 时钟约束:断言使用
@(posedge clk),仿真无需 XDC。 - 复位约束:
disable iff (!rst_n)确保复位期间断言被禁用。 - 时序边界:使用
##[0:N]表示延迟范围,避免使用绝对时间。 - 禁止使用:
$rose/$fell在组合逻辑属性中可能导致仿真-综合不匹配。

评论 0