文章目录
- 一、SVA 定义在模块中
- 二、SVA检验器与设计的bind绑定
-
- 2.1、通过模块名实现绑定
- 2.2、通过模块例化名实现绑定
- 三、典型DFF与MUX的断言
SVA检验器与设计(DUT)的连接方式主要有两种方式:
- 直接将SVA检验器定义在模块(module)中;
- 将SVA检验器与模块、模块的实例或者一个模块的多个实例进行bind绑定;
一、SVA 定义在模块中
示例:
module inline(clk, a, b, d1, d2);
input logic clk, a, b;
input logic [7:0] d1, d2;
output logic [7:0] d1;
always@(posedge clk) begin
if(a)
d <= d1;
if(b)
d <= d2;
end
property p_mutex;
@(posedge clk) not(a && b); // not关键字后的序列不能出现
endproperty
a_mutex: assert property(p_mutex); // DUT module中内嵌SVA检验器
endmodule
二、SVA检验器与设计的bind绑定
SVA检验器通过关键字bind可以与设计中的任何模块(module)或者实例(instance)绑定。实现绑定时,使用的是设计中的实际信号,语法如下:
2.1、通过模块名实现绑定
示例:
//1、设计模块
module inline(clk, a, b, d1, d2);
input logic clk, a, b;
input logic [7:0] d1, d2;
output logic [7:0] d1;
always@(posedge clk) begin
if(a)
d <= d1;
if(b)
d <= d2;
end
endmodule
//2、检验器模块——施加bind绑定设计module
module mutex_chk(a, b, clk);
input logic a, b, clk;
property p_mutex;
@(posedge clk) not(a && b);
endproperty
a_mutex: assert property(p_mutex);
endmodule
bind inline mutex_chk m_mutex_xhk(a,b,clk); //bind绑定语句在SVA模块外部
注: 通过bind语句将SVA检验器与设计module绑定,等价于将SVA例化到设计module中。
2.2、通过模块例化名实现绑定
示例:(top.u1)
// top层用以连接SVA与设计模块
module top(..);
...
inline u1(clk, a,b ,in1, in2, out1);
...
endmodule
//1、设计模块
module inline(clk, a, b, d1, d2);
input logic clk, a, b;
input logic [7:0] d1, d2;
output logic [7:0] d1;
always@(posedge clk) begin
if(a)
d <= d1;
if(b)
d <= d2;
end
endmodule
//2、检验器模块——施加bind绑定设计module
module mutex_chk(a, b, clk);
input logic a, b, clk;
property p_mutex;
@(posedge clk) not(a && b);
endproperty
a_mutex: assert property(p_mutex);
endmodule
bind top.u1 mutex_chk m_mutex_xhk(a,b,clk); //bind绑定语句在SVA模块外部, 绑定时的信号为设计中的实际信号
注:bind语句除了可以将将SVA检验器与设计module绑定,同样 可以实现其他任意两个模块之间的绑定。如:
三、典型DFF与MUX的断言
示例:
module simple_seq;
reg clk,rst;
reg sel1,sel2,sel3;
reg[15:0] d,q;
integer i;
initial begin clk = 1'b0; forever #25 clk = ~clk; end
initial begin rst = 1; #10; rst = 0; #100; rst = 1; end
initial begin
for(i=0; i<2000; i++)begin
d = $random();
sel1 = $random();
sel2 = sel1 ? 1'b0 : $random();
sel3 = (sel1 | sel2) ? 1'b0 : $random();
in1 = $random();
in2 = $random();
in3 = $random();
@(posedge clk);
end
$finish;
end
//####################DFF assertion###########################
always@(posedge clk or negedge rst)
if(!rst)begin
q <= 'h0;
end
else begin
q <= d;
end
property p_dff;
@(posedge clk)
disable iff(!rst)
rst |=> (q == $past(d));
endproperty
a_dff : assert property(p_dff) else $error("[DFF]DFF Check error for a_dff");
//###################MUX and DFF assertion###########################################
reg[15:0] sel_reg_out;
wire[15:0] sel_out;
assign sel_out = ({16{sel1}} & in1) | ({16{sel3}} & in3) | ({16{sel2}} & in2);
always@(posedge clk or negedge rst)
if(!rst)begin
sel_reg_out <= 'h0;
end
else begin
sel_reg_out <= sel_reg_out;
end
sequence s_sel;
sel_reg_out == $past(sel1 ? in1:
(sel2 ? in2:
(sel3 ? in3: 0)));
endsequence
property p_sel;
@(posedge clk)
disable iff(!rst)
rst |=> s_sel;
endproperty
a_sel : assert property(p_sel) else $error("[SELECT]SELECT Check error for a_sel");
endmodule