1、第十一章第十一章 断言与功断言与功能覆盖能覆盖LOREM IPSUM DOLOR目 录CONCENT11.1 断言11.2 覆盖率介绍11.3 功能覆盖11.4 实例11.1 断言GRADUATION THESIS11.1断言断言的概念:断言的概念:在Verilog HDL语言中,如果需要判断一个语法行为是否满足设计的需求,通常会设计过程性代码程序进行判断,从而实现等效性检查。该程序往往比较冗长,且可读性较差。SystemVerilog语言提供了一种用于间接验证设计通用属性的方法,这就是断言。表示方式:表示方式:断言采用关键字“assert”来表示,相当于条件表达式中的关键字“if”,但更能明
2、确表示功能检查已经完成。简单的断言示例如下:【例11-1】简单的断言示例.assert(result=a+b)$display(the summed data is right!);else$display(something is wrong!);11.1断言11.1.1 立即断言立即断言立即断言是一个程序声明,通常拥有仿真平台的initial语句块中。其功能是检查给定的条件并报告是否发生错误。如果没有错误,就继续执行下一个程序语句,否则仿真停止。【例11-2】立即断言示例 initial begin /初始化 a=5;b=7;cIn=0;#5$display($time,a=%0d,b=%
3、0d,cIn=%0d,sum=%0d,cOut=%0d,a,b,cIn,s,cOut);assert(s=a+b+cIn);/断言 end11.1断言断言语句块出现了两个新的语法:第一个语法是第一个语法是“%m”,该语法分别出现在$display和$error语句中,从仿真结果可以看出,采用该语法是可以清晰地打印出该断言在整个程序中的位置,如本例中的位置路径是adder.adderCheck。当没有显式声明断言语句块名称时,则该路径为adder。因此,为了调试方便,设计者往往会显式声明断言块的名称。另外一个语法就是另外一个语法就是$error任务任务。SystemVerilog针对错误出现的严
4、重程度自带了几种不同的任务,并仅仅只用于断言语句中。具体的系统任务及功能介绍如下表所示。函数具体功能描述$fatal运行期间产生的致命错误,隐含着会调用$finish函数来结束仿真。该任务带有两个参数。第一个参数默认为1,该参数会同时传送给$fatal任务以及$finish函数。第二个参数是要打印的字符串。$error运行期间产生的错误,其参数为要打印的字符串$warning运行期间产生的警告,其参数为要打印的字符串$info运行期间产生的信息说明,问题不严重,其参数为要打印的字符串11.1断言11.1.2 时序操作符时序操作符时序操作符主要有三类:时钟周期延时操作符时钟周期延时操作符、交叠蕴
5、涵操作符交叠蕴涵操作符和非交非交叠蕴涵操作符。叠蕴涵操作符。1.时钟周期延时操作符时钟周期延时操作符SystmVerilog在断言语法中专门开发了一种新的时钟周期延时操作符“#”,用于表示信号之间的时钟周期差。如#1,表示一个时钟延时。2.交叠蕴涵操作符交叠蕴涵操作符在时序信号中,有一类特殊的操作符蕴涵操作符。该操作符又可以分为两类:交叠蕴涵操作符和非交叠蕴涵操作符。交叠蕴涵操作符的符号是“|-”。其基本格式如下:A|-B;表示当A为真时,B在同一个时钟周期内也为真,否则不成功。该操作符在总线设计或者表示多个信号之间的关系时非常有用。11.1断言1.非交叠蕴涵操作符蕴涵操作符的另外一类就是非交
6、叠蕴涵操作符,其操作符的符号是“|=”,基本表现形式如下:A|=B;表示当A为真时,B在后一个时钟周期内也为真,否则不成功。其等效如以下表达式:A#1 B;可以看出,非交叠蕴涵操作符与交叠蕴涵操作符之间相差一个时钟周期的关系,因此上述的表达式,也可以采用交叠蕴涵操作符来等效,如下:A|-#1 B;该类操作符也是经常使用的操作符,如当CPU发出读取内存数据的命令时,内存需要在后一个周期内把数据准备好,并把数据传送到数据总线data上。因此,采用非交叠蕴涵操作符表示如下:read|=isunknown(data);11.1断言11.1.3 序列序列序列,顾名思义,就是表示信号之间的时序关系。序列以
7、关键字“sequence”开始,并以关键字“endsequence”结束。其基本语法结果如下:sequence sequence_name(argument_list);endsequence关键字sequence后紧跟着序列名称。序列名称后可以有序列参数,也可以省略。整个序列的主体是一个逻辑表达式,其内容不能为空,用于定义一个事件,一般用来定义组合逻辑断言。11.1断言11.1.4 属性属性属性定义了需要被检查的设计行为。它可以非常复杂,也可以非常简单。其基本语法结构如下所示。property property_name(argument_list);.endproperty每个属性块采用关
8、键字“property”开始,并以关键字“endproperty”结束。每个属性在property后会紧跟着属性的名字。属性参数是可选的。在属性块内,主要定义属性的行为。属性块是用于将事件组织起来,形成一个更为复杂的过程。如果把序列比喻为砖,则属性就是盖楼。和sequence块不同,属性块一般用于定义一个有时间观念的断言,因此,一些时序操作,如“|-”只能用于属性。需要特别注意的是,在属性中使用的值是在仿真器内核中预先采样的值。11.1断言11.1.5 并行断言并行断言对于并行断言来说,其基本设计流程如下:并行断言的基本格式如下:label:assert property(property_n
9、ame)else fail_statement;和立即断言类似,断言块前可以进行断言名称声明,也可以省略。并行断言采用关键字“assert”开始,并紧接着属性关键字“property”以及属性名,该属性就构成了断言表达式,属性名后可以包含信号列表,也可以省略取决于属性的参数列表。else语句表示如果断言不成功的情形,该语句也是可选的。11.1断言序列常常可以用于描述方式有限状态机的跳转。如序列abc(a,b,c),采用状态跳转图表示如下:整个序列等效于一个八个状态的有限状态机的状态跳转图,每个状态之间相差一个时钟周期。11.1断言1.范围操作符范围操作符在断言中,范围操作符的基本表达式为#n:
10、m,其中n是最小值,m是最大值,表示时钟周期数在n和m之间。n和m可以是任意不小于0的整数,m可以采用“$”符号来表示有界无穷大,也就是意思只要在仿真结束前满足条件就行。如果不满足,断言失败。如在CPU向内存读取命令read后,需要2到5个时钟周期内获取数据有效信息dataValid,从而在dataValid的指引下读取总线上的数据。属性的程序代码如下:property readValid;(posedge clk)read|-#2:5 dataValid;endproperty也可以采用非交叠蕴涵操作符,和交叠蕴涵操作符相比,相差一个时钟周期。其代码如下:property readValid
11、;(posedge clk)read|=#1:4 dataValid;endproperty11.1.6 重复操作符重复操作符11.1断言2.连续重复操作符连续重复操作符 该行为可以采用范围操作符来进行断言设计,如下所示。property serialTransCk;(posedge clk)data_en|-#1:128 data_en#1 done;endproperty2.连续重复操作符连续重复操作符11.1断言现在采用另外一种操作符来进行描述连续重复操作符。该操作符的基本表达式是*n:m,其中n为最小值,m为最大值,表达时钟周期为n到m之间。因此,可以修改如上程序,表示如下:prope
12、rty serialTransCk;(posedge clk)data_en|-data_en*1:128#1 done;endproperty和范围操作符相比,主要有两点不同:一是范围操作符的信号变量位于范围操作符的后面,而连续重复操作符位于信号变量的后面,二是连续重复操作符采用符号“*”来替代符号“#”。上述程序也可以采用非交叠蕴涵操作符来表示,和交叠蕴涵操作符相比,相差一个时钟周期,表示如下:property serialTransCk;(posedge clk)data_en|=data_en*0:127#1 done;endproperty重复操作可能不是一个范围,而是一个有固定时钟
13、周期的长度。此时,可以采用*n来实现,n表示要重复的时钟周期数量。如修改上述的协议,每次传输的数据总量为128个时钟。则修改程序如下:property serialTransCk;(posedge clk)data_en|-data_en*128#1 done;endpropert11.1断言3.严格非连续重复操作符严格非连续重复操作符连续重复操作符针对的目标信号为连续重复的信号,中间没有间隔。如果目标信号为非连续信号,则不能采用连续重复操作符来表示。具体观察如下波形图。SystemVerilog推出了另外一种操作符来表示该操作非连续重复操作符。非连续重复操作符包含严格非连续重复操作符和宽松非
14、连续重复操作符。严格非连续重复操作符的基本结构和连续重复操作符类似,只是把符号“*”修改为符号“-”,其基本结构是“-n:m”。n表示最小值,m表示最大值。n和m为不小于0的整数。因此,上述的波形采用非连续重复操作符的属性程序,表达如下:property non_con_serialTransCk;(posedge clk)data_en|-data_en-1:128#1 done;endproperty11.1断言1.宽松非连续重复操作符观察图11-10,总线传输完成信号done有效会在总线传输完成的下一个时钟周期有效,但是如果该信号不是立即在下一个时钟周期有效,则上述断言可能会失效。如修改
15、图如下:宽松非连续重复操作符和严格非连续重复操作符相似,其基本格式是:=n:m,其中n为最小值,m为最大值。宽松非连续重复操作符不在乎done出现的具体时刻,可能是数据传输结束后的第一个时钟周期,也可能是第二个时钟周期。因此,采用宽松非连续重复操作符来设计的属性代码如下:property loose_non_con_serialTransCk;(posedge clk)data_en|-data_en=1:128#1 done;endproperty11.1断言11.1.7 逻辑操作符逻辑操作符逻辑操作符功能描述or多个序列在同一个时钟下启动,只要其中成功,断言成功。如果任何一个都不成功,则断
16、言失败。and多个序列在同一个时钟下启动,但结束时间可能不同。只有所有的序列都成功,断言才成功,否则不成功。intersect和and操作符相似,但约束更为严格。序列不仅要求同时产生,而且结束时间也要求相同。throughout 左侧表达式在右侧的整个序列过程中保持为真within左侧事件发生的时间段必须在右侧事件发生的时间段内。也就是说,左侧事件发生不能早于右侧事件,但必须早于右侧事件结束。first_match如果在不同时间存在多个匹配,则该逻辑操作符只报告第一个匹配,其余的匹配自动放弃。11.1断言11.1.8 条件操作符条件操作符程序中的(1,a=A,b=B)语句是一个条件计算语句,第
17、一个逗号前的表达式是条件表达式,而第一个逗号后的表达式是赋值表达式,也就是说,1是条件表达式,该条件永远为真,a=A,b=B为赋值表达式,把A和B的值分别赋给a和b。property pipeadderck(A,B);logic 15:0 a,b;(posedge clk)disable iff(reset);(1,a=A,b=B)#3(sum=a+b);endproperty11.1断言11.1.9 断言系统函数断言系统函数系统函数功能描述$sample(expression)采用仿真器采样边沿前稳定值作为表达式的值$rose(expression,ce)如果表达式的最低有效位在采样时钟的作
18、用下,两个相邻时钟周期内采样值由0变为1,则该表达式为真,其他情形为假。$fell(expression,ce)如果表达式的最低有效位在采样时钟的作用下,两个相邻时钟周期内采样值由1变为0,则该表达式为真,其他情形为假。$stable(expression,ce)如果表达式的最低有效位在采样时钟的作用下,两个相邻时钟周期内采样值保持不变,则该表达式为真,其他情形为假。$change(expression,ce)如果表达式的最低有效位在采样时钟的作用下,两个相邻时钟周期内采样值不同,则该表达式为真,其他情形为假。$past(expression,numTicks,ce)表达式采用过去numTic
19、ks个时刻的采样数值作为表达式的值,而不采用当前时钟时刻的采样值。$onehot(Bus)Bus总线中有且仅有1个比特为1,其他是0$onehot0(Bus)Bus总线有不超过1个比特为1,也允许全0$isunknown(Bus)Bus总线存在高阻态或未定态countones(Bus)=nBus总线有且仅有n个比特是高电平,其他为低11.1断言断言系统函数的具体行为:11.2 覆盖率介绍GRADUATION THESIS11.2 覆盖率介绍100%的覆盖率是每一个验证工程师的追求。每个验证工程师都是根据验证计划,设计随机测试程序,并根据验证计划,改变随机种子,并反复运行同一个随机测试平台产生随
20、机激励。这样,每次仿真都会产生一个覆盖率,把这些覆盖率信息合并在一起就可以得到功能覆盖率,从而实现衡量整体验证的进展程度。11.2 覆盖率介绍11.2.1 代码覆盖率代码覆盖率主要概念:主要概念:代码覆盖率:代码覆盖率:是衡量整个设计的源代码被执行过的情况,包括行覆盖率、路径覆盖率、翻转覆盖率以及有限状态机覆盖率。行覆盖率:行覆盖率:是指有多少行代码被执行过;路径覆盖率:路径覆盖率:是指代码和表达式的路径有多少被执行过;翻转覆盖率:翻转覆盖率:是指变量的比特位的跳变覆盖而有限状态机覆盖率则主要针对有限状态机而已,包括有限状态机的状态访问以及状态转换的执行等。如初学者在设计D触发器时经常会忘记对
21、数据进行异步复位,其代码如下:always_ff(posedge clk,negege rst_l)q S3 S3=S2S3=S1 S2=S1S2=S2S2=S3S1=S0S1=S2状态跳转关系表状态跳转示意图11.3 功能覆盖SystemVerilog对于此类状态跳转的建仓采用状态跳转描述,而不再是具体的数据描述。如要对从状态S0到S3的序列覆盖,则可以建仓如下:bins S0XS3=(S0=S3);如在图中,存在一条状态跳转路径S0=S3=S2=S1=S0,可以声明如下:bins LongX=(S0=S3=S2=S1=S0);有时候需要在某个状态停留多个时钟周期,如I2C总线在地址接收阶段
22、需要重复八个时钟周期,因此在定义状态跳转时,也需要考虑此重复的状态。如假设图11-15,存在一条路径S0=S3=S2=S2=S1,也就是在S2时,需要停留两个时钟周期,则可以声明如下:bins LongX=(S0=S3=S2=S2=S1);也可以采用重复操作符“*”来描述,如针对上述代码,可以修改如下:bins LongX=(S0=S3=S2*2=S1);11.3 功能覆盖11.3.5 覆盖选项覆盖选项覆盖选项功能说明auto_bin_max用于限制自动创建仓的数量,缺省值为64,如果覆盖点变量或表达式的值超过了指定的最大值,SystmVerilog会把值平均分配给auto_bin_max个仓
23、weight总体覆盖率基于所有简单覆盖点和交叉覆盖率进行统计,在进行覆盖率统计时,需要去掉重复的覆盖,如单体覆盖与交叉覆盖并行时,可能需要对单体覆盖的权重设置为0,从而不影响整体覆盖率。Weight表示为权重值,为非负的整数,默认为1per_instance如果测试平台内对同一个覆盖组进行多次例化,则默认情况下,SystemVerilog会把所有实例的覆盖率数据汇总在一起。采用per_instance可以实现查看单个单独的报告comment覆盖组的注释,用于代码内使得报告更容易进行分析at_least用于设置整个覆盖组内的覆盖点或者单个覆盖点最少被访问的次数cross_num_print_mi
24、ssing用于使仿真和报告工具给出所有的仓,尤其是没有被命中的仓的信息goal设置覆盖组或者覆盖点的目标,缺省情况下为100。11.3 功能覆盖11.3.6 采样函数采样函数【例11-12】采用采样函数实现功能覆盖covergroup Cover_adder with function sample(logic 15:0 sum);property checksum;bit 15:0 sum_buff;(posedge clk)(ld_n,sum_buff=0|-ld_n*3#1(done&(sum=(sum_buff=ina+inb),sup.sample(sum);endproperty
25、ckSumValue:assert property(checksum)else$error(“the value is not correct”);SystemVerilog提供了采样函数并结合断言来实现功能覆盖的同时,实现采样的正确性。换句话说,就是确保结果正确的前提下,再进行功能覆盖。11.3 功能覆盖11.3.7 覆盖率数据分析覆盖率数据分析SystemVerilog提供了多个覆盖率数据查询函数,使得测试者可以检查是否已经达到设计目标,及时对随机测试加以控制。在全局层面在全局层面,可以采用系统任务$get_coverage获得全体覆盖组的总覆盖率。该任务可以返回一个0到100之间的实数
26、,代表总覆盖率为n%。也可以采用系统函数系统函数get_coverage()来实现获得具体覆盖组的覆盖率具体覆盖组的覆盖率,该函数可以带覆盖组名和实例名,用于给出一个覆盖组所有实例的覆盖率。其基本用法是:覆盖组名:get_coverage()或者实例名.get_coverage()。如果只需要对某个特定覆盖组实例的覆盖率进行统计特定覆盖组实例的覆盖率进行统计,则可以使用系统函数函数get_inst_coverage()来实现,其基本语法是:实例名:get_inst_coverage()。如果希望覆盖点平均分布如果希望覆盖点平均分布,则可以采用“solvebefore”约束来实现。11.4实例:
27、对有限状态机进行功能覆盖设计GRADUATION THESIS11.4 实例采用采用SystemVerilog对图对图11-15有限状态机进行代码设计,并对有限状态机进行代码设计,并对其进行仿真和功能覆盖检查。其进行仿真和功能覆盖检查。图 1115 状态跳转示意图本章小结本章主要讲述了本章主要讲述了SystemVerilog进行验证时最重要的进行验证时最重要的两大特性:断言与功能覆盖。着重讲述了断言的类型、两大特性:断言与功能覆盖。着重讲述了断言的类型、断言的组成以及用于断言的各种特殊操作符和系统函断言的组成以及用于断言的各种特殊操作符和系统函数。重点强调了功能覆盖的重要性,并从覆盖率的分数。重点强调了功能覆盖的重要性,并从覆盖率的分类开始,从细节描述了功能覆盖的各种要素,包括覆类开始,从细节描述了功能覆盖的各种要素,包括覆盖点、覆盖组、仓、覆盖选项以及覆盖率数据分析等盖点、覆盖组、仓、覆盖选项以及覆盖率数据分析等方面一一阐述。最后,通过一个实例来讲述以上各种方面一一阐述。最后,通过一个实例来讲述以上各种语法在具体的验证代码中的应用。语法在具体的验证代码中的应用。谢谢THANK YOU