电力电子转战数字IC20220822day66——断言和序列

目录

assertion断言

什么是assertion?

assertion的作用是什么?

assertion based verification ABV方法学定义assertion如何被使用,包括:

assertion的分类有哪些?

assertion如何编码实现?

property和sequence的关系

这里的seq和之前的seq的区别?

sequence可以提供形式参数,提高复用性

有两个操作符,第一个implication蕴含

sequence序列

##周期延迟符号

##[min:max]范围内clk延迟

$无穷大的周期

[*]重复操作事件

[=m]表示一个时间的连续性

and表示两个seq需要保持匹配

intersect要求匹配时刻在同一个clk

or表示两个seq至少需要一个满足

first_match表示从多次满足的序列中选择第一次满足的时刻,放弃其他时刻

throughout检查一个信号或表达式在贯穿一个seq时是否满足要求

within检查一个seq与另一个seq在部分clk长度上的重叠

.ended检查序列的重点

局部变量

调用方法


assertion断言

什么是assertion?

用来与设计功能和时序做比较的属性描述。???

越短越好!

assertion的作用是什么?

  • 检查设计的内容
  • 提高设计的可视度和调适能力
  • 检查设计特性在验证中是否被覆盖

assertion based verification ABV方法学定义assertion如何被使用,包括:

  • 谁写?
  • 哪种语言可以写?
  • 写在哪里?
  • 可以使用哪些断言库Library?
  • 如何调试?
  • 如何使用形式验证工具?
  • 如何使用断言覆盖率?

assertion的分类有哪些?

  • 立即断言immediate assertion
    • 非时序
    • 执行时如同过程语句
    • 可以在initial块、always块、task和function中使用
  • 并行断言concurrent assertion
    • 时序性的
    • 关键词property用来区分这两种断言
    • 与设计模块一同并行执行,所以称为并行断言

assertion如何编码实现?

[name:] assert(expression)[pass_statement][else fail_statement]

time t;

always @(posedge clk)
	if (state==REQ)
		assert (req1||req2)
	else begin
		t=$time;
		#5 $error("assert failed at time %0t", t);
	end

//结合$fatal $error $warning $info
assert (myfunc(a,b)) count1=count+1; else -> event1;
assert (y==0) else flag=1;
always @(state) assert (steate==$onehot) else $fatal;
base_rule1: assert property (cont_prop(rst, in1, in2)) pass_stat else fail_stat;
//req拉高,2个clk后grant拉高,1个clk后req拉低,1个clk后grant拉低
property req_grant_prop
	@(posedge clk) req ## 2 gnt ##1 !req ## !gnt;
endproperty

并行断言只会在clk边沿激活,变量的值是采样到的值

  • 可以直接包含一个property,也可以独立声明。
assert property (@(posedge clk)) disable iff(!reset) a | => b ##1 c);

assert property(my_prop);
property my_prop;
	@(posedge clk)) 
		disable iff(!reset) a | => b ##1 c;
endproperty

property和sequence的关系

property块可以直接包含sequence

复杂的property可以独立声明多个sequence

sequence是property的基本构建模块,经过组合来描述复杂的功能属性

这里的seq和之前的seq的区别?

描述时序,不是做激励

sequence s1;
@(posedge clk) a ##1 b ##1 c;
endsequence

sequence s2;
@(posedge clk) a ##1 c;
endsequence

property p1;
@(posedge clk) disable iff(!reset)
s1 |=>s2;//如果出现s1序列则马上跟着出现s2序列
endproperty

sequence可以在module interface program clocking package中声明

