26#define GEN_PASS_DEF_COMBINEASSERTLIKEPASS
27#include "circt/Dialect/Verif/Passes.h.inc"
57struct CombineAssertLikePass
58 : verif::impl::CombineAssertLikePassBase<CombineAssertLikePass> {
61 bool canScheduleOn(RegisteredOperationName opInfo)
const override {
62 return opInfo.getStringRef() == hw::HWModuleOp::getOperationName() ||
63 opInfo.getStringRef() == verif::FormalOp::getOperationName();
65 void runOnOperation()
override;
85 LogicalResult accumulateCondition(
90 auto condition = op.getProperty();
91 auto defop = op.getOperation();
92 Block *parent = defop->getBlock();
95 if (!isa<ltl::PropertyType, ltl::SequenceType>(condition.getType())) {
98 auto enable = op.getEnable();
104 builder.setInsertionPoint(defop);
107 comb::AndOp::create(builder, defop->getLoc(), condition, enable);
110 conds[parent].push_back(andop);
113 conds[parent].push_back(condition);
117 opsToErase[parent].push_back(defop);
124 template <
typename AT>
125 LogicalResult conjoinConditions(Operation *assertlike,
126 llvm::SmallVectorImpl<Value> &conds,
127 OpBuilder &builder) {
134 builder.setInsertionPointAfter(assertlike);
137 auto andop = comb::AndOp::create(builder, assertlike->getLoc(), conds,
141 AT::create(builder, andop.getLoc(), andop,
nullptr,
149 template <
typename AT>
150 LogicalResult conjoinAndErase(
153 OpBuilder &builder) {
155 for (
auto [parent, ops] : opsToErase) {
157 if (ops.size() > 1) {
159 if (
auto it = conds.find(parent); it != conds.end())
161 if (failed(conjoinConditions<AT>(ops.back(), conds[parent], builder)))
174void CombineAssertLikePass::runOnOperation() {
175 Operation *
module = getOperation();
176 OpBuilder builder(module);
181 module->walk([&](Operation *op) {
183 if (auto aop = dyn_cast<verif::AssertOp>(op))
184 if (failed(accumulateCondition(aop, assertConditions, assertsToErase,
186 return signalPassFailure();
187 if (
auto aop = dyn_cast<verif::AssumeOp>(op))
188 if (failed(accumulateCondition(aop, assumeConditions, assumesToErase,
190 return signalPassFailure();
195 if (failed(conjoinAndErase<verif::AssertOp>(assertConditions, assertsToErase,
197 return signalPassFailure();
200 if (failed(conjoinAndErase<verif::AssumeOp>(assumeConditions, assumesToErase,
202 return signalPassFailure();
205 assertConditions.clear();
206 assumeConditions.clear();
207 assertsToErase.clear();
208 assumesToErase.clear();
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.