Asssertion断言入门(三)——property的使用及断言的绑定

时钟声明

对于并行断言,其必须要具备时钟,property中可能具有单个时钟,也有可能是包括多个时钟。

单时钟

1.在sequence中独立指定时钟

sequence s2;
    @(posedge clk) a ##2 b;
endsequence
property p2;
    not s2;
endproperty
assert property(p2);

2.在property中独立指定时钟

property p2;
    @(posedge clk) not (a ##2 b);
endproperty
assert property(p3);

3.在过程快中,可以继承过程块的时钟

always@(posedge clk) assert property (not(a ##2 b))

4.在时钟快中,也可以继承时钟块的时钟

clocking master_clk @(posedge clk)
    property p3;
        not(a ##2 b);
    endproperty
endclocking
assert property(master_clk.p3);

断言时钟按照优先级逐级判定:

  • 显示声明断言时钟
  • 继承断言所嵌入环境的时钟
  • 继承默认的时钟

多时钟

一般对sequence或者property,默认情况下,在使用同一个时钟用来对数据做采样,但是不排除有多个时钟的采样。如果一个sequence或者property需要声明多个时钟用来做数据采样,可以使用##1结合第二个时钟沿采样。

sequence中,只能使用##1来表示与第一个时钟(CLK1)沿紧密相连的下一个时钟,而sequence操作符例如and、or、intersect等无法被使用在多时钟sequence。

//以下声明均非法
sequence clk_illegal;
@(posedge clk1) s1 ##0 @(posedge clk2) s2
@(posedge clk1) s1 ##2 @(posedge clk2) s2
@(posedge clk1) s1 intersect @(posedge clk2) s2
endsequence

在property中,可以使用and、or、intersect可以在多时钟property中使用,因为它们代表逻辑运算,并不参与sequence之间的时序。

property clk_legal;
    @(posedge clk1) b and @(posedge clk2) c;   
endproperty
assert property (@(posedge clk0) a |=> clk_legal) else $error();

注意:

  • 对于多时钟的断言,必须显示声明时钟,无法继承或者使用默认时钟;

  • 多时钟断言也无法嵌套入由时钟驱动的过程语句块和时钟块中

    //以下声明非法,
    always @(clk) assert property (mult_clock_prop);//mult_clock_prop表示为多时钟的property
    initial @(clk) assert property (mult_clock_prop);
    

绑定

断言既可以嵌入到设计中,也可以在设计外部定义。但是嵌入到设计内部,就需要考虑是否可以综合的问题,需要考虑添加编译定向。而在设计外部定义,不需要担心可综合的问题。那么如何在设计在外部定义呢?

  • 采用bind方法可以满足在设计外部定义断言,将断言绑定到设计内部或者接口上面;
  • bind 可以将包含断言的模块与设计模块或者实例进行绑定,既可以满足对设计信号的可视性,又能满足断言模块的独立性;
  • 使用方法:bind design_block_or_instance_name block_with_assertion
  • 使用绑定的优势:无需修改原有设计代码,也不需要添加监测信号,就可以实现断言的添加
interface range(input clk,enable,input int minval,expr);
    property crange_en;
        @(posedge clk) enable |-> (minval <= expr);
    endproperty
    range_chk: assert property(crange_en);
endinterface
        
bind cr_unit range r1(c_clk,c_en,v_low,(in1&&in2));

注意:(以上面代码做例子)

  • r1相当于range这个interface 的实例,将DUT的端口或者内部信号与它相连;

  • 但是这个接口与验证环境TB中的interface有所不同之处:

    1. TB中的interface想看DUT内部层次以下的信号,可以访问DUT内部层次的方式,访问内部信号,例如tb.dut.a.b.sig1。但是绑定时的接口是看不到DUT的层次,只能看到DUT的端口和这一层的内部信号,看不到层次以下的信号
    2. TB中的interface在例化后,其实体是存在于TB下的;而绑定时的接口例化后的实体是放在DUT内部

expect语句

assert、assume和cover都是非阻塞的方式,即他们本身并不去去阻塞后续的语句。而expect则是property中的一种阻塞使用方式。

  • expect的使用和assert一致,不过它会等待property执行通过,才会执行后续的语句。
//仿真在200ms开始,在连续的3拍内,要依次看到a,b,c,拉高,
//那么expect语句才会通过,否则报错
initial begin
   #200ms;
    expect( @(posedge clk) a ##1 b ##1 c ) else $error("expect failed");
end
  • expect同assert语句的调用方式类似,可以在function和task中使用,同时也可以引用静态变量或者动态变量
integer data;
...
task automatic wait_for(integer value,output bit success);
    expect(@(posedge clk) ##[1:10] data==value)  success = 1;
    else success = 0;
endtask
initial begin 
   bit ok;
    wiat_for(23,ok);
end
  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小verifier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值