12 #include "mlir/Dialect/Func/IR/FuncOps.h"
13 #include "mlir/Pass/Pass.h"
14 #include "mlir/Transforms/DialectConversion.h"
15 #include "mlir/Transforms/TopologicalSortUtils.h"
18 #define GEN_PASS_DEF_CONVERTHWTOSMT
19 #include "circt/Conversion/Passes.h.inc"
22 using namespace circt;
35 matchAndRewrite(
ConstantOp op, OpAdaptor adaptor,
36 ConversionPatternRewriter &rewriter)
const override {
37 rewriter.replaceOpWithNewOp<smt::BVConstantOp>(op, adaptor.getValue());
47 matchAndRewrite(
HWModuleOp op, OpAdaptor adaptor,
48 ConversionPatternRewriter &rewriter)
const override {
49 auto funcTy = op.getModuleType().getFuncType();
50 SmallVector<Type> inputTypes, resultTypes;
51 if (failed(typeConverter->convertTypes(funcTy.getInputs(), inputTypes)))
53 if (failed(typeConverter->convertTypes(funcTy.getResults(), resultTypes)))
55 if (failed(rewriter.convertRegionTypes(&op.getBody(), *typeConverter)))
57 auto funcOp = rewriter.create<mlir::func::FuncOp>(
58 op.getLoc(), adaptor.getSymNameAttr(),
59 rewriter.getFunctionType(inputTypes, resultTypes));
60 rewriter.inlineRegionBefore(op.getBody(), funcOp.getBody(), funcOp.end());
71 matchAndRewrite(OutputOp op, OpAdaptor adaptor,
72 ConversionPatternRewriter &rewriter)
const override {
73 rewriter.replaceOpWithNewOp<mlir::func::ReturnOp>(op, adaptor.getOutputs());
83 matchAndRewrite(InstanceOp op, OpAdaptor adaptor,
84 ConversionPatternRewriter &rewriter)
const override {
85 SmallVector<Type> resultTypes;
86 if (failed(typeConverter->convertTypes(op->getResultTypes(), resultTypes)))
89 rewriter.replaceOpWithNewOp<mlir::func::CallOp>(
90 op, adaptor.getModuleNameAttr(), resultTypes, adaptor.getInputs());
102 struct ConvertHWToSMTPass
103 :
public impl::ConvertHWToSMTBase<ConvertHWToSMTPass> {
104 void runOnOperation()
override;
116 converter.addConversion([](IntegerType type) -> std::optional<Type> {
117 if (type.getWidth() <= 0)
124 converter.addTargetMaterialization([&](OpBuilder &
builder, Type resultType,
126 Location loc) -> std::optional<Value> {
128 .create<mlir::UnrealizedConversionCastOp>(loc, resultType,
inputs)
133 converter.addTargetMaterialization(
134 [&](OpBuilder &
builder, smt::BitVectorType resultType, ValueRange
inputs,
135 Location loc) -> std::optional<Value> {
139 if (!isa<smt::BoolType>(
inputs[0].getType()))
142 unsigned width = resultType.getWidth();
143 Value constZero =
builder.create<smt::BVConstantOp>(loc, 0,
width);
144 Value constOne =
builder.create<smt::BVConstantOp>(loc, 1,
width);
145 return builder.create<smt::IteOp>(loc,
inputs[0], constOne, constZero);
149 converter.addTargetMaterialization(
150 [&](OpBuilder &
builder, smt::BoolType resultType, ValueRange
inputs,
151 Location loc) -> std::optional<Value> {
155 auto bvType = dyn_cast<smt::BitVectorType>(
inputs[0].getType());
156 if (!bvType || bvType.getWidth() != 1)
159 Value constOne =
builder.create<smt::BVConstantOp>(loc, 1, 1);
165 converter.addSourceMaterialization([&](OpBuilder &
builder, Type resultType,
167 Location loc) -> std::optional<Value> {
169 .create<mlir::UnrealizedConversionCastOp>(loc, resultType,
inputs)
176 patterns.add<HWConstantOpConversion, HWModuleOpConversion, OutputOpConversion,
177 InstanceOpConversion>(converter,
patterns.getContext());
180 void ConvertHWToSMTPass::runOnOperation() {
181 ConversionTarget target(getContext());
182 target.addIllegalDialect<hw::HWDialect>();
183 target.addLegalDialect<smt::SMTDialect>();
184 target.addLegalDialect<mlir::func::FuncDialect>();
186 RewritePatternSet
patterns(&getContext());
187 TypeConverter converter;
191 if (failed(mlir::applyPartialConversion(getOperation(), target,
193 return signalPassFailure();
198 for (
auto func : getOperation().getOps<mlir::func::FuncOp>()) {
201 if (func.getBody().getBlocks().size() != 1)
204 mlir::sortTopologically(&func.getBody().front());
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 populateHWToSMTConversionPatterns(TypeConverter &converter, RewritePatternSet &patterns)
Get the HW to SMT conversion patterns.
void populateHWToSMTTypeConverter(TypeConverter &converter)
Get the HW to SMT type conversions.