48 llvm::dbgs() <<
"==----- Running SFCCompat "
49 "---------------------------------------------------===\n"
50 <<
"Module: '" << getOperation().getName() <<
"'\n";);
52 bool madeModifications =
false;
53 SmallVector<InvalidValueOp> invalidOps;
56 auto isFullResetAnno = [fullResetAttr](
Annotation anno) {
57 auto annoClassAttr = anno.getClassAttr();
58 return annoClassAttr == fullResetAttr;
62 [&](
unsigned argNum,
Annotation anno) {
return isFullResetAnno(anno); });
63 getOperation()->walk([isFullResetAnno, &fullResetExists](Operation *op) {
66 madeModifications |= fullResetExists;
68 auto result = getOperation()->walk([&](Operation *op) {
70 if (
auto inv = dyn_cast<InvalidValueOp>(op)) {
71 invalidOps.push_back(inv);
72 return WalkResult::advance();
74 auto reg = dyn_cast<RegResetOp>(op);
76 return WalkResult::advance();
80 if (!fullResetExists &&
walkDrivers(reg.getResetValue(),
true,
true,
false,
82 return src.isa<InvalidValueOp>();
84 ImplicitLocOpBuilder builder(reg.getLoc(), reg);
85 RegOp newReg = builder.create<RegOp>(
86 reg.getResult().getType(), reg.getClockVal(), reg.getNameAttr(),
87 reg.getNameKindAttr(), reg.getAnnotationsAttr(),
88 reg.getInnerSymAttr(), reg.getForceableAttr());
89 reg.replaceAllUsesWith(newReg);
91 madeModifications =
true;
92 return WalkResult::advance();
98 if (!isa<AsyncResetType>(reg.getResetSignal().getType()))
99 return WalkResult::advance();
101 reg.getResetValue(),
true,
true,
true,
103 if (src.isa<ConstantOp, InvalidValueOp, SpecialConstantOp,
104 AggregateConstantOp>())
106 auto diag = emitError(reg.getLoc());
107 auto [fieldName, rootKnown] = getFieldName(dst);
108 diag <<
"register " << reg.getNameAttr()
109 <<
" has an async reset, but its reset value";
111 diag <<
" \"" << fieldName <<
"\"";
112 diag <<
" is not driven with a constant value through wires, "
113 "nodes, or connects";
114 std::tie(fieldName, rootKnown) = getFieldName(src);
115 diag.attachNote(src.getLoc())
116 <<
"reset driver is "
117 << (rootKnown ? (
"\"" + fieldName +
"\"") :
"here");
120 return WalkResult::advance();
121 return WalkResult::interrupt();
124 if (result.wasInterrupted())
125 return signalPassFailure();
128 for (
auto inv : invalidOps) {
130 if (inv->getUses().empty()) {
132 madeModifications =
true;
135 ImplicitLocOpBuilder builder(inv.getLoc(), inv);
138 .
Case<ClockType, AsyncResetType, ResetType>(
139 [&](
auto type) -> Value {
140 return builder.create<SpecialConstantOp>(
141 type, builder.getBoolAttr(
false));
143 .Case<IntType>([&](
IntType type) -> Value {
146 .Case<BundleType, FVectorType>([&](
auto type) -> Value {
148 assert(width &&
"width must be inferred");
149 auto zero = builder.create<ConstantOp>(APSInt(*width));
150 return builder.create<BitCastOp>(type, zero);
153 llvm_unreachable(
"all types are supported");
156 inv.replaceAllUsesWith(replacement);
158 madeModifications =
true;
161 if (!madeModifications)
162 return markAllAnalysesPreserved();