Skip to content

[FSM] Convert FSM to SMT#9379

Merged
TaoBi22 merged 146 commits intollvm:mainfrom
luisacicolini:fsm-to-smt-assertions
Mar 4, 2026
Merged

[FSM] Convert FSM to SMT#9379
TaoBi22 merged 146 commits intollvm:mainfrom
luisacicolini:fsm-to-smt-assertions

Conversation

@luisacicolini
Copy link
Copy Markdown
Contributor

@luisacicolini luisacicolini commented Dec 22, 2025

This PR lowers the FSM dialect into SMT assertions.

We represent states as SMT functions fun (out, var) taking as input the FSM's outputs and variables, and transitions s0 -> s1 as implications quantified over all the arguments, variables, and outputs:
forall arg0, arg1, out0, var0: vars F_s0(out0, var0) &&& guard_s01(arg0, var0) => F_s1(out1, var1), where:

  • out0 and var0 are universally quantified
  • out1 is computed according to the operations in the output regions of the respective states
  • guard_s01 is a boolean computed according to the transition's guard region, depending on the state's arguments and variables`
  • var1 is computed according to the transition's action region, considering the arguments at the arriving state s1, i.e., var1 = action(arg1, var0)
  • we universally quantify over all input values, for every state (arg0, arg1)

Co-authored-by: @AtticusKuhn

Copy link
Copy Markdown
Contributor

@TaoBi22 TaoBi22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Just a few nits and potential code simplifications below

Comment thread include/circt/Conversion/Passes.td Outdated
Comment thread include/circt/Conversion/Passes.td Outdated
Comment thread lib/Conversion/FSMToSMT/CMakeLists.txt Outdated
Comment thread lib/Conversion/FSMToSMT/FSMToSMT.cpp Outdated
Comment thread lib/Conversion/FSMToSMT/FSMToSMT.cpp Outdated
Comment thread lib/Conversion/FSMToSMT/FSMToSMT.cpp
Comment thread lib/Conversion/FSMToSMT/FSMToSMT.cpp
Comment thread lib/Conversion/FSMToSMT/FSMToSMT.cpp Outdated
Comment on lines +605 to +624
if (isa<comb::CombDialect, hw::HWDialect>(op.getDialect()) ||
isa<verif::AssertOp>(op)) {
auto *newOp = b.clone(op, mapping);

// Retrieve the assertion values
if (isa<verif::AssertOp>(newOp)) {
auto assertedVal = newOp->getOperand(0);
auto castVal = mlir::UnrealizedConversionCastOp::create(
b, loc, b.getType<smt::BitVectorType>(1), assertedVal);

// Convert to SMT boolean type
auto toBool = bv1toSmtBool(b, loc, castVal.getResult(0));
auto inState = smt::ApplyFuncOp::create(
b, loc, stateFunctions[pa.stateId],
forallQuantified.drop_front(numArgs));

// Produce an implication `F_state(outs, vars, [time]) ->
// assertedVal`
returnVal = smt::ImpliesOp::create(b, loc, inState, toBool);
newOp->erase();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above re: moving check before clone

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, i think this is necessary to maintain the types' consistency when the unrealized conversion casts are created, so I did not do this.

Comment thread lib/Conversion/FSMToSMT/FSMToSMT.cpp Outdated
@TaoBi22 TaoBi22 merged commit 109346b into llvm:main Mar 4, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FSM the FSM dialect SMT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants