package sva_delay_repeat_range_pkg; // int d1, d2; // bit a, b, c=1'b1; // sequence q_s; a ##1 c; endsequence // sequence my_sequence; e ##1 d[->1]; endsequence //---------------------------------------------------------------- // ****** DYNAMIC DELAY ##d1 ********** // Application: $rose(a) |-> q_dynamic_delay(d1) ##0 my_sequence; sequence q_dynamic_delay(count); int v; (1, v=count) ##0 first_match((1, v=v-1'b1) [*0:$] ##1 v<=0); endsequence //---------------------------------------------------------------- // ****** DYNAMIC DELAY RANGE ##[d1:d2] ********** //##[d1:d2] ##0 b; // NO sequence followng the "b" // $rose(a) |-> q_dynamic_delay_range(d1, d2, b)) // and b[->1] ##1 my_sequence; // $rose(a) ##0 q_dynamic_delay_range(d1, d2, b) |-> my_sequence; sequence q_dynamic_delay_range(int d1, d2, bit b); int v1, vdiff; (1, v1=d1, vdiff=d2-d1) ##0 q_dynamic_delay(v1) ##0 first_match((1, vdiff=vdiff - 1)[*0:$] ##1 (b || vdiff<=0)) ##0 b; endsequence //---------------------------------------------------------------- // ****** DYNAMIC REPEAT q_s[*d1] ********** // Application: $rose(a) |-> q_dynamic_repeat(q_s, d1) ##1 my_sequence; sequence q_dynamic_repeat(q_s, count); int v=count; (1, v=count) ##0 first_match((q_s, v=v-1'b1) [*1:$] ##0 v<=0); endsequence //---------------------------------------------------------------- // ****** DYNAMIC REPEAT RANGE q_s[*d1:d2] ********** // Application: $rose(a) |-> (q_dynamic_repeat_range(q_s, d1, d2, b) // and b[->1] ##1 my_sequence // use the same "b" // $rose(a) ##1 q_dynamic_repeat_range(q_s, d1, d2, b) |-> my_sequence; sequence q_dynamic_repeat_range_until(sequence q_s, int r1, r2, bit b); int v, diff; (1, v=r1, diff=r2-r1) ##0 q_dynamic_repeat(q_s, v) ##0 // repeat to r1 first_match((q_s, diff=diff-1'b1) [*0:$] ##1 (b || diff<=0 )) ##0 b; endsequence sequence q_dynamic_repeat_range_fixed(sequence q_s, int r1, r2); int v, diff; (1, v=r1, diff=r2-r1) ##0 q_dynamic_repeat(q_s, v) ##0 // repeat to r1 first_match((q_s, diff=diff-1'b1) [*0:$] ##1 (diff<=0 )); endsequence endpackage module m(input bit clk, a, rst_n, input bit[1:0] v, output bit b); import uvm_pkg::*; `include "uvm_macros.svh" import sva_delay_repeat_range_pkg::*; timeunit 1ns; timeprecision 100ps; bit a_r, b0, b1, rose; bit[1:0] cycle; am_v: assume property(@ (posedge clk) v > 0); // ****** DYNAMIC DELAY ##v ********** // Application: $rose(a) |-> q_dynamic_delay(v) ##0 my_sequence; ap_dyn_delay: assert property(@ (posedge clk) $rose(a) |-> q_dynamic_delay(v) ##0 b); ap_fix_delay: assert property(@ (posedge clk) $rose(a) |-> ##3 b); // For formal verification generate for (genvar i=0; i<=3; i++) begin ap_fvi: assert property(@ (posedge clk) v==i && $rose(a) |-> ##i b); end endgenerate always_ff @(posedge clk or negedge rst_n) // needed to detect $rose if(!rst_n) a_r <= 1'b0; else a_r <= a; let vminus1=v-1'b1; always_ff @(posedge clk or negedge rst_n) begin if(!rst_n) begin a_r <= 1'b0; cycle <= 2'b00; b <= 1'b0; rose <= 1'b0; end else if(cycle==2'b00 && a==1 && a_r==0) begin // $rose cycle <= cycle + 1'b1; rose <= 1'b1; b <= 1'b0; end else if (cycle == vminus1) begin // the end of the ## cycle <= 2'b00; b <= 1'b1; rose <= 1'b0; end else if (rose==1'b1) begin cycle <= cycle + 1'b1; b <= 1'b0; end end endmodule module top; import uvm_pkg::*; `include "uvm_macros.svh" timeunit 1ns; timeprecision 100ps; bit clk=1'b1, a, b, rst_n=1'b1; bit[1:0] v=2'b11; initial forever #10 clk=!clk; m m1(.*); initial begin repeat(3) @(posedge clk); rst_n <= 1'b0; @(posedge clk); rst_n <= 1'b1; repeat(100) begin @(posedge clk); #2; if (!randomize(a) with { a dist {1'b1:=1, 1'b0:=1}; }) `uvm_error("MYERR", "randomize error"); end $stop; end endmodule