Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/circt/Conversion/CombToAIG.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@

namespace circt {

// FIXME: Rename to CombToSynthTargetIR
enum CombToAIGTargetIR {
// Lower to And-Inverter
AIG,
// Lower to Majority-Inverter
MIG
};

#define GEN_PASS_DECL_CONVERTCOMBTOAIG
#include "circt/Conversion/Passes.h.inc"

Expand Down
13 changes: 11 additions & 2 deletions include/circt/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -779,16 +779,25 @@ def LowerSimToSV: Pass<"lower-sim-to-sv", "mlir::ModuleOp"> {
// ConvertCombToAIG
//===----------------------------------------------------------------------===//

// FIXME: Rename to ConvertCombToSynth
def ConvertCombToAIG: Pass<"convert-comb-to-aig", "hw::HWModuleOp"> {
let summary = "Lower Comb ops to AIG ops.";
let dependentDialects = [
"circt::comb::CombDialect",
"circt::aig::AIGDialect",
"circt::synth::SynthDialect"
];

let options = [
ListOption<"additionalLegalOps", "additional-legal-ops", "std::string",
"Specify additional legal ops to partially legalize Comb to AIG">,
"Specify additional legal ops to partially legalize Comb">,
Option<"targetIR", "target-ir", "circt::CombToAIGTargetIR",
/*default=*/"circt::CombToAIGTargetIR::AIG",
"Target IR kind",
[{::llvm::cl::values(
clEnumValN(circt::CombToAIGTargetIR::AIG, "aig", "Lower to AIG"),
clEnumValN(circt::CombToAIGTargetIR::MIG, "mig", "Lower to MIG")
)}]>,
Option<"maxEmulationUnknownBits", "max-emulation-unknown-bits", "uint32_t", "10",
"Maximum number of unknown bits to emulate in a table lookup">
];
Expand All @@ -797,7 +806,7 @@ def ConvertCombToAIG: Pass<"convert-comb-to-aig", "hw::HWModuleOp"> {
//===----------------------------------------------------------------------===//
// ConvertAIGToComb
//===----------------------------------------------------------------------===//

// FIXME: Rename to ConvertSynthToComb
def ConvertAIGToComb: Pass<"convert-aig-to-comb", "hw::HWModuleOp"> {
let summary = "Lower AIG ops to Comb ops";
let description = [{
Expand Down
1 change: 1 addition & 0 deletions include/circt/Dialect/AIG/AIG.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ include "mlir/IR/DialectBase.td"
def AIG_Dialect : Dialect {
let name = "aig";
let cppNamespace = "::circt::aig";
let dependentDialects = ["::circt::synth::SynthDialect"];
let summary = "Representation of AIGs";
}

Expand Down
13 changes: 13 additions & 0 deletions include/circt/Dialect/AIG/AIGOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,23 @@
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Rewrite/PatternApplicator.h"

#include "circt/Dialect/AIG/AIGDialect.h"

#define GET_OP_CLASSES
#include "circt/Dialect/AIG/AIG.h.inc"

namespace circt {
namespace aig {
struct AndInverterVariadicOpConversion
: mlir::OpRewritePattern<circt::aig::AndInverterOp> {
using OpRewritePattern<circt::aig::AndInverterOp>::OpRewritePattern;
mlir::LogicalResult
matchAndRewrite(circt::aig::AndInverterOp op,
mlir::PatternRewriter &rewriter) const override;
};
} // namespace aig
} // namespace circt

#endif // CIRCT_DIALECT_AIG_AIGOPS_H
18 changes: 14 additions & 4 deletions include/circt/Dialect/Synth/Transforms/SynthesisPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@
namespace circt {
namespace synth {

enum TargetIR {
// Lower to And-Inverter Graph
AIG,
// Lower to Majority-Inverter Graph
MIG
};

/// Options for the aig lowering pipeline.
struct AIGLoweringPipelineOptions
: public mlir::PassPipelineOptions<AIGLoweringPipelineOptions> {
struct CombLoweringPipelineOptions
: public mlir::PassPipelineOptions<CombLoweringPipelineOptions> {
PassOptions::Option<bool> disableDatapath{
*this, "disable-datapath",
llvm::cl::desc("Disable datapath optimization passes"),
Expand All @@ -35,6 +42,9 @@ struct AIGLoweringPipelineOptions
*this, "timing-aware",
llvm::cl::desc("Lower operators in a timing-aware fashion"),
llvm::cl::init(false)};
PassOptions::Option<TargetIR> targetIR{
*this, "lowering-target", llvm::cl::desc("Target IR to lower to"),
llvm::cl::init(TargetIR::AIG)};
};

/// Options for the aig optimization pipeline.
Expand All @@ -61,8 +71,8 @@ struct AIGOptimizationPipelineOptions
//===----------------------------------------------------------------------===//

/// Populate the synthesis pipelines.
void buildAIGLoweringPipeline(mlir::OpPassManager &pm,
const AIGLoweringPipelineOptions &options);
void buildCombLoweringPipeline(mlir::OpPassManager &pm,
const CombLoweringPipelineOptions &options);
void buildAIGOptimizationPipeline(
mlir::OpPassManager &pm, const AIGOptimizationPipelineOptions &options);

Expand Down
2 changes: 1 addition & 1 deletion integration_test/Bindings/Python/dialects/synth.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def build_module(module):

# Check that the synthesis pipeline is registered.
pm = PassManager.parse(
"builtin.module(hw.module(synth-aig-lowering-pipeline, "
"builtin.module(hw.module(synth-comb-lowering-pipeline, "
"synth-aig-optimization-pipeline))")
pm.run(m.operation)
# CHECK: hw.module @foo(
Expand Down
20 changes: 20 additions & 0 deletions integration_test/circt-synth/mig.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: circt-opt %s --pass-pipeline='builtin.module(hw.module(hw-aggregate-to-comb,convert-comb-to-aig{target-ir=mig},convert-aig-to-comb))' -o %t.mlir
// RUN: circt-lec %t.mlir %s -c1=bit_logical -c2=bit_logical --shared-libs=%libz3 | FileCheck %s --check-prefix=COMB_BIT_LOGICAL
// COMB_BIT_LOGICAL: c1 == c2
hw.module @bit_logical(in %arg0: i32, in %arg1: i32, in %arg2: i32, in %arg3: i32,
in %cond: i1, out out0: i32, out out1: i32, out out2: i32, out out3: i32) {
%0 = comb.or %arg0, %arg1, %arg2, %arg3 : i32
%1 = comb.and %arg0, %arg1, %arg2, %arg3 : i32
%2 = comb.xor %arg0, %arg1, %arg2, %arg3 : i32
%3 = comb.mux %cond, %arg0, %arg1 : i32

hw.output %0, %1, %2, %3 : i32, i32, i32, i32
}

// RUN: circt-lec %t.mlir %s -c1=add -c2=add --shared-libs=%libz3 | FileCheck %s --check-prefix=COMB_ADD
// COMB_ADD: c1 == c2
hw.module @add(in %arg0: i4, in %arg1: i4, in %arg2: i4, out add: i4) {
%0 = comb.add %arg0, %arg1, %arg2 : i4
hw.output %0 : i4
}

56 changes: 54 additions & 2 deletions lib/Conversion/AIGToComb/AIGToComb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "circt/Dialect/AIG/AIGOps.h"
#include "circt/Dialect/Comb/CombOps.h"
#include "circt/Dialect/HW/HWOps.h"
#include "circt/Dialect/Synth/SynthDialect.h"
#include "circt/Dialect/Synth/SynthOps.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"

Expand Down Expand Up @@ -53,6 +55,55 @@ struct AIGAndInverterOpConversion : OpConversionPattern<aig::AndInverterOp> {
}
};

struct SynthMajorityInverterOpConversion
: OpConversionPattern<synth::mig::MajorityInverterOp> {
using OpConversionPattern<
synth::mig::MajorityInverterOp>::OpConversionPattern;
LogicalResult
matchAndRewrite(synth::mig::MajorityInverterOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
// Only handle 1 or 3-input majority inverter for now.
if (op.getNumOperands() > 3)
return failure();

auto getOperand = [&](unsigned idx) {
auto input = op.getInputs()[idx];
if (!op.getInverted()[idx])
return input;
auto width = input.getType().getIntOrFloatBitWidth();
auto allOnes = hw::ConstantOp::create(rewriter, op.getLoc(),
APInt::getAllOnes(width));
return rewriter.createOrFold<comb::XorOp>(op.getLoc(), input, allOnes,
true);
};

if (op.getNumOperands() == 1) {
rewriter.replaceOp(op, getOperand(0));
return success();
}

assert(op.getNumOperands() == 3 && "Expected 3 operands for majority op");
SmallVector<Value, 3> inputs;
for (size_t i = 0; i < 3; ++i)
inputs.push_back(getOperand(i));

// MAJ(x, y, z) = x & y | x & z | y & z
auto getProduct = [&](unsigned idx1, unsigned idx2) {
return rewriter.createOrFold<comb::AndOp>(
op.getLoc(), ValueRange{inputs[idx1], inputs[idx2]}, true);
};

SmallVector<Value, 3> operands;
operands.push_back(getProduct(0, 1));
operands.push_back(getProduct(0, 2));
operands.push_back(getProduct(1, 2));

rewriter.replaceOp(
op, rewriter.createOrFold<comb::OrOp>(op.getLoc(), operands, true));
return success();
}
};

} // namespace

//===----------------------------------------------------------------------===//
Expand All @@ -69,13 +120,14 @@ struct ConvertAIGToCombPass
} // namespace

static void populateAIGToCombConversionPatterns(RewritePatternSet &patterns) {
patterns.add<AIGAndInverterOpConversion>(patterns.getContext());
patterns.add<AIGAndInverterOpConversion, SynthMajorityInverterOpConversion>(
patterns.getContext());
}

void ConvertAIGToCombPass::runOnOperation() {
ConversionTarget target(getContext());
target.addLegalDialect<comb::CombDialect, hw::HWDialect>();
target.addIllegalDialect<aig::AIGDialect>();
target.addIllegalDialect<aig::AIGDialect, synth::SynthDialect>();

RewritePatternSet patterns(&getContext());
populateAIGToCombConversionPatterns(patterns);
Expand Down
1 change: 1 addition & 0 deletions lib/Conversion/AIGToComb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_circt_conversion_library(CIRCTAIGToComb
CIRCTAIG
CIRCTHW
CIRCTComb
CIRCTSynth
MLIRIR
MLIRPass
MLIRSupport
Expand Down
1 change: 1 addition & 0 deletions lib/Conversion/CombToAIG/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_circt_conversion_library(CIRCTCombToAIG
CIRCTHW
CIRCTComb
CIRCTAIG
CIRCTSynth
MLIRIR
MLIRPass
MLIRSupport
Expand Down
Loading