71 auto wires = component.getWiresOp();
72 Block *wiresBody = wires.getBodyBlock();
74 auto &seqOps =
seq.getBodyBlock()->getOperations();
75 if (!llvm::all_of(seqOps, [](
auto &&op) {
return isa<EnableOp>(op); })) {
76 seq.emitOpError(
"should only contain EnableOps in this pass.");
84 OpBuilder builder(component->getRegion(0));
87 Value fsmIn = fsmRegister.getIn();
88 Value fsmWriteEn = fsmRegister.getWriteEn();
89 Value fsmOut = fsmRegister.getOut();
91 builder.setInsertionPointToStart(wiresBody);
92 auto oneConstant =
createConstant(wires.getLoc(), builder, component, 1, 1);
95 builder.setInsertionPointToEnd(wiresBody);
97 builder.create<GroupOp>(wires->getLoc(), builder.getStringAttr(
"seq"));
100 auto &symTable =
am.getChildAnalysis<SymbolTable>(wires);
101 symTable.insert(seqGroup);
104 SmallVector<Attribute, 8> compiledGroups;
106 seq.walk([&](EnableOp enable) {
107 StringRef groupName = enable.getGroupName();
108 compiledGroups.push_back(
109 SymbolRefAttr::get(builder.getContext(), groupName));
110 auto groupOp = symTable.lookup<GroupOp>(groupName);
112 builder.setInsertionPoint(groupOp);
113 auto fsmCurrentState =
createConstant(wires->getLoc(), builder, component,
114 fsmBitWidth, fsmIndex);
118 auto guard = groupOp.getDoneOp().getGuard();
119 Value source = groupOp.getDoneOp().getSrc();
120 auto doneOpValue = !guard ? source
122 wires->getLoc(), guard, source,
false);
129 builder.create<comb::ICmpOp>(wires->getLoc(), comb::ICmpPredicate::eq,
130 fsmOut, fsmCurrentState,
false);
131 auto notDone = comb::createOrFoldNot(wires->getLoc(), doneOpValue, builder);
133 builder.create<
comb::AndOp>(wires->getLoc(), eqCmp, notDone,
false);
137 builder.setInsertionPoint(seqGroup);
138 auto groupDoneGuard =
139 builder.create<
comb::AndOp>(wires->getLoc(), eqCmp, doneOpValue,
false);
142 auto goOp = groupOp.getGoOp();
143 assert(goOp &&
"The Go Insertion pass should be run before this.");
144 goOp->setOperands({oneConstant, groupGoGuard});
147 fsmNextState =
createConstant(wires->getLoc(), builder, component,
148 fsmBitWidth, fsmIndex + 1);
149 builder.setInsertionPointToEnd(seqGroup.getBodyBlock());
150 builder.create<AssignOp>(wires->getLoc(), fsmIn, fsmNextState,
152 builder.create<AssignOp>(wires->getLoc(), fsmWriteEn, oneConstant,
160 builder.setInsertionPoint(seqGroup);
161 auto isFinalState = builder.create<comb::ICmpOp>(
162 wires->getLoc(), comb::ICmpPredicate::eq, fsmOut, fsmNextState,
false);
165 builder.setInsertionPointToEnd(seqGroup.getBodyBlock());
166 builder.create<GroupDoneOp>(seqGroup->getLoc(), oneConstant, isFinalState);
170 builder.setInsertionPointToEnd(wiresBody);
172 createConstant(wires->getLoc(), builder, component, fsmBitWidth, 0);
173 builder.create<AssignOp>(wires->getLoc(), fsmIn, zeroConstant, isFinalState);
174 builder.create<AssignOp>(wires->getLoc(), fsmWriteEn, oneConstant,
178 builder.setInsertionPoint(
seq);
179 builder.create<EnableOp>(
180 seq->getLoc(), seqGroup.getSymName(),
181 ArrayAttr::get(builder.getContext(), compiledGroups));