// // verilator_coverage annotation // DESCRIPTION: Verilator: FSM coverage grouped reset semantics test // // This file ONLY is placed under the Creative Commons Public Domain. // SPDX-FileCopyrightText: 2026 Wilson Snyder // SPDX-License-Identifier: CC0-1.0 // Group accepted simulator-style reset semantics, including reset include / // exclude behavior and nearby fallback cases that should still preserve FSMs. module fsm_reset_policy ( input logic clk, input logic rst ); typedef enum logic [0:0] { S0 = 1'b0, S1 = 1'b1 } state_t; state_t state_incl /*verilator fsm_reset_arc*/; state_t state_excl; always_ff @(posedge clk) begin if (rst) state_incl <= S0; else %000001 case (state_incl) // [FSM coverage] %000001 // [fsm_arc t.reset_policy_u.state_incl::ANY->S0[reset_include]] %000001 // [fsm_arc t.reset_policy_u.state_incl::S0->S1] %000000 // [fsm_state t.reset_policy_u.state_incl::S0] *** UNCOVERED *** %000001 // [fsm_state t.reset_policy_u.state_incl::S1] S0: state_incl <= S1; default: state_incl <= S1; endcase end always_ff @(posedge clk) begin if (rst) state_excl <= S0; else %000001 case (state_excl) // [FSM coverage] %000001 // [fsm_arc t.reset_policy_u.state_excl::ANY->S0[reset]] %000001 // [fsm_arc t.reset_policy_u.state_excl::S0->S1] %000000 // [fsm_state t.reset_policy_u.state_excl::S0] *** UNCOVERED *** %000001 // [fsm_state t.reset_policy_u.state_excl::S1] S0: state_excl <= S1; default: state_excl <= S1; endcase end endmodule module fsm_reset_other_assign_ok ( input logic clk, input logic rst ); typedef enum logic [1:0] { S0 = 2'b00, S1 = 2'b01, S2 = 2'b10 } state_t; logic aux; logic start; state_t state_q; state_t state_d; always_ff @(posedge clk) begin if (rst) begin aux <= 1'b1; start <= 1'b1; state_q <= S0; aux <= 1'b0; end else begin state_q <= state_d; end end always_comb begin state_d = state_q; case (state_q) S0: state_d = start ? S1 : S2; default: state_d = S0; endcase end endmodule module fsm_oneblock_reset_mismatch_ok ( input logic clk, input logic rst ); typedef enum logic [1:0] { S0 = 2'd0, S1 = 2'd1, S2 = 2'd2 } state_t; state_t state_q = S0; state_t other_q = S2; always_ff @(posedge clk) begin if (rst) begin other_q <= S0; end else begin %000001 case (state_q) // [FSM coverage] %000001 // [fsm_arc t.oneblock_reset_mismatch_ok_u.state_q::S0->S1] %000000 // [fsm_state t.oneblock_reset_mismatch_ok_u.state_q::S0] *** UNCOVERED *** %000001 // [fsm_state t.oneblock_reset_mismatch_ok_u.state_q::S1] %000001 // [fsm_state t.oneblock_reset_mismatch_ok_u.state_q::S2] S0: state_q <= S1; default: state_q <= S2; endcase end end endmodule module fsm_oneblock_reset_nonconst_ok ( input logic clk, input logic rst ); typedef enum logic [1:0] { S0 = 2'd0, S1 = 2'd1, S2 = 2'd2 } state_t; state_t state_q = S0; state_t other_q = S2; // Useful because the one-block reset fallback must ignore non-constant reset // assignments and still retain the supported case(state_q) FSM below. always_ff @(posedge clk) begin if (rst) begin state_q <= other_q; end else begin %000001 case (state_q) // [FSM coverage] %000000 // [fsm_arc t.oneblock_reset_nonconst_ok_u.state_q::S0->S1] %000000 // [fsm_state t.oneblock_reset_nonconst_ok_u.state_q::S0] *** UNCOVERED *** %000000 // [fsm_state t.oneblock_reset_nonconst_ok_u.state_q::S1] *** UNCOVERED *** %000001 // [fsm_state t.oneblock_reset_nonconst_ok_u.state_q::S2] S0: state_q <= S1; default: state_q <= S2; endcase end end endmodule module t ( input logic clk ); logic rst; integer cyc; fsm_reset_policy reset_policy_u (.clk(clk), .rst(rst)); fsm_reset_other_assign_ok reset_other_assign_ok_u (.clk(clk), .rst(rst)); fsm_oneblock_reset_mismatch_ok oneblock_reset_mismatch_ok_u (.clk(clk), .rst(rst)); fsm_oneblock_reset_nonconst_ok oneblock_reset_nonconst_ok_u (.clk(clk), .rst(rst)); initial begin rst = 1'b1; cyc = 0; end always @(posedge clk) begin cyc <= cyc + 1; if (cyc == 1) rst <= 1'b0; if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule