diff --git a/include/circt/Dialect/FSM/FSMOps.td b/include/circt/Dialect/FSM/FSMOps.td index d1dd516cd6..6d52ac4c2c 100644 --- a/include/circt/Dialect/FSM/FSMOps.td +++ b/include/circt/Dialect/FSM/FSMOps.td @@ -222,7 +222,8 @@ def StateOp : FSMOp<"state", [HasParent<"MachineOp">, Symbol, NoTerminator]> { }]; let builders = [ - OpBuilder<(ins "StringRef":$stateName)> + OpBuilder<(ins "StringRef":$stateName)>, + OpBuilder<(ins "StringRef":$stateName, "ValueRange":$outputs)> ]; let skipDefaultBuilders = 1; @@ -301,8 +302,11 @@ def TransitionOp : FSMOp<"transition", [HasParent<"StateOp">, NoTerminator]> { }]; let builders = [ - OpBuilder<(ins "StringRef":$nextState)>, - OpBuilder<(ins "fsm::StateOp":$nextState)> + // OpBuilder<(ins "StringRef":$nextState)>, + OpBuilder<(ins "fsm::StateOp":$nextState)>, + OpBuilder<(ins "StringRef":$nextState, + CArg<"llvm::function_ref", "{}">:$guardCtor, + CArg<"llvm::function_ref", "{}">:$actionCtor)> ]; let skipDefaultBuilders = 1; diff --git a/lib/Dialect/FSM/FSMOps.cpp b/lib/Dialect/FSM/FSMOps.cpp index 0cb42ce4ae..0045d48953 100644 --- a/lib/Dialect/FSM/FSMOps.cpp +++ b/lib/Dialect/FSM/FSMOps.cpp @@ -321,6 +321,18 @@ void StateOp::build(OpBuilder &builder, OperationState &state, state.addAttribute("sym_name", builder.getStringAttr(stateName)); } +void StateOp::build(OpBuilder &builder, OperationState &state, + StringRef stateName, ValueRange outputs) { + OpBuilder::InsertionGuard guard(builder); + Region *output = state.addRegion(); + output->push_back(new Block()); + builder.setInsertionPointToEnd(&output->back()); + builder.create(state.location, outputs); + Region *transitions = state.addRegion(); + transitions->push_back(new Block()); + state.addAttribute("sym_name", builder.getStringAttr(stateName)); +} + SetVector StateOp::getNextStates() { SmallVector nextStates; llvm::transform( @@ -402,16 +414,29 @@ LogicalResult OutputOp::verify() { //===----------------------------------------------------------------------===// void TransitionOp::build(OpBuilder &builder, OperationState &state, - StringRef nextState) { - state.addRegion(); // guard - state.addRegion(); // action - state.addAttribute("nextState", - FlatSymbolRefAttr::get(builder.getStringAttr(nextState))); + StateOp nextState) { + build(builder, state, nextState.getName()); } void TransitionOp::build(OpBuilder &builder, OperationState &state, - StateOp nextState) { - build(builder, state, nextState.getName()); + StringRef nextState, + llvm::function_ref guardCtor, + llvm::function_ref actionCtor) { + state.addAttribute("nextState", + FlatSymbolRefAttr::get(builder.getStringAttr(nextState))); + OpBuilder::InsertionGuard guard(builder); + + Region *guardRegion = state.addRegion(); // guard + if (guardCtor) { + builder.createBlock(guardRegion); + guardCtor(); + } + + Region *actionRegion = state.addRegion(); // action + if (actionCtor) { + builder.createBlock(actionRegion); + actionCtor(); + } } Block *TransitionOp::ensureGuard(OpBuilder &builder) {