举例介绍序列:

例1

sequence seq1
    @(posedge clk) b;
endsequence

序列seq1检查信号 “b” 在每个时钟上升沿都为高电平。如果信号 “b” 在任何一个时钟上升沿不为高电平,断言将失败。这相当于 “b == 1’b1”。

例2

sequence seq_a_and_b;
    @(posedge clk) a&&b;
endsequence

//在断言的property中调用sequence
check_a_and_b:assert property(seq_a_and_b);

//或如下
check_a_and_b: assert property(seq_a_and_b) $display("a&&b is true");
    else $error("a&&b is false");

例3:带参数的sequence

sequence seq1(signal_1, signal_2);
    @(posedge clk) signal_1&&signal_2;
endsequence

//在断言的property中调用sequence
check_a_and_b:assert property(seq1(a,b));

//或如下
check_a_and_b:assert property(seq1(a,b)) $display("a&&b is true");
    else $error("a&&b is false");

例4:带时序关系的sequence,在SVA 中时钟延时用符号 “##” 来表示,如 “##2” 表示延时两个时钟周期;

sequence seq2;
    @(posedge clk) a ##2 b;
endsequence

//在断言的property中调用sequence
check_a_and_b:assert property(seq2);

sequence只有在时钟上升沿到来后检查a是否为1才会继续检查后面的b;

例5:sequence内可以调用其他sequence

sequence seq1;
    @(posedge clk) a&&b;
endsequence

sequence seq2;
    seq1;
endsequence

sequence与property的异同

  1. 任何sequence中的表达式都可以放到property中;
  2. 任何在property中的表达式也可以搬到sequence中,但是只有在property中才能使用蕴含操作符 |->(立即检查), |=>(打一拍再检查) 。
  3. property中可以例化其他property和sequence,sequence中也可以调用其他的sequence,但是不能例化property;
  4. property需要用 cover/assert/assume 等关键字进行实例化,而sequence直接调用即可;

蕴含操作符详解:

  1. 蕴含(implication)操作符用来表示,如果property中左边的先行算子(antecedent)成立,那么property右边的后续算子(consequent)才会被计算。
  2. 如果先行算子不成功,那么整个属性就默认地被认为成功,这叫做“空成功”(vacuous success)。
  3. 蕴含结构只能用在属性定义中,不能再序列中使用。
  4. 蕴含可以分为两类:交叠蕴含(overlapped implication)和非交叠蕴含(non-overlapped implication)。
  • |->交叠操作符

        如果条件满足,则评估其后续算子序列。

        如果条件不满足,则表现为空成功,不执行后续算子。

  • |=>非交叠操作符

        如果条件满足,则在下一个周期评估其后续算子序列。

        如果条件不满足,则表现为空成功,不执行后续算子。

SVA触发判断

  1. clock触发事件:@(posedge clk) A事件;
  2. 边沿触发事件

                $rose(a);           //-----------信号上升

                $fell(a);             //-----------信号下降

                $stable(a);        //-----------信号值不变

                $changed(a);    //----------return 1 if signal changed

断言循环延迟范围(##[])

判断多个事件/信号的行为关系:

简单SVA举例:

“disable iff”构造

在某些设计情况中,如果一些条件为真,则我们不想执行检验。换句话说,这就像是一个异步的复位,使得检验在当前时刻不工作。SVA提供了关键词“disable iff”来实现这种检验器的异步复位。

“disable iff”的基本语法如下:

disable iff(expression)<property definition0>

        FIFO的验证:

        1、检查FIFO满时不再写:

check_enqueue_no_wr: assert property (@posedge clk) disable iff(!rst_n)
    full |-> !wr;

        2、检查FIFO空时不再读:

check_denqueue_no_rd: assert property (@posedge clk) disable iff(!rst_n)
    empty |-> !rd;

断言覆盖率:

  1. 断言:用于一次性地或在一段时间内核对两个设计信号之间关系的声明性代码。
  2. 断言覆盖率可以测量某断言被触发的频繁程度。
  3. 断言可以跟随设计和测试平台一起仿真,也可以被形式验证工具所证实。
  4. 可以使用SV的程序性代码编写等效性检查,但使用SVA来表达会更容易。
  5. 断言最常用于查找错误,例如两个信号之间的相位关系,是否应该互斥或者请求与许可信号之间的时序等。
  6. 一旦检测到问题,仿真就可以立即停止。
  7. 断言可以用于查找感兴趣的信号的值或状态。
  8. 可以使用cover property来测量这些关心的信号的值或者状态是否发生。
  9. 在仿真结束时,仿真工具可以自动生成断言覆盖率数据。
  10. 断言覆盖率数据以及其他覆盖率数据都会被集成在同一个覆盖率数据库中,验证人员可以对其展开分析。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