// vr_checker.sv — valid/ready stream rules, usable from either side // SRC_IS_DUT = 1 : the design under test drives valid/data -> source rules asserted // SRC_IS_DUT = 0 : the design under test drives ready -> source rules assumed module vr_checker #( parameter int W = 8, parameter bit SRC_IS_DUT = 1'b1, parameter int MAX_STALL = 8 // sink must accept within this many cycles ) ( input logic clk, input logic rst, input logic valid, input logic ready, input logic [W-1:0] data ); default clocking cb @(posedge clk); endclocking default disable iff (rst); // Source-side rules property p_valid_held; valid && !ready |=> valid; endproperty property p_data_stable; valid && !ready |=> $stable(data); endproperty // Sink-side rule property p_no_long_stall; valid |-> ##[0:MAX_STALL-1] ready; endproperty if (SRC_IS_DUT) begin : g_dut_is_source a_valid_held: assert property (p_valid_held); a_data_stable: assert property (p_data_stable); m_no_long_stall: assume property (p_no_long_stall); end else begin : g_dut_is_sink m_valid_held: assume property (p_valid_held); m_data_stable: assume property (p_data_stable); a_no_long_stall: assert property (p_no_long_stall); end c_stall_then_accept: cover property (valid && !ready ##1 valid && ready); c_back_to_back: cover property (valid && ready ##1 valid && ready); endmodule