问询SystemVerilog中调用$finish后执行预设代码块的实现方法
SystemVerilog $finish触发后执行自定义收尾逻辑的实现方案
SystemVerilog标准本身没有提供$finish执行后的原生回调钩子,但可以通过编译阶段全局宏替换的方式实现需求,完全不需要修改任何已有的测试用例,也不需要引入UVM等框架。
核心实现方案(零修改存量代码,全仿真器兼容)
具体操作步骤
- 第一步:编写独立的通用收尾逻辑文件,比如命名为
finish_hook.sv,内容如下:
// 自定义收尾任务,兼容原生$finish的入参 task custom_finish(int finish_level = 0); // 此处写入所有你需要执行的预定义收尾任务 print_test_result_summary(); dump_functional_coverage_report(); close_all_open_file_handles(); clear_shared_memory_resources(); // 收尾逻辑执行完成后调用原生$finish,加反斜杠避免被宏重复替换 \$finish(finish_level); endtask
- 第二步:在仿真编译命令中添加全局宏定义参数,将所有代码中的
$finish替换为你的自定义任务,不同仿真器的参数写法略有区别:- Synopsys VCS:添加编译参数
+define+$finish=custom_finish - Siemens Questa/Modelsim:添加编译参数
-define $finish=custom_finish - Cadence Xcelium:添加编译参数
-define $finish=custom_finish
- Synopsys VCS:添加编译参数
- 第三步:编译时将
finish_hook.sv放在编译队列的最前面,保证宏定义在所有代码解析前生效。
方案优势
- 完全不侵入存量测试代码,开发人员无需调整原有编码习惯,仍然按常规方式调用
$finish即可 - 逻辑完全透明,后台收尾任务的修改不影响上层测试用例
- 兼容所有主流商用仿真器,不需要依赖任何第三方框架
补充方案(仿真器特定实现)
如果你的项目固定使用某一款仿真器,也可以通过仿真器提供的可编程接口注册退出回调:
- VCS可以通过VHPI接口调用
vhpi_register_cb注册退出类回调 - Questa可以通过FLI接口调用
mti_AddQuitCB注册退出前执行的函数
该方案的局限性是和仿真器强绑定,迁移仿真工具时需要重新适配,通用性不如宏替换方案。
内容的提问来源于stack exchange,提问作者mmillar10
相关产品推荐
相关产品推荐

