verilator/test_regress/t/t_cover_fsm_reset.v

156 lines
3.1 KiB
Systemverilog

// 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
case (state_incl)
S0: state_incl <= S1;
default: state_incl <= S1;
endcase
end
always_ff @(posedge clk) begin
if (rst) state_excl <= S0;
else
case (state_excl)
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
case (state_q)
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
case (state_q)
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