一、为什么需要bind
一般在设计RTL代码中,如果设计人员在其中写了assert,这样能够很方便在仿真去收集设计代码的运行结果和情况。但是如果没有写assert,但是我们验证人员是没有办法去修改设计代码的,所以我们需要将assertion与DUT设计绑定在一起。
module test(clk,rst,sig0,sig1);
input sig0;
input clk,rst;
output sig1;
bit sig1;
always@(posedge clk)
begin
if(rst == 1'b0)
sig1 <= 1'b0;
else sig1 <=sig0;
end
endmodule
//>>>step1 : define sva
module ast_chk(clk,rst,sig0,sig1);
input clk,rst,sig0,sig1;
//property
property p;
@(posedge clk)
disable iff(rst == 1'b0)
sig0 |->##1 sig1;
endproperty
//assert
a:assert property(p)$display("@%0t | p :PASSED",$time);
else $display("@%0t | p:FAILED!",$time);
endmodule
//tb
module top_tb;
bit clk,rst;
bit sig0;
bit sig1;
initial begin
clk = 1'b0;
forever #1 clk = ~clk;
end
initial begin
sig0 = 1'b0;
rst = 1'b0;
#2 rst = 1'b1;
#2 sig0 = 1'b1;
#2 sig0 = 1'b0;
#4 sig0 = 1'b1;
#3 sig0 = 1'b0;
#4 $stop;
end
//>>>step2:instance dut and sva
test u_dut(clk,rst,sig0,sig1);
ast_chk sva_01(clk,tst,sig0,sig1);
//>>>step3:bind sva and dut
bind test ast_chk sva_01(clk,rst,sig0,sig1);
endmodule
代码解释:
- 这里的assertion与DUT代码是分开的,然后用过进行单独的定义,之后再进行设计例化bind在一起;
- 其中还会将assertion与DUT的信号进行连接;
- bind和assertion关联的信号不一定是所有信号,关联的port list可以少于DUT实际端口数;
- bind时使用的是设计实例化时连接端口的实际信号名,不是设计定义时指定的端口名,如果设计例化时也是原端口名则可以继续使用;
二、bind的多种形式
bind <module_name or instance_name> <checker_name> <checker_instance_name> <design_signals>
- module_name和instance_name用于指定将要被监测的设计的模块名或者实例名;
- checker_name用于指定监测模块名,即定义断言属性的模块;
- checker_instance_name用于指定监测模块的实例名;
- design_signals用于指定将要监测的模块的信号;
- 如果bind时使用具体的实例化名,那么assertion仅可与特定的实例化设计关联,与同一模块的其他实例化不关联;
- 如果bind时使用的是待测设计定义时指定的名字(module_name),那么assertion将可与该待测设计所有的实例关联
module test(clk,rst,sig0,sig1);
input sig0;
input clk,rst;
output bit sig1;
always@(posedge clk)
begin
if(rst == 1'b0)
sig1 <= 1'b0;
else
sig1 <= sig0;
end
endmodule
//>>>step1:define sva
module ast_chk(clk,rst,sig0,sig1);
input clk,rst,sig0,sig1;
//property
property p;
@(posedge clk)
disable iff(rst == 1'b0)
sig0 |->##1 sig1;
endproperty
//assert
a:assert property(p) $display("@%0t | p :PASSED!",$time);
else $display("@%0t | p FAILED! ",$time);
endmodule
module top_tb;
bit clk,rst;
bit sig0,sig1;
initial begin
clk = 1'b0;
forever #1 clk = ~clk;
end
initial begin
sig0 = 1'b0;
rst = 1'b0;
#2 rst = 1'b1;
#2 sig0 = 1'b1;
#2 sig0 = 1'b0;
#4 sig0 = 1'b1;
#3 sig0 = 1'b0;
#4 $stop;
end
//>>>step2:instance dut and sva
test u_dut0(clk,rst,sig0,sig1);
test u_dut1(clk,rst,sig0,sig2);
ast_chk sva_01(clk,rst,sig0,sig1);
ast_chk sva_01(clk,rst,sig0,sig2);
//>>>step3:bind sva and dut
bind test:u_dut0 ast_chk sva_01(clk,rst,sig0,sig1);
bind test:u_dut1 ast_chk sva_01(clk,rst,sig0,sig1);//
endmodule
- bind可以选择test中的进行,但是一个bind实例只能bind一个;
- bind时候需要连接的信号是他们的真实信号,上面的实例名可以改变,但是bind的时候需要把它们的都变会原来的;