sequence t2;
(a ## [2:3] b) or (c ##[1:2] d);
endsequence

sequence可以提供形式参数,提高复用性

sequence s20_1 (data, en);//参数为data和en
(!frame && (data==data_bus)) ##1 (c_be[0:3] == en);
endsequence

有两个操作符,第一个implication蕴含

表示:如果property中左边的先行算子成立,那么右边的后续算子才会被计算

如果先行算子antecedent不成功,整个属性就默认被认为成功,这是空成功vacuous success

只能在property中定义,不能在seq中定义

分类

  • 交叠蕴含overlapped implication

    • 符号是|→
    • 如果条件满足,则评估后续算子序列;如果不满足,表现为空成功,不执行后续算子
    property p_req_ack;
    @(posedge clk) mem_en |-> (req ##2 ack);
    endproperty
    
  • 非交叠蕴含noi

    • 符号是|=→
    • 如果条件满足,则在下一周期评估后续算子序列;如果不满足则同上

sequence序列

##周期延迟符号

##n表示在n个clk后

##0表示在当前周期,即交叠周期,相当于逻辑与&&

sequence a_b
@(posedge clk) a ##1 b;
endsequence

##[min:max]范围内clk延迟

min和max必须是非负数,seq会在从min到max时间窗口中最早的时间来匹配?

在1个clk就出现b,则后面的clk就不会看了,最早的意思就是这样

sequence a_b
@(posedge clk) a ##[1:5] b;
endsequence

$无穷大的周期

将max换成$,增大仿真评估序列的负担,不推荐

[*]重复操作事件

n非负数,不能为$

表示b必须在两个连续的clk为真

sequence a_b
@(posedge clk) a ##1 b[*2];
endsequence

如果是[*2:5],表示b必须在2-5个连续clk为真(相当于逻辑或)

a[*0]表示没有在任何正数clk内有效:如果a不满足,则忽略了,继续找b和c等其他事件

a[*0:3] ##1 b表示:b、a ##1 b、a ##1 a ##1 b、a ##1 a ##1 a ##1 b

[=m]表示一个时间的连续性

需要重复发生m次,但不用在连续的clk发生

例如在实战1中的burst read测试,期望读的data和ack信号在接下来的4个clk内返回,但是不需要连续4个clk

[=m:n]表示从最小m到最大n的非连续clk

and表示两个seq需要保持匹配

SEQ1 and SEQ2

  • 两个seq的满足时间可以不同,SEQ1先满足,等待SEQ2满足时,and满足

and左右可以是信号

intersect要求匹配时刻在同一个clk

和and类似,区别在于两个seq时序要在同一个clk内匹配

or表示两个seq至少需要一个满足

SEQ1 or SEQ2,逻辑或||

  • 两个seq在同一时刻触发,最终满足至少其中一个
  • 每个seq的结束时间可以不同,结束时间以晚结束的seq为准

 对于and和or的应用:如果burst write的长度为4,则写的长度可以为1、2或4

property burstlengthvalid
@(posedge clk) disable iff(!rst)
((burstlen==4) |-> (wrlen--1) or (wrlen==2) or (wrlen==4))
endproperty

assert property (bustlengthvalid)

first_match表示从多次满足的序列中选择第一次满足的时刻,放弃其他时刻

sequence t1;
te1 ## [2:5] te2;//2-5次te2,共4种情况
endsequence

sequence ts1;
first_match (te1 ## [2:5] te2);//上述4种情况中的第一次匹配的时刻
endsequence

sequence t2;
(a ## [2:3] b) or (c ## [1:2] b);
endsequence 

sequence ts2;
first_match(t2);
endsequence

每一次PCI总线进入idle时状态机也应该返回idle,所以时序要求frame和irdy信号保持至少两个clk以上为高时系统状态为idle

sequence checkbusidle
(## [2:$] (frame && irdy));//宁可写成100也不要$
endsequence

property first_match_idle
@(posedge clk) first_match (checkbusidle) |-> (state==busidle);
endproperty

throughout检查一个信号或表达式在贯穿一个seq时是否满足要求

Sig1/Exp1 throughout Seq,左边和右边不一样

在burst模式信号拉低后2个clk时,irdy/trdy要连续7个clk保持为低,同时burst模式信号在这连续的clk中也为低。(也就是burst模式信号至少比右边seq的时间还要长)

sequence burst_rule1;
@(posedge mclk)
	$fell (burst_mode) ##0//看做一个seq:burst_mode在这一拍拉低了
	(!burst_mode) throughout (##2 ((trdy==0) && (irdy==0)) [*7]);
endsequence

  

within检查一个seq与另一个seq在部分clk长度上的重叠

SEQ1 within SEQ2,当seq1满足在seq2的一部分连续clk内成立,则表达式成立

trdy需要再irday下拉的1个clk后保持7个clk为低,同时irday也将保持8个clk为低:

!trdy[*7] within (($fell irdy) ##1 !irdy [*8])

.ended检查序列的重点

SEQ.ended

在某一时刻序列抵达终点,则条件满足

sequence e1;
@(posedge sysclk) $rose(ready) ##1 proc1 ##1 proc2;
endsequence
//在inst为高的下一个clk,e1应该结束或者已经结束
sequence rule;
@(posedge sysclk) reset ##1 inst ##1 e1.ended ##1 branch_back;
endsequence

 

 

sequence arbseq (aFell, bRose);
@(posedge clk) $fell(aFell) ##1
$rose(bRose);
endsequence

property endcycle;
@(posedge clk) $rose(c) |=> arbseq(a,b).ended;
endproperty
//这个property是不满足的,因为是在c拉高的时刻才开始这个property,a至少要在下个clk拉低
$rose(c) && $fell(a) |=> $rose(b)

局部变量

可以在sequence或者property中使用,会伴随他们动态创建

每一个sequence实例都会有它自己的变量拷贝

sequence rs_cache_done
##[1:5] rdDone;
endsequence
//在cache rdDone拉高后读出的rdData会在2个clk后,在其基础上加1,并作为wrData写入
sequence check_reg_wr_data;
int local_data;//局部变量
(rs_cache_done, local_data==cache_rd_data) ##2 (reg_wr_data == (local_data+1));
endsequence
property checkreadidack;
int loc_id;
//read拉高,伴随readid,下一次read必须在这一次read对应的readack返回之后才可以发起,用局部变量来存储
($rose(read), loc_id=readid) |=>//满足序列后执行逗号后的表达式
not ($rose(read) && readid==loc_id) ##0 ($rose(readack) && readackid==loc_id);
endproperty
//先满足($rose(readack) && readackid==loc_id)
//not ($rose(read) && readid==loc_id)没有相同readid的read发起
//##0 表示逻辑与

调用方法

序列匹配时可以调用task,void function、系统函数

sequence s1;
logic v,w;
(a, v=e) ##1 (b[->1], w=f, $display("b after a with v = %h, w = %h \\n", v,w));

系统函数用来访问指定类型的变量采样:访问当前和上一个周期采样值,检测采样变量的变化

$rose(expression[, clocking_event])
$fell(expression[, clocking_event])
//与上一个采样周期相比,变量最低位是否跳变为1或0,满足则返回1,否则返回0
//clocking_event在sequence中不需要单独提供,一般会指定采样clk
$stable(expression[, clocking_event])
//表示在连续两个clk内表达式的值保持不变,满足则返回1,否则返回0
$past(expr[, num_cycles][, gating_expr][, clocking_event])
//访问在过去若干个采样周期前的数值,默认num_cycle为1,采样1个clk前的数值
property reqcauseack;
@(posedge clk) $rose(ack) |-> $past(req, 2);
endproperty
//在ack拉高时的前两个clkreq应该为高
property cache_read_chk;
@(posedge clk) (state==CACHE_READ) |-> ($past(state) != CACHE_MISS);
endproperty
//如果当前是CACHE_READ,则上一个状态不应该是miss

$rose fell stable可以在过程块语句和连续赋值中使用

always @(posedge clk)
testdone<=stimulus_over & $rose(unit_done);

always @(posedge clk) begin
if($stable(my_sig)) begin $display(); end
end

assign intr_cleared=$fell(intr, @(posedge clk));//class里面能不能指定clk
assign intr_set=$rose(intr, @posedge clk);

系统函数也可以在seq,pro,assertion中使用

$countbits(expression, control_bit)计算expression中匹配control_bit数值的位数

$countones相当于$countbits(expression, ‘1)

$onehot(expression)相当于$countbits(expression, ‘1)==1

$isunknown(expression)相当于$countbits(expression, ‘x, ‘z)!=0

$assertoff(level, [list of module, instance or assertion_identifier]);

$assertkill(level, [list of module, instance or assertion_identifier]);

$asserton(level, [list of module, instance or assertion_identifier]);

level=0表示当前模块或者层次下所有assertion,level=n表示当前模块或层次下n层范围中的assertion

identifier表示property的名字或者assertion的label

module assert_control();
initial begin
	@(negedge top_tb.reset_n) $display();
	$assertoff(0, top_tb.cpu_inst1);
	@(posedge top_tb.reset_n) $display();
	$asserton(0, top_tb.cpu_inst1);
end
endmodule
//在reset阶段停止所有assertion,复位之后开启
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值