【SVA】功能覆盖率——断言常用写法



前言

断言(assertion)是验证工作中常用的自动检查手段,相比于checker或者reference model更加轻量化也更方便移植,同时也是收集功能覆盖率的重要一环。


一、断言分类

1、即时断言 Immediate Assertions

即时断言作用和 if 语句的效果类似,在仿真运行到这句代码时做出判断。

int a;
assert(a) else `uvm_error(get_type_name(), "assert fail");
if(a) else `uvm_error(get_type_name(), "assert fail");

如上两句代码,在验证环境中效果是一样的,都是运行到这行代码时,a非0就报错。
需要注意的是,断言如果违例,默认报错的信息是“ Offending xxx ”,加上 else `uvm_error() 语句会更加方便。

2、并发断言 Concurrent Assertions

并发断言是最常用的,一般和时序强相关的检查都可以用这种形式实现,本文内容也主要描述并发断言。
并发断言需要指定采样时钟,可以在module、interface里实现,在整个仿真周期内都起效。

ast_ack_when_req: assert property(@(posedge clk) disable iff(~rstn) ack |-> req)
else `uvm_error("xxx", "ast_ack_when_req fail");

如上就是一个简单的检查,在rstn为1时生效,每当clk的上升沿判断,如果当拍a为高,检查下一拍b为高,否则报错。
符号|->称为蕴含符,只有当蕴含符前面的条件满足时,才检查后面的时序是否正确。

二、常见用法

1、generate

断言和verilog语句类似,只是多了一些独特的用法和关键词,也支持用generate语句批量产生断言。如果DUT内有一个module例化多份,一个断言规则在这些实例中都适用,那么这个功能就很好用。

	`define INST(num) tb_top.dut.inst``num	// 宏定义路径,用法详见文章 [宏定义日常用法](https://blog.csdn.net/Zwwang97/article/details/136601241)
	generate
		for(genvar num=0; num<4; num++) begin: inst_gen
			ast_ack_when_req: assert property(@(posedge clk) disable iff(~rstn)
				`INST(num).ack |-> `INST(num).req)	// 通过路径宏分别索引到各个inst,ack为高的同时req必定为高
			else `uvm_error("xxx", "ack when req is 0");
		end
	endgenerate

2、property 和 sequence

如果有两组信号的检查逻辑是类似的,可以使用property来复用,将两组信号作为参数传入。

	property ack_when_req_p(logic ack, logic req);
		@(posedge clk) disable iff(~rstn) ack |-> req;	// 可以复用的检查逻辑
	endproperty
	ast_cmd_ack:  assert property(ack_when_req_p(cmd_ack,  cmd_req));
	ast_data_ack: assert property(ack_when_req_p(data_ack, data_req));

如果有一段时序需要复用,可以使用sequence描述这段时序,然后在不同的property内复用。

	sequence req_ack_success_s;
		req && ack;	// req和ack同时为高
	endsequence
	property no_consecutive_p(logic ack, logic req);
		@(posedge clk) disable iff(~rstn)
		req_ack_success_s |-> ##1 not req_ack_success_s;	// 连续两次req和ack握手成功间隔必须大于1拍
	endproperty

3、if else

如果对于cmd_req/ack信号,写命令是当拍回ack,但是读命令是下一拍,可以分开写成两个,也可以使用if else语句写成一个。

	ast_ack_when_req: assert property(@(posedge clk) disable iff(~rstn)
		cmd_ack |->
		if(cmd_type == WR) cmd_req
		else if(cmd_type == RD) $past(cmd_req))
	else `uvm_error("xxx", "ack when req is 0");

4、变量延迟

断言中只支持##1这种常数delay,但如果delay值是不确定的(如和寄存器配置值有关),可以用以下方法。

ast_ack_after_req: assert property(@(posedge clk) disable iff(~rstn)
	int delay;
	(req, delay = cfg_delay) ##0 (delay>0, delay=delay-1)[*0:$] ##0 (delay == 0) |-> ack)	// req为高后cfg_delay拍,ack必为高
else `uvm_error("xxx", "ast_ack_after_req fail");

总结

以上就是功能覆盖率中写断言时会用到的一些用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值