mirror of https://github.com/llvm/circt.git
[FSMToSV] Fix bug of operations not being cloned in transition region (#8753)
Co-authored-by: Atticus Kuhn <atticusmkuhn@gmail.com>
This commit is contained in:
parent
7775fb9ee9
commit
888e6787e4
|
@ -665,8 +665,18 @@ MachineOpConverter::convertState(StateOp state) {
|
|||
res.outputs = outputOp.getOperands(); // 3.2
|
||||
}
|
||||
|
||||
auto transitions = llvm::SmallVector<TransitionOp>(
|
||||
state.getTransitions().getOps<TransitionOp>());
|
||||
SmallVector<TransitionOp> transitions;
|
||||
for (auto &op : state.getTransitions().getOps()) {
|
||||
if (auto transOp = dyn_cast<TransitionOp>(op)) {
|
||||
transitions.push_back(transOp);
|
||||
} else {
|
||||
// Clone operations which are inside `transitions` region but outside
|
||||
// `guard` region.
|
||||
auto opClone = b.clone(op);
|
||||
for (auto [i, res] : llvm::enumerate(op.getResults()))
|
||||
res.replaceAllUsesWith(opClone->getResult(i));
|
||||
}
|
||||
}
|
||||
// 3.3, 3.4) Convert the transitions and record the next-state value
|
||||
// derived from the transitions being selected in a priority-encoded manner.
|
||||
auto nextStateRes = convertTransitions(state, transitions);
|
||||
|
|
|
@ -191,3 +191,38 @@ module {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----
|
||||
|
||||
// Test the usage of operations defined inside `transition` region but outside `guard region`
|
||||
// CHECK-LABEL: hw.module @OpsInTransition(in %clk : !seq.clock, in %rst : i1) attributes {emit.fragments = [@FSM_ENUM_TYPEDEFS]} {
|
||||
// CHECK: sv.alwayscomb {
|
||||
// CHECK-NEXT: sv.case %[[R:.*]] : !hw.typealias<@fsm_enum_typedecls::@OpsInTransition_state_t, !hw.enum<State1, State2>>
|
||||
// CHECK-NEXT: case State1: {
|
||||
// CHECK-NEXT: sv.bpassign %[[STATE_NEXT:.*]], %[[B:.*]] : !hw.typealias<@fsm_enum_typedecls::@OpsInTransition_state_t, !hw.enum<State1, State2>>
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: case State2: {
|
||||
// CHECK-NEXT: sv.bpassign %[[STATE_NEXT:.*]], %[[A:.*]] : !hw.typealias<@fsm_enum_typedecls::@OpsInTransition_state_t, !hw.enum<State1, State2>>
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: default: {
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: hw.output
|
||||
// CHECK-NEXT: }
|
||||
|
||||
module {
|
||||
fsm.machine @OpsInTransition() -> () attributes {initialState = "State1"} {
|
||||
fsm.state @State1 output {
|
||||
fsm.output
|
||||
} transitions {
|
||||
%false = hw.constant false
|
||||
fsm.transition @State1 guard {
|
||||
fsm.return %false
|
||||
}
|
||||
}
|
||||
fsm.state @State2 output {
|
||||
fsm.output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue