保姆级教程超硬核包会,SystemVerilog SV 断言

前言:仿真的时候,需要观察某些程序运行的结果是否符合预期,这一需求一般是通过断言来实现。

断言

  • 对于程序的检查。
  • 断言是设计的属性的描述
  • 如果被检查的属性与期望不同断言失败
  • 如果被禁止在设计中出现的属性在仿真中出现,也断言失败。
  • 断言可以在功能仿真中不断被监视。
  • 相同的断言可以在仿真中也可以在形式验证中复用。

断言的评估和执行包括一下三个阶段:

  • 预备(Preponed)在这个阶段,采样断言变量,而且信号或变量的状态不能改变。这样确保在时隙开始的时候采样到最稳定的值。
  • 观察(Observed)在这个阶段,对所有的属性表达式求值。
  • 相应(Reactive)在这个阶段,调度评估属性成功或失败的代码。

1. 为什么使用SVA语言?

  • SVA是一种描述性语言,可以详细的描述相关的状况, 非常精确且易于维护。
  • 有内嵌函数来测定特定情况,并且可以收集断言覆盖率。

1.1 即时断言

  • 基于仿真事件的语义,与在过程块中其他表达式一样。
  • 即时断言本质与时序无关,立即求值。必须放在过程块的定义中,应用在动态仿真里。
always_comb
begin
	a_aia : assert (a&&b);//assert 断言
end

1.2. 并发断言

  • 基于时钟周期,根据调用的变量采样值计算测试表达式。
  • 一般放在模块接口里。
a_cc : assert property(@(posedge cik) not(a&&b)); //

有property的是并发断言,后边跟的时钟。

2. 建立SVA块

  • 功能由多个逻辑事件组成。这些事件可以是简单的同一个时钟边缘求值的表达式。

2.1 序列

  • SVA用序列sequence来表示这些事件,描述这些发生变化的事件
sequence name_of_sequence;
	< test expression>;
endsequence

-多个序列可以逻辑组合生成更复杂的序列,使用属性property来表示 。例如序列1发生导致序列2发生。

property name_of_property;
	<test expression>; or
	<comples sequence expressions>;
endproperty

2.1.1 序列内建方法

//rose 从0变为1 
	$rose(expression or signal)
//fell 从1变为0
	$fell(expression or signal)
//stable值没发生变化
	$stable(expression or signal)

sequence s2;
	@(posedge clk) $rose(a);//从0变为1
endsequence

2.1.2 序列中的形式参数

  • 定义形式参数,不需要指明对象,使得序列可以复用。
sequence s3_lib (a,b);
	a||b;
endsequence

sequence s3_lib_inst1;
	s3_lib(req1,req2);
endsequence //这两个序列完成了嵌套

2.1.3 序列中的时序关系

## 表示时钟周期延迟。

sequence s4;
	@(posedge clk ) a##2 b; //默认a为高 过两拍后 b是否为高
endsequence

2.2. 属性property

  • property对设计的行为做的描述
  • assert、caver、assume 的对象是property。
  • assert检查在任何时刻对应的属性描述是否成立。
  • cover在认识时候对应的属性是否发生过
  • aassume描述边界激励的属性

在工作中的流程一般为:

  • 建立SVA检查其的步骤:建立布尔表达式; 建立序列表达式;时序上的表达式;建立属性。

2.3 SVA中的时钟定义

  • 在序列、属性和断言语句中都可以定义时钟。
  • 一般在属性中指定时钟,并保持序列独立于时钟,可以提高序列的重用性。

2.4. 禁止属性

  • 属性检查默认都是正确的条件,属性也可以被禁止发生。禁止属性表示期望属性为假,当属性发生时,断言失败。

断言执行块
SV语言被定义在断言检查失败时,仿真器会打印信息,对于成功的断言,仿真器不会打印信息

2.5. 蕴含操作符

蕴含(implication)等效于if then。

  • 蕴含的左边为先行算子(antecedent),右边叫做后续算子(consequent)。
  • 先行算子是约束条件,成功会计算后续算子。
  • 先行算子不成功,整个属性默认为空成功。
  • 蕴含结构只能用在属性的定义中。
  • 蕴含可以分为交叠和非交叠蕴含。

交叠蕴含使用->表示

  • 如果先行算子匹配,则在同一拍计算后续算子成立不成立。

非交叠蕴含使用=>表示

  • 如果先行算子匹配,则在下一拍计算后续算子成立不成立。

2.6 描述延迟的方法

2.6.1 重叠时序窗口

property p12;
	@(posedge clk) (a&&b) |-> ##[1:3] c;
