SystemVerilog中的断言(Assertion)

本文详细介绍了SystemVerilog中的断言(SVA)技术,包括立即断言、并发断言的使用,以及布尔表达式、Sequence和Property的不同层次和特性。此外,还涵盖了断言操作符和系统函数的讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 简介

SystemVerilog断言(SVA)主要是用于验证设计的行为,其主要功能有两点:

  • 在特定条件或事件序列的故障上生成警告或错误;
  • 收集功能覆盖率的数据。

 

 2. 立即断言(Immediate Assertion)

立即断言执行时如同过程语句,她在程序执行到这个程序块使立即执行,并且可以结合$fatal,$error,$warning和$info函数给出不同级别的消息提示。

断言比if语句更加紧凑,且断言里面的逻辑跟if语句是相反的。设计者应该期望括号内的表达式为真,否则输出一个错误。

//使用if语句检查一个信号
bus.cb.request<=1;
repeat(2) @bus.cb;
if(bus.cb.grant!=2'b01)
  $display("Error,grant!=1");

//简单的立即断言
bus.cb.request<=1;
repeat(2) @bus.cb;
al:assert (bus.cb==2'b01);

//定制断言行为
bus.cb.request<=1;
repeat(2) @bus.cb;
al:assert (bus.cb==2'b01)
else $error("Grant not asserted");

 

3. 并发断言

并发断言可以认为时一个连续运行的模块,他为整个仿真过程检查信号的值,需要在断言内指定一个采样时钟。

例中是一个检查仲裁器request信号的断言,request信号除了在复位期间,其他任何时候都不能是X或Z。

//检查X/Z的并发断言
interface arb_if(input bit clk);
  logic[1:0] grant,request;
  logic rst;

  property request_2state;
    @(posedge clk) disable iff(rst);
    $isunknown(request)==0;         //确保没有z或者x值存在
  endproperty
  assert_request_2state:assert property(requset_2state);
endinterface

可以在过程块,module,interface和program内定义并发断言,区别并发断言和立即断言的关键字是property。

 

4. 断言的层次结构

 SVA从单元的角度来说可以分为3个层次,分别是:

  • Boolean expression布尔表达式
  • Sequence序列
  • Property属性

 4.1 Boolean expression布尔表达式

布尔表达式是组成断言的最小单元,常用的操作符:&&,||,!,^等。

//简单的布尔表达式断言
example_assert: assert property(@(posedge clk) a&&b==1);

 

4.2 Sequence序列

在任何设计中,功能总是由多个逻辑事件的组合来表示,这些事件可以是简单的同一个时钟沿被求值得布尔表达式,也可以是经过几个时钟周期的求值事件,SVA用关键字 sequence来表示这些事件,sequence可以让断言易读,复用性高;sequence是布尔表达式更高一层的单元。

sequence具有以下特性:

  • 可带参数;
  • 可以在 property 中调用;
  • 可以使用局部变量;
  • 可以定义时钟周期;
  • 可以使用序列方法,如 ended、matched、triggered,这些只能在sequence中使用;
//简单的Sequence
sequence seq_1;
@(posedge clk) a==1;
endsequence

//调用sequence
a_1: assert property(seq_1);

 带逻辑关系的sequence:

//带逻辑关系的Sequence
sequence seq_1;
@(posedge clk) a||b;  //如果a和b都为0,则断言失败
endsequence

带参数的sequence: 

//带参数的sequence
sequence seq_1 (a, b)
  a || b ;
endsequence

sequence seq_2
  seq_1(a,b);         //在当前sequence调用seq_1
endsequence

带时序关系的sequence:

//带时序关系的sequence
sequence seq;
  @(posedge clk) a ##2 b;  //在时钟上升沿到来检查a是否为1,若不为1则断言失败
                           //若a为1,则检查两个周期之后b是否为1,若不为1,断言失败
endsequence

4.3 Property属性

property是比sequence更高一层的单元,也是构成断言最常用的模块。其中最重要的性质是可以在property中使用蕴含操作符(|-> |=>)。

propert可以调用sequence:

//property调用sequence
sequence seq_1;
  @(posedge clk) a||b;
endsequece

property p;
 seq_1;          //调用seq_1
endproperty

a_1: assert property(p);

property与sequence的相同和不同之处:

  • 任何在sequence中的表达式都可以放到property中;
  • 任何在property中的表达式也可以搬到sequence中,但是只有在property中才能使用蕴含操作符;
  • property中可以例化其他property和sequence,sequence中也可以调用其他的sequence,但是不能例化property;
  • property需要用cover/assert/assume等关键字进行实例化,而sequence直接调用即可;

5. 断言操作符和系统函数

 断言常用的操作符如下:

##n表示延时了n和时钟周期;
##[m:n]表示后续事件在n-m周期内出现都可以判定为真
$表示无穷大的周期(在仿真结束前),不建议使用
[*n]表示事件重复n次
[*m:n]表示一定范围内重复的事件
[=m]表示一个事件的连续性,需要重复m次,但并不需要在连续周期内发生
[=m:n]表示一个事件的连续性,需要重复n-m次,但并不需要在连续周期内发生
|->交叠蕴含,涵的左边叫做”先行算子“(antecedent),右边叫做”后续算子“(consequent)。如果先行算子匹配,在同一个时钟周期计算后续算子表达式。
|=>

非交叠蕴含,如果先行算子匹配,在下一个时钟周期计算后续算子表达式。

常见的系统函数如下:

$rose

$rose(boolean expression or signalname);

信号/表达式的值从0变为1时返回真

$fell

$fell( boolean expression or signalname);

信号/表达式的值从1变为0时返回真

$stable

$stable(boolean expression or signalname) ;

信号/表达式的值不发生变化时返回真

$past

$past(signal_name, number of clock cycles);

访问在过去若干采样周期的值

and断定两个事件同时发生
intersect断定两个事件同时发生或结束
or断定两个事件至少一个发生
first_match从多次满足的序列中选择第一次满足的时刻,从而放弃其他满足时刻
throughout

a throughout b

断定在b事件成立的过程中,a事件“一直”成立

within

a within b

断定b事件发生的时间段里包含a事件发生的时间段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值