SVA中的内嵌函数

SVA中存在着大量的内嵌函数,这些函数在实现对特定状态数据检查非常有用,本文将示例其中几种常用的内嵌函数,这几个内嵌函数为:$onehot\$onehot0\$isunknown\$countones等。


1 $onehot(expression)

该函数主要用于在任意给定的采样事件,表达式最终结果中不管其他位为不定态还是高阻态,只要有一位且仅有一位为高时,该函数即返回真。

【示例】
`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0;
logic [7:0] sig1;

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

initial begin
       sig0 = 1'b0;   sig1 = 8'b0000_0000;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0001;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0011;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0000;
    #6 $stop;
end

sequence s;
    @(posedge clk) $onehot(sig1);
endsequence  // s
property p;
    @(posedge clk) $rose(sig0) |-> ##1 s;
endproperty // p

a : assert property(p) $display("@%0t | p : PASSED!",$time);
    else $display("@%0t | p : FAILED!",$time);
endmodule // top_tb
【仿真结果】
示例中,在第一次检查时,sig1只有一位为高,所以$onehot返回真,属性匹配;第二次检查时sig1中有2位为高,所以$onehot返回假,属性不匹配;第三次检查sig1sig1[1]为不定态,sig1其他位为低,$onehot返回假,属性不匹配;第四次检查sig1sig1[1]为高阻态,sig1其他位为低,$onehot返回假,属性不匹配;第五次检查sig1sig[1]为不定态,sig1[3]为高电平,即sig1中有1位为高电平,所以$onehot返回真,属性匹配;第六次检查sig1sig1[1]为高阻态,sig1[3]为高电平,即sig1中有1位为高电平,所以$onehot返回真,属性匹配;第七次检查sig1所有位都为低电平,所以$onehot返回假,属性不匹配。

2 $onehot0(expression)

该函数主要用于在任意给定的采样事件,表达式最终结果中不管其他位为不定态还是高阻态,只要有一位为高或者没有任何位为高时,该函数即返回真。

【示例】

`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0;
logic [7:0] sig1;

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

initial begin
       sig0 = 1'b0;   sig1 = 8'b0000_0000;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0001;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0011;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0000;
    #6 $stop;
end

sequence s;
    @(posedge clk) $onehot0(sig1);
endsequence  // s
property p;
    @(posedge clk) $rose(sig0) |-> ##1 s;
endproperty // p

a : assert property(p) $display("@%0t | p : PASSED!",$time);
    else $display("@%0t | p : FAILED!",$time);
endmodule // top_tb
【仿真结果】
示例中,在第一次检查时,sig1只有一位为高,所以$onehot0返回真,属性匹配;第二次检查时sig1中有2位为高,所以$onehot0返回假,属性不匹配;第三次检查sig1sig1[1]为不定态,sig1其他位为低,$onehot0返回真,属性匹配;第四次检查sig1sig1[1]为高阻态,sig1其他位为低,$onehot0返回真,属性匹配;第五次检查sig1sig[1]为不定态,sig1[3]为高电平,即sig1中有1位为高电平,所以$onehot0返回真,属性匹配;第六次检查sig1sig1[1]为高阻态,sig1[3]为高电平,即sig1中有1位为高电平,所以$onehot0返回真,属性匹配;第七次检查sig1所有位都为低电平,所以$onehot0返回真,属性匹配。

3 $isunknown(expression)

该函数用于检验表达式最终结果中的各位中是否有x或者z

【示例】

`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0;
logic [7:0] sig1;

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

initial begin
       sig0 = 1'b0;   sig1 = 8'b0000_0000;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0001;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0011;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0000;
    #6 $stop;
end

sequence s;
    @(posedge clk) $isunknown(sig1);
endsequence  // s
property p;
    @(posedge clk) $rose(sig0) |-> ##1 s;
endproperty // p

a : assert property(p) $display("@%0t | p : PASSED!",$time);
    else $display("@%0t | p : FAILED!",$time);
endmodule // top_tb
【仿真结果】

示例中,当sig1中存在X或者Z时,$isunknown就会返回真,此时属性检查匹配。当sig1中不存在X或者Z时,$isunknown就会返回假,此时属性检查不匹配。


4 $countones(expression)

该函数主要用于获得信号中电平为高的位的个数。

【示例】

`timescale 1 ns / 1 ps
module top_tb;
logic clk;
logic sig0;
logic [7:0] sig1;

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

initial begin
       sig0 = 1'b0;   sig1 = 8'b0000_0000;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0001;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0011;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_00z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10x0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_10z0;
    #2 sig0 = 1'b1;#2 sig0 = 1'b0;sig1 = 8'b0000_0000;
    #6 $stop;
end

sequence s;
    @(posedge clk) $countones(sig1);
endsequence  // s
property p;
    @(posedge clk) $rose(sig0) |-> ##1 s;
endproperty // p

a : assert property(p) $display("@%0t | p : PASSED!",$time);
    else $display("@%0t | p : FAILED!",$time);
endmodule // top_tb
【仿真结果】

示例中,当sig1中没有任何一位为高电平,那么$countones返回为0,即认为假,所以属性检查不匹配。当sig1中有某一位或者多位为高,那么$countones返回为不为0的位的个数,在属性判断中非零即认为真,所以示例中属性检查在某位或者多位为高电平时匹配。



全部评论
SVA中的内嵌函数新知识
点赞 回复 分享
发布于 2022-10-16 16:21 河南

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务