SVA中的与或非(and_or_not)

面对复杂的时序关系,往往一个sequence已经不能完全实现一个复杂功能的检查。为此,在SVA中引入了逻辑操作的概念,与其他语句结构的逻辑操作符不同的是,断言中进行逻辑操作的是序列而不是表达式。在SVA中常用的逻辑操作有三种:and,or,not等。


1 and

“and”可以按照逻辑与的方式组合两个序列,当两个序列都匹配时,整个属性成功。使用方式如下:
property p;
    sequence_1 and sequence_2;
endproperty //p
但是在具体使用时需要注意,sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点以两个sequence中最后一个成功的sequence的匹配点为属性的成功点。
 【示例】
`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0,sig1;

initial begin
    clk = 1'b0;
    forever #1 clk = ~clk;
end

initial begin
       sig0 = 1'b0;sig1 = 1'b0;
    #2 sig0 = 1'b1;
    #2 sig0 = 1'b0;sig1 = 1'b1;
    #4 sig1 = 1'b0;$stop;
end
// sequence s0
sequence s0;
    @(posedge clk) $rose(sig0) ##1 sig1;
endsequence // s0
// sequence s1 
sequence s1;
    @(posedge clk) $rose(sig0) ##2 sig1;
endsequence // s1
// property
property p;
    s0 and s1;
endproperty // p
as0 : assert property(s0) $display("@%0t | s0 : PASSED!",$time);
      else $display("@%0t | s0 : FAILED!",$time);
as1 : assert property(s1) $display("@%0t | s1 : PASSED!",$time);
      else $display("@%0t | s1 : FAILED!",$time);
ap  : assert property(p) $display("@%0t | p : PASSED!",$time);
      else $display("@%0t | p : FAILED!",$time);      
endmodule
【仿真结果】 

示例中,s0和s1监测的起始点都是在3ns,s0在5ns时断言匹配,但是s1在7ns时才断言匹配,此时“s0 and s1”成功,可见两个序列and时,两个序列的起始点必须一样,但是结束点可以不一样,结束点取决于最后一个匹配的序列。

为了确保设计中的某些同时发生的并行操作能够正确执行,可以使用and操作符实现对这种场景的检查。


2 or

“or”可以按照逻辑或的方式组合两个序列,当两个序列有一个匹配时,整个属性成功。使用方式如下:

property p;
    sequence_1&nbs***bsp;sequence_2;
endproperty //p
但是在具体使用时需要注意,sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点取决于最早匹配成功的sequence,只要两个序列有一个匹配成功,整个属性就认为匹配。



【示例】
`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0,sig1;

initial begin
    clk = 1'b0;
    forever #1 clk = ~clk;
end

initial begin
       sig0 = 1'b0;   sig1 = 1'b0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;   sig1 = 1'b1;
    #4 sig1 = 1'b0;#2 sig0 = 1'b1;#2 sig0 = 1'b0;
    #2 sig1 = 1'b1;#3 sig1 = 1'b0;#4 $stop;
end
//sequece s0
sequence s0;
    @(posedge clk) $rose(sig0) ##1 sig1;
endsequence // s0
// sequence s1
sequence s1;
    @(posedge clk) $rose(sig0) ##2 sig1;
endsequence // s1
// property p
property p;
    s0&nbs***bsp;s1;
endproperty // p
// assertion
as0 : assert property(s0) $display("@%0t | s0 : PASSED!",$time);
      else $display("@%0t | s0 : FAILED!",$time);
as1 : assert property(s1) $display("@%0t | s1 : PASSED!",$time);
      else $display("@%0t | s1 : FAILED!",$time);
ap  : assert property(p) $display("@%0t | p : PASSED!",$time);
      else $display("@%0t | p : FAILED!",$time); 
endmodule
【仿真结果】 

示例中,在5ns开始s0首先匹配成功,则此时“s0 or s1”匹配成功,此时s1尚未匹配,匹配结束点与s0一样;在13ns处s0没有匹配成功,但是s1在15ns匹配成功,则此时“s0 or s1”匹配成功,且结束点与s1匹配的结束点一样。可见or操作的结束匹配位置为第一个匹配序列的结束点。


3 not

“not”虽然只是对序列结果取反,但是在SVA中,理解not时必须注意反向思维,否则可能混乱。因为not操作的对象为一个序列,所以not操作的起始和结束点与其操作的对象一致。使用方式如下:

property p;
    not (sequence);
endproperty //p
括号中为删除内容(但是在具体使用时需要注意,sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点取决于最早匹配成功的sequence,只要两个序列有一个匹配成功,整个属性就认为匹配。)


【示例】
`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0,sig1;

initial begin
    clk = 1'b0;
    forever #1 clk = ~clk;
end

initial begin
       sig0 = 1'b0;   sig1 = 1'b0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;   sig1 = 1'b1;
    #4 sig1 = 1'b0;#2 sig0 = 1'b1;#2 sig0 = 1'b0;
    #2 sig1 = 1'b1;#3 sig1 = 1'b0;#4 $stop;
end
//sequece s
sequence s;
    $fell(sig0) ##1 sig1;
endsequence // s
// property p
property p;
    @(posedge clk) not s;
endproperty // p
// assertion
as : assert property(@(posedge clk) s) $display("@%0t | s : PASSED!",$time);
      else $display("@%0t | s : FAILED!",$time);
ap  : assert property(p) $display("@%0t | p : PASSED!",$time);
      else $display("@%0t | p : FAILED!",$time); 
endmodule
【仿真结果】 

示例中,在3ns时序列s失败,但是“not s”匹配成功,但是在7ns时,s匹配成功,但是“not s”不匹配,注意这次匹配的起始点在5ns处。可见not是对序列的反向匹配。之所以看到图中“not s”在7ns时存在一个匹配的表示,那是因为s在此刻(7ns)被采样为假。



【示例】
`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0,sig1,sig2;

initial begin
    clk = 1'b0;
    forever #1 clk = ~clk;
end

initial begin
       sig0 = 1'b0;   sig1 = 1'b0;   sig2 = 1'b0;
    #2 sig0 = 1'b1;#2 sig1 = 1'b1;   sig0 = 1'b0;
    #2 sig2 = 1'b1;   sig1 = 1'b0;#2 sig2 = 1'b0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;#2 sig1 = 1'b1;
    #2 sig1 = 1'b0;   sig2 = 1'b1;#4 sig2 = 1'b0;
    $stop;
end
// property
property p;
    @(posedge clk) not(sig0 ##2 sig1 |-> ##1 sig2);
endproperty // p
// assertion
ap  : assert property(p) $display("@%0t | p : PASSED!",$time);
      else $display("@%0t | p : FAILED!",$time); 
endmodule  // top_tb
【仿真结果】 

示例中,在3ns时作为|->的先行算子“sig0 ##2 sig1”为假,此时按照之前定义的蕴含操作的说明,当先行算子为假时,此时的蕴含操作将会为空成功。而在实际的应用中,对空成功的not操作将会表现为一次断言匹配失败,即空成功被not操作认为是一次“真成功”,这样的基于空成功的not操作得到的结果可能不是期望的。在具有蕴含操作断言中使用not操作一定要注意起作用的表达式的组成,否则结果不堪设想。


全部评论

相关推荐

评论
点赞
1
分享
牛客网
牛客企业服务