18#include "mlir/Pass/Pass.h"
19#include "mlir/Transforms/DialectConversion.h"
22#define GEN_PASS_DEF_CONVERTSYNTHTOCOMB
23#include "circt/Conversion/Passes.h.inc"
38 matchAndRewrite(synth::ChoiceOp op, OpAdaptor adaptor,
39 ConversionPatternRewriter &rewriter)
const override {
41 rewriter.replaceOp(op, adaptor.getInputs().front());
46struct SynthAndInverterOpConversion
50 matchAndRewrite(synth::aig::AndInverterOp op, OpAdaptor adaptor,
51 ConversionPatternRewriter &rewriter)
const override {
53 auto width = op.getResult().getType().getIntOrFloatBitWidth();
56 SmallVector<Value> operands;
57 operands.reserve(op.getNumOperands());
58 for (
auto [input, inverted] :
llvm::zip(op.getOperands(), op.getInverted()))
59 operands.push_back(inverted ? rewriter.createOrFold<
comb::
XorOp>(
60 op.
getLoc(), input, allOnes, true)
64 op, rewriter.createOrFold<
comb::AndOp>(op.getLoc(), operands,
true));
69struct SynthMajorityInverterOpConversion
74 matchAndRewrite(synth::mig::MajorityInverterOp op, OpAdaptor adaptor,
75 ConversionPatternRewriter &rewriter)
const override {
77 if (op.getNumOperands() > 3)
80 auto getOperand = [&](
unsigned idx) {
81 auto input = op.getInputs()[idx];
82 if (!op.getInverted()[idx])
84 auto width = input.getType().getIntOrFloatBitWidth();
86 APInt::getAllOnes(width));
87 return rewriter.createOrFold<
comb::XorOp>(op.getLoc(), input, allOnes,
91 if (op.getNumOperands() == 1) {
92 rewriter.replaceOp(op, getOperand(0));
96 assert(op.getNumOperands() == 3 &&
"Expected 3 operands for majority op");
97 SmallVector<Value, 3> inputs;
98 for (
size_t i = 0; i < 3; ++i)
99 inputs.push_back(getOperand(i));
102 auto getProduct = [&](
unsigned idx1,
unsigned idx2) {
104 op.getLoc(), ValueRange{inputs[idx1], inputs[idx2]},
true);
107 SmallVector<Value, 3> operands;
108 operands.push_back(getProduct(0, 1));
109 operands.push_back(getProduct(0, 2));
110 operands.push_back(getProduct(1, 2));
113 op, rewriter.createOrFold<
comb::OrOp>(op.getLoc(), operands,
true));
125struct ConvertSynthToCombPass
126 :
public impl::ConvertSynthToCombBase<ConvertSynthToCombPass> {
128 void runOnOperation()
override;
129 using ConvertSynthToCombBase<ConvertSynthToCombPass>::ConvertSynthToCombBase;
134 patterns.add<SynthChoiceOpConversion, SynthAndInverterOpConversion,
135 SynthMajorityInverterOpConversion>(
patterns.getContext());
138void ConvertSynthToCombPass::runOnOperation() {
139 ConversionTarget target(getContext());
140 target.addLegalDialect<comb::CombDialect, hw::HWDialect>();
141 target.addIllegalDialect<synth::SynthDialect>();
143 RewritePatternSet
patterns(&getContext());
146 if (failed(mlir::applyPartialConversion(getOperation(), target,
148 return signalPassFailure();
assert(baseType &&"element must be base type")
static Location getLoc(DefSlot slot)
static void populateSynthToCombConversionPatterns(RewritePatternSet &patterns)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.