16#include "llvm/Support/Debug.h"
17#include "llvm/Support/Format.h"
18#include "llvm/Support/KnownBits.h"
20#define DEBUG_TYPE "datapath-ops"
25LogicalResult CompressOp::verify() {
28 if (getNumOperands() < 3)
29 return emitOpError(
"requires 3 or more arguments - otherwise use add");
31 if (getNumResults() >= getNumOperands())
32 return emitOpError(
"must reduce the number of operands by at least 1");
34 if (getNumResults() < 2)
35 return emitOpError(
"must produce at least 2 results");
43 SmallVectorImpl<Type> &inputTypes,
44 SmallVectorImpl<Type> &resultTypes) {
46 int64_t inputCount, resultCount;
47 Type inputElementType;
49 if (parser.parseType(inputElementType) || parser.parseLSquare() ||
50 parser.parseInteger(inputCount) || parser.parseArrow() ||
51 parser.parseInteger(resultCount) || parser.parseRSquare())
55 inputTypes.assign(inputCount, inputElementType);
56 resultTypes.assign(resultCount, inputElementType);
63 TypeRange inputTypes, TypeRange resultTypes) {
65 printer << inputTypes[0] <<
" [" << inputTypes.size() <<
" -> "
66 << resultTypes.size() <<
"]";
74std::pair<CompressorBit, CompressorBit>
81 auto carryVal = builder.createOrFold<
comb::OrOp>(
89 auto carryDelay = sumDelay + 1;
93 std::pair<CompressorBit, CompressorBit> fa{sum, carry};
99std::pair<CompressorBit, CompressorBit>
105 auto sumDelay = std::max(a.
delay, b.
delay) + 1;
106 auto carryDelay = sumDelay;
110 std::pair<CompressorBit, CompressorBit> ha{sum, carry};
116 const SmallVector<SmallVector<Value>> &addends,
117 Location
loc, OpBuilder &builder)
121 SmallVector<size_t> constantOnes(
width, 0);
125 for (
auto row : addends) {
129 for (
size_t i = 0; i <
width; ++i) {
131 if (knownBit.isZero())
133 if (knownBit.isAllOnes()) {
148 for (
size_t i = 0; i <
width; ++i) {
149 size_t ones = constantOnes[i] + carry;
162 llvm::function_ref<FailureOr<int64_t>(Value)> getDelay) {
164 for (
auto &[value, result] : column) {
165 auto delay = getDelay(value);
176 for (
const auto &column :
columns)
177 maxSize = std::max(maxSize, column.size());
188 size_t m =
static_cast<size_t>(std::floor(1.5 * mPrev));
197 size_t targetHeight) {
198 SmallVector<Value> addend;
199 SmallVector<Value> addends;
201 for (
size_t i = 0; i < targetHeight; ++i) {
208 for (
size_t j = 0; j <
width; ++j) {
210 addend.push_back(
columns[j][i].val);
212 addend.push_back(falseValue);
215 std::reverse(addend.begin(), addend.end());
216 addends.push_back(comb::ConcatOp::create(builder,
loc, addend));
224 size_t targetHeight) {
228 if (maxHeight <= targetHeight)
240 size_t targetHeight) {
249 SmallVector<SmallVector<CompressorBit>> newColumns(
width);
251 for (
size_t i = 0; i <
width; ++i) {
256 col, [](
const auto &a,
const auto &b) {
return a.delay > b.delay; });
258 while (col.size() + newColumns[i].size() > targetStageHeight) {
259 if (col.size() < 2) {
260 llvm::errs() <<
"CompressorTree: Not enough bits in column " << i
261 <<
" to compress further.\n New Columns size: "
262 << newColumns[i].size()
263 <<
", Current Column size: " << col.size() <<
"\n";
264 llvm::report_fatal_error(
265 "Expected at least two bits in compressor column");
268 auto bit0 = col.pop_back_val();
269 auto bit1 = col.pop_back_val();
272 if (col.size() >= 1) {
275 auto targetDelay = std::max(bit0.delay, bit1.delay) + 1;
280 auto *it = llvm::find_if(col, [targetDelay](
const auto &pair) {
281 return pair.delay <= targetDelay;
284 if (it != col.end()) {
289 bit2 = col.pop_back_val();
293 newColumns[i].push_back(sum);
294 if (i + 1 < newColumns.size())
295 newColumns[i + 1].push_back(carry);
300 newColumns[i].push_back(sum);
301 if (i + 1 < newColumns.size())
302 newColumns[i + 1].push_back(carry);
307 newColumns[i].append(col);
311 columns = std::move(newColumns);
318 llvm::dbgs() <<
"Compressor Tree: Height = " <<
getMaxHeight()
324 llvm::dbgs() << std::string(9,
' ');
325 for (
size_t j =
width; j > 0; --j) {
328 llvm::dbgs() << llvm::format(
"%02d", j - 1);
331 << std::string(9,
' ') << std::string(
width * 3,
'-') <<
"\n";
334 llvm::dbgs() <<
" [" << llvm::format(
"%02d", i) <<
"]: [";
335 for (
size_t j =
width; j > 0; --j) {
339 llvm::dbgs() << llvm::format(
345 llvm::dbgs() <<
"]\n";
354#define GET_OP_CLASSES
355#include "circt/Dialect/Datapath/Datapath.cpp.inc"
assert(baseType &&"element must be base type")
static void printCompressFormat(OpAsmPrinter &printer, Operation *op, TypeRange inputTypes, TypeRange resultTypes)
static ParseResult parseCompressFormat(OpAsmParser &parser, SmallVectorImpl< Type > &inputTypes, SmallVectorImpl< Type > &resultTypes)
false return failure()
Parse an optional keyword or string and set instance into 'result'.
size_t getNextStageTargetHeight() const
SmallVector< SmallVector< CompressorBit > > columns
SmallVector< Value > compressToHeight(OpBuilder &builder, size_t targetHeight)
SmallVector< Value > columnsToAddends(OpBuilder &builder, size_t targetHeight)
CompressorTree(size_t width, const SmallVector< SmallVector< Value > > &addends, Location loc, OpBuilder &builder)
LogicalResult withInputDelays(llvm::function_ref< FailureOr< int64_t >(Value)> getDelay)
std::pair< CompressorBit, CompressorBit > halfAdderWithDelay(OpBuilder &builder, CompressorBit a, CompressorBit b)
std::pair< CompressorBit, CompressorBit > fullAdderWithDelay(OpBuilder &builder, CompressorBit a, CompressorBit b, CompressorBit c)
SmallVector< Value > compressUsingTiming(OpBuilder &builder, size_t targetHeight)
size_t getMaxHeight() const
KnownBits computeKnownBits(Value value, unsigned maxDepth=5)
Compute "known bits" information about the specified value - the set of bits that are guaranteed to a...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.