26#define GEN_PASS_DEF_FOLDASSUMEPASS
27#include "circt/Dialect/Verif/Passes.h.inc"
61struct FoldAssumePass : verif::impl::FoldAssumePassBase<FoldAssumePass> {
64 bool canScheduleOn(RegisteredOperationName opInfo)
const override {
65 return opInfo.getStringRef() == hw::HWModuleOp::getOperationName() ||
66 opInfo.getStringRef() == verif::FormalOp::getOperationName();
69 void runOnOperation()
override;
78 LogicalResult findAssertlikes(
81 Block *blk = defop->getBlock();
84 if (isa<ltl::PropertyType, ltl::SequenceType>(
85 defop->getOperand(0).getType()))
89 if (
auto it = ops.find(blk); it != ops.end())
90 if ((it->getSecond().size() > 0)) {
92 <<
"Multiple " << defop->getName()
93 <<
" found in the current block! Run `--combine-assert-like` "
94 <<
"before running --fold-assume.";
99 ops[blk].push_back(defop);
105 LogicalResult foldAssumesIntoAsserts(OpBuilder &builder) {
107 auto i1 = builder.getI1Type();
110 for (
auto [blk, ops] : assumes) {
118 if (ops.size() > 1) {
119 ops.back()->emitError(
120 "Multiple assuptions found in the current block! Run "
121 "`--combine-assert-like` before running --fold-assume.");
126 auto assumeOp = cast<verif::AssumeOp>(ops.front());
127 Location loc = assumeOp.getLoc();
128 Value cond = assumeOp.getProperty();
131 builder.setInsertionPoint(ops.front());
134 if (
auto it = asserts.find(blk);
135 it != asserts.end() && it->getSecond().size() > 0) {
136 auto const &assertOps = it->getSecond();
140 if (assertOps.size() > 1) {
141 assertOps.back()->emitError(
142 "Multiple assertions found in the current block! Run "
143 "`--combine-assert-like` before running --fold-assume.");
148 auto assertOp = cast<verif::AssertOp>(assertOps.front());
149 builder.setInsertionPoint(assertOps.front());
150 Location assertLoc = assertOp.getLoc();
151 Value
en = assertOp.getEnable();
154 verif::AssertOp::create(
155 builder, assertLoc, assertOp.getProperty(),
157 en ? comb::AndOp::create(builder, assertLoc, en, cond) : cond,
168 verif::AssertOp::create(builder, loc, tConst, cond,
181void FoldAssumePass::runOnOperation() {
182 Operation *
module = getOperation();
183 OpBuilder builder(module);
187 if (!isa<hw::HWModuleOp, verif::FormalOp>(module))
191 WalkResult wr =
module->walk([&](Operation *op) {
192 if (isa<verif::AssumeOp, verif::AssertOp>(op))
194 if (failed(findAssertlikes(op,
195 isa<verif::AssertOp>(op) ? asserts : assumes)))
196 return WalkResult::interrupt();
197 return WalkResult::advance();
201 if (wr.wasInterrupted())
202 return signalPassFailure();
205 if (failed(foldAssumesIntoAsserts(builder)))
206 return signalPassFailure();
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.