Fix FSM detection of coverage-only branches (#7941) (#7942)

Fixes #7941
This commit is contained in:
Patrick Creighton 2026-07-16 09:48:36 -07:00 committed by GitHub
parent 255bcff3ac
commit cc1b36bafd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 70 additions and 2 deletions

View File

@ -1106,9 +1106,8 @@ class FsmDetectVisitor final : public VNVisitor {
AstVarScope* thenVscp = nullptr;
AstVarScope* elseVscp = nullptr;
AstNode* const thenNodep = singleMeaningfulBranch(skipLeadingIgnorableStmt(ifp->thensp()));
UASSERT_OBJ(thenNodep, ifp, "Empty then-branch unexpectedly survived to FSM detection");
AstNode* const elseNodep = singleMeaningfulBranch(skipLeadingIgnorableStmt(ifp->elsesp()));
if (!elseNodep) return false;
if (!thenNodep || !elseNodep) return false;
if (!directConstStateAssignNode(thenNodep, thenVscp, thenValue)) return false;
if (!directConstStateAssignNode(elseNodep, elseVscp, elseValue)) return false;
if (thenVscp == stateVscp && elseVscp == stateVscp) return true;

View File

@ -45,6 +45,38 @@
end
endmodule
module fsm_negated_guard (
%000009 input logic clk,
%000001 input logic rst,
%000001 input logic hold
);
typedef enum logic {
S0,
S1
} state_t;
%000004 state_t state_q;
%000004 state_t state_d;
000010 always_comb begin
000010 state_d = state_q;
~000010 case (state_q)
// [FSM coverage]
%000001 // [fsm_arc t.negated_guard_u.state_q::ANY->S0[reset]] [reset arc, excluded from %]
%000003 // [fsm_arc t.negated_guard_u.state_q::S1->S0]
%000003 // [fsm_state t.negated_guard_u.state_q::S0]
%000004 // [fsm_state t.negated_guard_u.state_q::S1]
%000009 S0: if (!hold) state_d = S1;
%000004 S1: state_d = S0;
endcase
end
%000009 always_ff @(posedge clk) begin
%000007 if (rst) state_q <= S0;
%000007 else state_q <= state_d;
end
endmodule
module fsm_three_block (
%000009 input logic clk,
%000001 input logic rst,
@ -426,6 +458,11 @@
.rst(rst),
.start(start)
);
fsm_negated_guard negated_guard_u (
.clk(clk),
.rst(rst),
.hold(start)
);
fsm_three_block three_block_u (
.clk(clk),
.rst(rst),

View File

@ -37,6 +37,33 @@ module fsm_basic (
end
endmodule
module fsm_negated_guard (
input logic clk,
input logic rst,
input logic hold
);
typedef enum logic {
S0,
S1
} state_t;
state_t state_q;
state_t state_d;
always_comb begin
state_d = state_q;
case (state_q)
S0: if (!hold) state_d = S1;
S1: state_d = S0;
endcase
end
always_ff @(posedge clk) begin
if (rst) state_q <= S0;
else state_q <= state_d;
end
endmodule
module fsm_three_block (
input logic clk,
input logic rst,
@ -369,6 +396,11 @@ module t (
.rst(rst),
.start(start)
);
fsm_negated_guard negated_guard_u (
.clk(clk),
.rst(rst),
.hold(start)
);
fsm_three_block three_block_u (
.clk(clk),
.rst(rst),