-
Notifications
You must be signed in to change notification settings - Fork 415
[FSM] Lower FSM to SMT dialect
#9379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
8cdbd54 to
611c6cd
Compare
| fsm.transition @S0 | ||
| } | ||
| } | ||
| } No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: missing EOF newline
| // CHECK-NEXT: } | ||
|
|
||
|
|
||
| module @fsm_with_time { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this FSM have specific characteristics to make it suitable for the timed test? If not then you could do this in basic.mlir with a --check-prefix (like in
circt/test/arcilator/arcilator.mlir
Line 4 in f5a6e91
| hw.module @Top(in %clock : !seq.clock, in %i0 : i4, in %i1 : i4, out out : i4) { |
| // CHECK-NEXT: %c0_i8 = hw.constant 0 : i8 | ||
| // CHECK-NEXT: %c50_i8 = hw.constant 50 : i8 | ||
| // CHECK-NEXT: %c50_i32 = hw.constant 50 : i32 | ||
| // CHECK-NEXT: %c1_i32 = hw.constant 1 : i32 | ||
| // CHECK-NEXT: %true = hw.constant true | ||
| // CHECK-NEXT: %F_S0 = smt.declare_fun "F_S0" : !smt.func<(!smt.bv<8>, !smt.bv<32>) !smt.bool> | ||
| // CHECK-NEXT: %F_S1 = smt.declare_fun "F_S1" : !smt.func<(!smt.bv<8>, !smt.bv<32>) !smt.bool> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could these SSA values be matched as FileCheck variables instead of using raw names? (It's a bit more stable if the naming changes for some reason)
| // Read options from the generated base | ||
| LoweringConfig cfg; | ||
| cfg.withTime = withTime; // default false | ||
| cfg.timeWidth = 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth making this a pass option?
| SmallVector<std::string> &states, Location &loc) { | ||
| std::string nextState = t.getNextState().str(); | ||
| Transition tr = {from, insertStates(states, nextState)}; | ||
| if (!t.getGuard().empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (!t.getGuard().empty()) { | |
| if (t.hasGuard()) { |
| } | ||
| } else { | ||
| // Ignore assertions in action regions | ||
| mlir::emitWarning(loc, "Assertions in action regions are ignored."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
| mlir::emitWarning(loc, "Assertions in action regions are ignored."); | |
| newOp->emitWarning("Assertions in action regions are ignored."); |
| if (!isa<verif::AssertOp>(newOp)) { | ||
| // Retrieve the guard value | ||
| if (isa<fsm::ReturnOp>(newOp)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
| } else { | ||
| // Ignore assertions in guard regions | ||
|
|
||
| mlir::emitWarning(loc, "Assertions in guard regions are ignored."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above
| if (!isa<verif::AssertOp>(newOp)) { | ||
|
|
||
| // Retrieve all the operands of the output operation | ||
| if (isa<fsm::OutputOp>(newOp)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
| if (!isa<fsm::OutputOp>(op) && !isa<fsm::UpdateOp>(op) && | ||
| !isa<fsm::ReturnOp>(op)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just do
| if (!isa<fsm::OutputOp>(op) && !isa<fsm::UpdateOp>(op) && | |
| !isa<fsm::ReturnOp>(op)) { | |
| if (!isa<fsm::OutputOp, fsm::UpdateOp, fsm::ReturnOp>(op)) { |
This PR lowers the FSM dialect into SMT-LIB assertions.
We represent a transition
s0 -> s1as a Constrained Horn Clause (CHC), i.e., as an implication.