在验证的过程中, 老工程师总会提到, 需要做一个计数器, 来检测中断请求和响应匹配.
这是一个直觉且直接的想法, 中断检测计数器会在仿真从开始工作到结尾.
这个检测机制可以使用assertion 进行表述, 比如当req发生时候, 5个周期内可以得到响应, 只要每个req得到满足 , 可以充分说明: 中断响应和请求是配对的.
ack_chk: assert property( @( posedge clk) sig_req |-> ## [1:5] sig_ack);
在实际电路中, 在mask 的前端 bind 这个assertion check 模块进行检测. 例化在hw_top 中, 留有debug info 和 en_sva 开关.
参考代码:
// irun cmd : irun -sv test.sv -access +r -input shm.tcl -assert
module test();
reg clk,rst;
reg sig_req;
reg sig_ack;
bit ack_sts;
bit [3:0] random_delay;
bit dbg_info;
// initial
initial begin
dbg_info = 1;
#7;
clk = 0;
rst= 0;
#4;
rst = 1;
#2000;
$finish;
end
initial forever #5 clk = ~clk;
// drive
initial begin
repeat (2) begin
#30;
std::randomize(random_delay);
#(random_delay);
if (dbg_info)$display($realtime,,"[before_req] random_delay is %0d",random_delay);
sig_req = 1;
@(posedge clk)
sig_req = 0;
#50;
sig_ack = 0;
end
end
// // sva check
ack_01: assert property( @( posedge clk) sig_req |-> ## [1:5] sig_ack);
// circuit
always@(posedge clk or negedge rst) begin
if(rst == 0) begin
sig_req = 0;
sig_ack = 0;
ack_sts = 0;
end else begin
if (sig_req == 1'b1) ack_sts <= 1'b1;
else ack_sts <= 0;
end
end
always @(posedge ack_sts) begin
randcase
1: begin
if (dbg_info)$display($realtime,,"case 1 enter");
repeat (1) @(posedge clk);
sig_ack = 1;
end
1: begin
if (dbg_info)$display($realtime,,"case 2 enter");
repeat (2) @(posedge clk);
sig_ack = 1;
end
1: begin
if (dbg_info)$display($realtime,,"case 3 enter");
repeat (3) @(posedge clk);
sig_ack = 1;
end
1: begin
if (dbg_info)$display($realtime,,"case 4 enter");
repeat (4) @(posedge clk);
sig_ack = 1;
end
endcase
end
endmodule
// shm.tcl
/*
database -open waves -shm
probe -create test -depth all -all -shm -database waves
run
exit
*/