endproperty

a12: assert property(p12);

a和b同时为高后的 1-3个周期内,c至少有一个周期为高。

2.6.2 无限时序窗口

  • $表示时序没有上限,检测器不断地检查表达式是否成功,直到仿真结束。
  • ended使序列可以简单的连接

3. SVA中的一些命令

$past构造

  • 当满足条件时,检查之前的状态是不是在预期。
$past(signal_name, number of clock cycles)

连续重复运算符[ * n]

  • 表面信号或序列将在指定数量的周期内连续的匹配,每次匹配之间都有一个时钟周期的隐藏延迟。
signal or sequence [*n] 
  • 连续重复的次数也可以是一个窗口。
a[ *1:5 ]表示a从某个时钟周期开始重复1-5

[->]跟随重复运算符

  • a[->3]信号a连续或间断的出现3次为高。

非连续重复运算符[=m]

  • 表示一个事件的连续性,需要重复发生m次,但不需要在连续的周期内完成
  • b[=3]表示b必须在3个周期内为1,但并不需要是三个连续的周期

二者区别:

  • 跟随重复表示判断结束跟着执行后面的表达式。
  • 非联系重复表示判断结束后会间隔1拍或者几排再执行后边的表达式。

and

  • and可以用来逻辑地组合两个序列,当两个序列都成功时,属性才算成功。

  • 两个序列必须具有相同的起始点,但是可以有不同的结束点。

  • 检验的起始点是第一个序列的成功时的起始点,结束点是使得属性最终成功的另一个序列成功时的结束点。

sequence s27 a;
 @(posedge clk) a##[1:2] b; //a为高过了1到2拍b为高
endsequence
sequence s27 b;
 @(posedge clk) c##[2:3] d;
endsequence
property p27;
	@(posedge clk)  s27a and s27b;
endproperty 

intersecct

  • 与and类似,但要求两个序列的长度必须相等。即同时开始同时结束。

or

  • 只要一个序列成功就算成功。

first_match

  • 使用and/or可能出现一个检验具有多个匹配的情况。
  • first_match构造可以确保只用第一次序列匹配,而丢弃其他匹配。

throughout

  • ()throughout(时间条件) //要求某个条件必须一直为高时。

within

  • 允许在一个序列中定义另一个序列。
seq1 within seq2

表示seq1在seq2的开始到结束范围内发生
其他

  • $onehot(expr) 检验表达式是否只有一位为1。
  • $onehot0(expr) 检验表达式只有1位或没有任何位为0。
  • $isunknown(expr)检验表达式任何位是否有x,z。
  • $countones(expr)计算向量中为1的位数。

disable iff

  • 可以用来禁止在一些条件下的属性检验。
  • 在复位时一般不需要检验:disable iff (reset)。

expect

  • expect与Verilog中的等类语句类似,用来等待属性的成功检验。 e
  • xpect构造后的代码作为一个阻塞语句来执行。 expect构造语法与assert相似。

4. SVA中的局部变量

  • 在序列或者属性内部可以定义局部变量,并可以赋值。 变量接着子程序放置,用逗号隔开。
  • SVA中调用子程序,在序列每次成功匹配时调用子程序。

5. 将SVA与设计连接

有两种方法可以将SVA检验器连接到设计中。
(1)在模块定义中内建或者内联检验器。
(2)将检验器与模块、模块的实例或者一个模块的多个实例绑定。
注意,定义检验器模块时,他是一个独立的实体。检验器用来检验一组通用的信号,检验器可以与设计中任何的模块或者实例绑定,绑定的语法如下所示。

bind<module_name or instance name>
	<checker name> <checker instance name>
		<design signals>;

6. SVA与功能覆盖率

  • 断言可以用来获得有关协议覆盖的穷举信息。SVA提供了关键词cover来实现这一功能,cover语句的基本语法如下所示。
<cover_name>: cover property (property name)\

cover_name是用户提供的名称,用来标明覆盖语句,property_name是用户想获得覆盖信息的属性名。
cover语句的结果包含下面的信息:
(1)属性被尝试检验的次数。
(2)属性成功的次数。
(3)属性失败的次数。
(4)属性空成功的次数。
检验器mutex_chx在一次模拟中的覆盖日志的实例如下所示:

c_mutex,12 attempts,12 match,0 vacuous match

就像断言(assert)语句一样,覆盖(cover)语句可以有执行块。在一个覆盖成功匹配时,可以调用一个函数(function)或者任务(task),或者更新一个局部变量。

你可能感兴趣的:(System,Verilog,fpga开发)