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 GroupOp::create(builder, 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
121 : comb::AndOp::create(builder, wires->getLoc(),
122 guard, source,
false);
129 comb::ICmpOp::create(builder, wires->getLoc(), comb::ICmpPredicate::eq,
130 fsmOut, fsmCurrentState,
false);
131 auto notDone = comb::createOrFoldNot(wires->getLoc(), doneOpValue, builder);
133 comb::AndOp::create(builder, wires->getLoc(), eqCmp, notDone,
false);
137 builder.setInsertionPoint(seqGroup);
138 auto groupDoneGuard = comb::AndOp::create(builder, wires->getLoc(), eqCmp,
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 AssignOp::create(builder, wires->getLoc(), fsmIn, fsmNextState,
152 AssignOp::create(builder, wires->getLoc(), fsmWriteEn, oneConstant,
160 builder.setInsertionPoint(seqGroup);
162 comb::ICmpOp::create(builder, wires->getLoc(), comb::ICmpPredicate::eq,
163 fsmOut, fsmNextState,
false);
166 builder.setInsertionPointToEnd(seqGroup.getBodyBlock());
167 GroupDoneOp::create(builder, seqGroup->getLoc(), oneConstant, isFinalState);
171 builder.setInsertionPointToEnd(wiresBody);
173 createConstant(wires->getLoc(), builder, component, fsmBitWidth, 0);
174 AssignOp::create(builder, wires->getLoc(), fsmIn, zeroConstant, isFinalState);
175 AssignOp::create(builder, wires->getLoc(), fsmWriteEn, oneConstant,
179 builder.setInsertionPoint(
seq);
180 EnableOp::create(builder,
seq->getLoc(), seqGroup.getSymName(),
181 ArrayAttr::get(builder.getContext(), compiledGroups));