在芯片验证过程中,检查器(Checker)是确保设计符合协议规范的关键工具。本文基于一篇技术论文,分享如何为AMBA协议(如AXI、AHB)构建可重用的检查器IP(Checker IP,简称CIP),并简化其核心思路,帮助工程师快速上手。
一、什么是Checker IP?
Checker IP是一组用SystemVerilog编写的代码,用于检查设计是否符合协议规范。它包含三类核心功能:
- 断言(Assert):检查信号行为是否符合预期(例如:“Master必须发送有效的请求信号”)。
- 假设(Assume):定义输入信号的约束条件(例如:“Slave收到的请求信号必须合法”)。
- 覆盖(Cover):跟踪关键场景是否被测试到(例如:“是否覆盖了所有突发传输类型?”)。
与传统的验证IP(VIP)不同,CIP专注于“检查”而非“激励生成”,因此既能用于仿真验证,也可适配形式验证工具。
二、Checker IP的设计要点
1. 协议兼容性
AMBA协议(如AXI3)通常包含主(Master)和从(Slave)设备,二者对同一信号的检查逻辑可能不同。例如:
- Master端需要检查自己发出的信号是否合法(用
assert
)。 - Slave端则需假设接收的信号合法(用
assume
)。
因此,CIP需设计为可配置模块,同一段代码能根据场景切换为断言或假设。
2. 代码封装方式
SystemVerilog提供了多种封装检查器的方式:
- 模块(Module):最常用,通过
bind
命令将检查器绑定到设计模块中。 - 接口(Interface):适合与UVM测试平台配合,避免模块嵌套问题。
- Checker构造:语法更灵活,但工具兼容性较差,建议用于简单场景。
示例:使用bind
将AXI检查器绑定到设计模块:
bind dut_axi_master cip_axi_master checker_inst (.*);
三、编码注意事项
1. 避免仿真与形式验证的冲突
- 屏蔽工具专用代码:例如,UVM的错误报告代码需用宏定义包裹,防止形式验证工具报错。
`ifdef SIMULATION uvm_error("CHECK_FAIL", "信号超时!");
`endif
- 谨慎使用时序函数:如
$past
可能因初始值导致误报。建议添加延迟:
// 错误示例:直接使用$past
assert (req → ##2 $past(ack)); // 正确示例:延迟检查起点
assert (##1 req → ##2 $past(ack));
2. 参数化与可配置性
- 使用
parameter
和generate
支持不同协议配置(如AXI3/AXI4、数据位宽等)。 - 为可选信号(如AXI的锁定信号
LOCK
)添加条件编译开关。
四、如何验证Checker IP本身?
检查器本身也需要验证!推荐方法:
- 单元测试:针对每条断言编写测试用例,覆盖合法和非法场景。
- 自动化检查:使用SVUnit框架,自动捕获预期错误。
// 示例:用SVUnit检查断言是否触发
uvm_report_mock::expect_error("非法传输");
run_test();
uvm_report_mock::check_expected_errors();
五、总结
构建Checker IP的核心目标是:将协议规范转化为可重用、可配置的检查代码。关键步骤包括:
- 区分断言与假设,适配主从设备需求。
- 选择兼容性高的封装方式(模块或接口)。
- 编写自检单元测试,确保检查器自身可靠。
通过以上方法,可以显著提升验证效率,缩短项目周期。
延伸阅读:
- SystemVerilog断言手册
- ARM AXI协议文档
希望这篇博客能帮助你快速理解Checker IP的设计思路。如有疑问,欢迎留言讨论!
参考文章
Architecting “Checker IP” for AMBA
protocols