CIRCT 23.0.0git
Loading...
Searching...
No Matches
GenericLUTMapper.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a generic LUT mapper pass using the cut-based rewriting
10// framework. It performs technology mapping by converting combinational logic
11// networks into implementations using K-input lookup tables (LUTs).
12//
13//===----------------------------------------------------------------------===//
14
19#include "circt/Support/LLVM.h"
21#include "mlir/IR/Builders.h"
22#include "mlir/Pass/Pass.h"
23#include "llvm/Support/Debug.h"
24
25#define DEBUG_TYPE "synth-generic-lut-mapper"
26
27using namespace circt;
28using namespace circt::synth;
29
30namespace circt {
31namespace synth {
32#define GEN_PASS_DEF_GENERICLUTMAPPER
33#include "circt/Dialect/Synth/Transforms/SynthPasses.h.inc"
34} // namespace synth
35} // namespace circt
36
37//===----------------------------------------------------------------------===//
38// Generic LUT Pattern
39//===----------------------------------------------------------------------===//
40
41/// A generic K-input LUT pattern that can implement any boolean function
42/// with up to K inputs using a lookup table.
44 unsigned k; // Maximum number of inputs for this LUT
45 SmallVector<DelayType, 8> cachedDelays; // Pre-computed unit delays
46
47 GenericLUT(mlir::MLIRContext *context, unsigned k)
49
50 std::optional<MatchResult> match(CutEnumerator &enumerator,
51 const Cut &cut) const override {
52 const auto &network = enumerator.getLogicNetwork();
53 // This pattern can implement any cut with at most k inputs
54 if (cut.getInputSize() > k || cut.getOutputSize(network) != 1)
55 return std::nullopt;
56
57 // Create match result with a reference to cached delays
58 return MatchResult(
59 1.0, ArrayRef<DelayType>(cachedDelays).take_front(cut.getInputSize()));
60 }
61
62 llvm::FailureOr<Operation *> rewrite(mlir::OpBuilder &rewriter,
63 CutEnumerator &enumerator,
64 const Cut &cut) const override {
65 const auto &network = enumerator.getLogicNetwork();
66 // NOTE: Don't use NPN since it's unnecessary.
67 const auto &truthTableOpt = cut.getTruthTable();
68 if (!truthTableOpt)
69 return failure();
70 const auto &truthTable = *truthTableOpt;
71 LLVM_DEBUG({
72 llvm::dbgs() << "Rewriting cut with " << cut.getInputSize()
73 << " inputs and " << cut.getInputSize()
74 << " operations to a generic LUT with " << k << " inputs.\n";
75 cut.dump(llvm::dbgs(), network);
76 llvm::dbgs() << "Truth table details:\n";
77 truthTable.dump(llvm::dbgs());
78 });
79
80 SmallVector<bool> lutTable;
81 // Convert the truth table to a LUT table
82 for (uint32_t i = 0; i < truthTable.table.getBitWidth(); ++i)
83 lutTable.push_back(truthTable.table[i]);
84
85 // Reverse the inputs to match the LUT input order
86 SmallVector<Value> lutInputs;
87 lutInputs.reserve(cut.inputs.size());
88 for (auto i : llvm::reverse(cut.inputs))
89 lutInputs.push_back(network.getValue(i));
90
91 auto *rootOp = network.getGate(cut.getRootIndex()).getOperation();
92 assert(rootOp && "cut root must be a valid operation");
93
94 // Generate comb.truth table operation.
95 auto truthTableOp = comb::TruthTableOp::create(rewriter, rootOp->getLoc(),
96 lutInputs, lutTable);
97
98 // Replace the root operation with the truth table operation
99 return truthTableOp.getOperation();
100 }
101
102 unsigned getNumOutputs() const override { return 1; }
103
104 StringRef getPatternName() const override { return "GenericLUT"; }
105};
106
107//===----------------------------------------------------------------------===//
108// Generic LUT Mapper Pass
109//===----------------------------------------------------------------------===//
110
112 : public impl::GenericLutMapperBase<GenericLUTMapperPass> {
113 using GenericLutMapperBase<GenericLUTMapperPass>::GenericLutMapperBase;
114
115 void runOnOperation() override {
116 auto module = getOperation();
117 // Create the cut rewriter options
118 CutRewriterOptions options;
119 options.strategy = strategy;
120 options.maxCutInputSize = maxLutSize;
121 options.maxCutSizePerRoot = maxCutsPerRoot;
122 options.allowNoMatch = false;
123 options.attachDebugTiming = test;
124
125 // Create the pattern for generic K-LUT
126 SmallVector<std::unique_ptr<CutRewritePattern>, 4> patterns;
127 patterns.push_back(
128 std::make_unique<GenericLUT>(module->getContext(), maxLutSize));
129
130 // Create the pattern set
131 CutRewritePatternSet patternSet(std::move(patterns));
132
133 // Create the cut rewriter
134 CutRewriter rewriter(options, patternSet);
135
136 // Apply the rewriting
137 if (failed(rewriter.run(module)))
138 return signalPassFailure();
139 }
140};
assert(baseType &&"element must be base type")
Strategy strategy
Cut enumeration engine for combinational logic networks.
const LogicNetwork & getLogicNetwork() const
Get the logic network (read-only).
Manages a collection of rewriting patterns for combinational logic optimization.
Main cut-based rewriting algorithm for combinational logic optimization.
LogicalResult run(Operation *topOp)
Execute the complete cut-based rewriting algorithm.
Represents a cut in the combinational logic network.
void dump(llvm::raw_ostream &os, const LogicNetwork &network) const
unsigned getOutputSize(const LogicNetwork &network) const
Get the number of outputs from root operation.
const std::optional< BinaryTruthTable > & getTruthTable() const
Get the truth table for this cut.
uint32_t getRootIndex() const
Get the root index in the LogicNetwork.
llvm::SmallVector< uint32_t, 6 > inputs
External inputs to this cut (cut boundary).
unsigned getInputSize() const
Get the number of inputs to this cut.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition synth.py:1
void runOnOperation() override
A generic K-input LUT pattern that can implement any boolean function with up to K inputs using a loo...
std::optional< MatchResult > match(CutEnumerator &enumerator, const Cut &cut) const override
Check if a cut matches this pattern and compute area/delay metrics.
unsigned getNumOutputs() const override
Get the number of outputs this pattern produces.
SmallVector< DelayType, 8 > cachedDelays
StringRef getPatternName() const override
Get the name of this pattern. Used for debugging.
llvm::FailureOr< Operation * > rewrite(mlir::OpBuilder &rewriter, CutEnumerator &enumerator, const Cut &cut) const override
Return a new operation that replaces the matched cut.
GenericLUT(mlir::MLIRContext *context, unsigned k)
Base class for cut rewriting patterns used in combinational logic optimization.
mlir::MLIRContext * context
Configuration options for the cut-based rewriting algorithm.
unsigned maxCutInputSize
Maximum number of inputs allowed for any cut.
unsigned maxCutSizePerRoot
Maximum number of cuts to maintain per logic node.
bool allowNoMatch
Fail if there is a root operation that has no matching pattern.
bool attachDebugTiming
Put arrival times to rewritten operations.
OptimizationStrategy strategy
Optimization strategy (area vs. timing).
Result of matching a cut against a pattern.