13 #include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
14 #include "mlir/Dialect/Arith/IR/Arith.h"
15 #include "mlir/Pass/Pass.h"
16 #include "mlir/Transforms/DialectConversion.h"
17 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
20 #define GEN_PASS_DEF_CONVERTVERIFTOSMT
21 #include "circt/Conversion/Passes.h.inc"
25 using namespace circt;
38 matchAndRewrite(verif::AssertOp op, OpAdaptor adaptor,
39 ConversionPatternRewriter &rewriter)
const override {
40 Value cond = typeConverter->materializeTargetConversion(
42 adaptor.getProperty());
43 rewriter.replaceOpWithNewOp<smt::AssertOp>(op, cond);
53 struct LogicEquivalenceCheckingOpConversion
59 matchAndRewrite(verif::LogicEquivalenceCheckingOp op, OpAdaptor adaptor,
60 ConversionPatternRewriter &rewriter)
const override {
61 Location loc = op.getLoc();
62 auto *firstOutputs = adaptor.getFirstCircuit().front().getTerminator();
63 auto *secondOutputs = adaptor.getSecondCircuit().front().getTerminator();
65 if (firstOutputs->getNumOperands() == 0) {
68 rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(
true));
69 rewriter.replaceOp(op, trueVal);
73 smt::SolverOp solver =
74 rewriter.create<smt::SolverOp>(loc, rewriter.getI1Type(), ValueRange{});
75 rewriter.createBlock(&solver.getBodyRegion());
78 if (failed(rewriter.convertRegionTypes(&adaptor.getFirstCircuit(),
81 if (failed(rewriter.convertRegionTypes(&adaptor.getSecondCircuit(),
87 for (
auto arg : adaptor.getFirstCircuit().getArguments())
88 inputs.push_back(rewriter.create<smt::DeclareFunOp>(loc, arg.getType()));
97 rewriter.mergeBlocks(&adaptor.getFirstCircuit().front(), solver.getBody(),
99 rewriter.mergeBlocks(&adaptor.getSecondCircuit().front(), solver.getBody(),
101 rewriter.setInsertionPointToEnd(solver.getBody());
107 SmallVector<Value> outputsDifferent;
108 for (
auto [out1, out2] :
109 llvm::zip(firstOutputs->getOperands(), secondOutputs->getOperands())) {
110 Value o1 = typeConverter->materializeTargetConversion(
111 rewriter, loc, typeConverter->convertType(out1.getType()), out1);
112 Value o2 = typeConverter->materializeTargetConversion(
113 rewriter, loc, typeConverter->convertType(out1.getType()), out2);
114 outputsDifferent.emplace_back(
115 rewriter.create<smt::DistinctOp>(loc, o1, o2));
118 rewriter.eraseOp(firstOutputs);
119 rewriter.eraseOp(secondOutputs);
122 if (outputsDifferent.size() == 1)
123 toAssert = outputsDifferent[0];
125 toAssert = rewriter.create<smt::OrOp>(loc, outputsDifferent);
127 rewriter.create<smt::AssertOp>(loc, toAssert);
131 rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(
false));
133 rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(
true));
134 auto checkOp = rewriter.create<smt::CheckOp>(loc, rewriter.getI1Type());
135 rewriter.createBlock(&checkOp.getSatRegion());
136 rewriter.create<smt::YieldOp>(loc, falseVal);
137 rewriter.createBlock(&checkOp.getUnknownRegion());
138 rewriter.create<smt::YieldOp>(loc, falseVal);
139 rewriter.createBlock(&checkOp.getUnsatRegion());
140 rewriter.create<smt::YieldOp>(loc, trueVal);
141 rewriter.setInsertionPointAfter(checkOp);
142 rewriter.create<smt::YieldOp>(loc, checkOp->getResults());
144 rewriter.replaceOp(op, solver->getResults());
156 struct ConvertVerifToSMTPass
157 :
public circt::impl::ConvertVerifToSMTBase<ConvertVerifToSMTPass> {
158 void runOnOperation()
override;
164 patterns.add<VerifAssertOpConversion, LogicEquivalenceCheckingOpConversion>(
168 void ConvertVerifToSMTPass::runOnOperation() {
169 ConversionTarget target(getContext());
170 target.addIllegalDialect<verif::VerifDialect>();
171 target.addLegalDialect<smt::SMTDialect, arith::ArithDialect>();
172 target.addLegalOp<UnrealizedConversionCastOp>();
174 RewritePatternSet
patterns(&getContext());
175 TypeConverter converter;
179 if (failed(mlir::applyPartialConversion(getOperation(), target,
181 return signalPassFailure();
193 RewritePatternSet cleanupPatterns(&getContext());
194 populateReconcileUnrealizedCastsPatterns(cleanupPatterns);
196 if (failed(mlir::applyPatternsAndFoldGreedily(getOperation(),
197 std::move(cleanupPatterns))))
198 return signalPassFailure();
llvm::SmallVector< StringAttr > inputs
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void populateVerifToSMTConversionPatterns(TypeConverter &converter, RewritePatternSet &patterns)
Get the Verif to SMT conversion patterns.
void populateHWToSMTTypeConverter(TypeConverter &converter)
Get the HW to SMT type conversions.