• systemverilog学习 ---- assertion结束


    加下来我们讨论assertion的操作符,方便对时序进行建模。

    Repetition Operators

    property p;
    	@(posedge clk) a |-> ##1 b ##1 b ##1 b;
    endproperty
    a:assert property(p);
    
    • 1
    • 2
    • 3
    • 4

    再上面这个例子中,如果信号a在一个给定的时钟上升沿为高电平,那么信号b应该在接下来的连续的三个时钟周期为高电平。但是如果表达式出现多个周期,一个一个的通过##写会很繁琐。因此systemverilog提供了重复操作符。

    signal [*n] or sequence [*n]
    "n" is the number of repetitions.
    
    • 1
    • 2

    因此基于重复操作符,上面的例子可以改写为:

    property p;
    	@(posedge clk) a |-> ##1 b[*3];
    endproperty
    
    • 1
    • 2
    • 3

    当然也可以不连续,可以使用go-to-repetition(->n)操作符,这意味着信号不用再连续的时钟周期内出现特定的值。

    property p;
    	@(posedge clk) a |-> ##1 b[->3] ##1 c;
    endproperty
    
    • 1
    • 2
    • 3

    上面例子表明,如果信号a在一个给定的时钟上升沿为高电平。紧接着信号b应该在有三个时钟周期内为高电平,最后紧接着的时钟周期内信号c为高电平。
    在如下面的例子所示:

    $rose(rdy) ##1 rd_en[->4] ##1 intr_en;
    
    • 1

    在这里插入图片描述
    上图中,绿色表示rdy上升沿,紫色表示rd_en=1,蓝色表示intr_en,语句表示rdy上升沿后要有4个周期的rd_en,满足4个周期后紧跟一个周期intr_en=1。

    若可以不连续,便可以贯彻到底使用,如下例子所示,表示不用紧跟出现rd_en=1。
    在这里插入图片描述

    SVA method

    时序定义,除了电平值,还会涉及边沿等情况,接下来讨论SVA的方法。

    $rose (boolean expression or signal name)
    
    • 1

    $rose(布尔表达式或者信号名)。如果这个表达式最低有效位或者信号变为高电平时,会返回true,否则会返回false。

    rose

    sequence seq_rose;
    	@(posedge clk) $rose(a);
    endsequence
    
    • 1
    • 2
    • 3

    在上面例子中,序列seq_rose会在每一个时钟的上升沿检查,信号a是否从0变成1,若这个转变没有出现,则认为这次断言失败。

    fell

    声明如下:

    $fell(boolean expression or signal name);
    
    • 1

    当最低的有效位变为0时返回true,否则返回false。

    sequence seq_fall;
    	@(posedge clk) $fell(a);
    endseqence
    
    • 1
    • 2
    • 3

    序列seq_fell在每一个时钟的上升沿检查信号a是否从1变到0,如果这个转变没有出现,那么则认为此次断言失败。

    stable

    $stable (boolean expression or signal name)
    
    • 1

    表示稳定没有变化,则若这个周期和上个周期的值是一样的,即没有变化,就返回true。

    sequence seq_stable;
    	@(posedge clk) $stable(a);
    endsequence
    
    • 1
    • 2
    • 3

    序列seq_stable会在每一个时钟的上升沿检测信号a是否是稳定的,如果由任何的转变出现,那么断言失败。

    past

    $past(signal_name, number of cloc cycles)
    
    • 1

    $ stable是参考了前一个时钟周期的值,我们可以通过$ past访问当前时刻前一些周期的值,其中第一个参数制定了信号,第二个参数指定了访问了前几个周期。

    property p;
    	@(posedge clk) b |-> ($past(a,2)==1);
    endproperty
    a:assert property(p);
    
    • 1
    • 2
    • 3
    • 4

    上面例子显示,在每一个时钟周期的上升沿检查b是否高电平,若是的,则在此时的前两个周期信号a是高电平。
    我们也可以有条件地访问过去周期的值,第三个参数是门控信号,可以理解为使能信号。

    $past(signal_name, number of clock cycles, gating signal)
    
    • 1

    还有一些跟位有关,见下图,onehot检查信号只有1bit为1,onehot0检查信号只有1bit为1或者全为0,isunknown检查信号的任意bit出现x或者z,countones返回信号所有位中1的个数。
    在这里插入图片描述
    在这里插入图片描述

    disable iff

    与约束一样,在一些情况下,我们不需要使能assertion。在systemverilog中,可以使用disable iff实现。在下面的例子中,如果信号a在一个给定的时钟上升沿为高时,那么信号b则要有三个时钟周期的高电平,紧接着的一个时钟周期信号c应该是高电平,但是在整个序列检查的过程中,如果reset的信号为高的话,那么整个检查都会被停止。注意蕴涵操作符,当a=0时,视为空成功,是依然进行检查的。

    property p;
    	@(posedge clk)
    	disable iff(reset) a |-> ##1 b[->3] ##1 c;
    endproperty
    a:assert prperty(p);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ended

    当我们要连接序列时,一个序列的末尾可以用于同步。在下面的例子中,seq_1表示a和b都为1,在下一个时钟周期c为1。seq_2表示d为1时,再经过4-6个时钟周期e=1。在属性p中,通过序列.ended连接了两个序列,可以理解为序列的末尾为1时必然出现完整的序列。

    sequence seq_1;
    	(a && b) ##1 c;
    endsequence
    
    sequence seq_2;
    	d ##[4:6] e;
    endsequence
    
    property p;
    	@(posedge clk) seq_1.ended |-> ##2 seq2_ended;
    endproperty
    a:assert property(p);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    delay

    前面我们延时一般都通过常量给定,如##2,但不能定义一个变量如num,##num的语法是错误的。
    在这里插入图片描述
    可以使用如下的方案:
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    c++TCP socket实时文件传输
    Spring Boot集成antlr实现词法和语法分析
    linux安装zookeeper
    Eclipse 主网即将上线迎空投预期,Zepoch 节点或成受益者?
    拓扑排序及其衍生
    Java:org.apache.commons.io包的工具类:IOUtils、FileUtils、FilenameUtils
    动态SQL第一部分(重点)
    垃圾回收机制的算法实现——引用计数算法的工程优化
    Java 某个经纬度是否在genjson文件中
    用 OpenCV 实现图像中水平线检测与校正
  • 原文地址:https://blog.csdn.net/weixin_45614076/article/details/126447659