CIRCT 20.0.0git
Loading...
Searching...
No Matches
LowerSeqShiftReg.cpp
Go to the documentation of this file.
1//===- LowerSeqShiftReg.cpp - seq.shiftreg lowering -----------------------===//
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
14#include "mlir/Pass/Pass.h"
15#include "mlir/Transforms/DialectConversion.h"
16#include "llvm/ADT/TypeSwitch.h"
17
18namespace circt {
19namespace seq {
20#define GEN_PASS_DEF_LOWERSEQSHIFTREG
21#include "circt/Dialect/Seq/SeqPasses.h.inc"
22} // namespace seq
23} // namespace circt
24
25using namespace circt;
26using namespace seq;
27
28namespace {
29
30struct ShiftRegLowering : public OpConversionPattern<seq::ShiftRegOp> {
31public:
32 using OpConversionPattern::OpConversionPattern;
33
34 LogicalResult
35 matchAndRewrite(seq::ShiftRegOp op, OpAdaptor adaptor,
36 ConversionPatternRewriter &rewriter) const final {
37 Value in = adaptor.getInput();
38 auto baseName = op.getName();
39 Value init = {};
40 if (auto powerOn = adaptor.getPowerOnValue()) {
41 if (auto op = powerOn.getDefiningOp()) {
42 if (op->hasTrait<mlir::OpTrait::ConstantLike>())
43 init = createConstantInitialValue(rewriter, op);
44 }
45
46 if (!init)
47 return op->emitError() << "non-constant initial value is not supported";
48 }
49
50 for (size_t i = 0; i < op.getNumElements(); ++i) {
51 StringAttr name;
52 if (baseName.has_value())
53 name = rewriter.getStringAttr(baseName.value() + "_sh" + Twine(i + 1));
54 in = rewriter.create<seq::CompRegClockEnabledOp>(
55 op.getLoc(), in, adaptor.getClk(), adaptor.getClockEnable(),
56 adaptor.getReset(), adaptor.getResetValue(), name, init);
57 }
58
59 rewriter.replaceOp(op, in);
60 return success();
61 }
62};
63
64struct LowerSeqShiftRegPass
65 : public circt::seq::impl::LowerSeqShiftRegBase<LowerSeqShiftRegPass> {
66 void runOnOperation() override;
67};
68
69} // namespace
70
71void LowerSeqShiftRegPass::runOnOperation() {
72 MLIRContext &ctxt = getContext();
73 ConversionTarget target(ctxt);
74
75 target.addIllegalOp<seq::ShiftRegOp>();
76 target.addLegalDialect<seq::SeqDialect, hw::HWDialect>();
77 RewritePatternSet patterns(&ctxt);
78 patterns.add<ShiftRegLowering>(&ctxt);
79
80 if (failed(
81 applyPartialConversion(getOperation(), target, std::move(patterns))))
82 signalPassFailure();
83}
84
86 return std::make_unique<LowerSeqShiftRegPass>();
87}
mlir::TypedValue< seq::ImmutableType > createConstantInitialValue(OpBuilder builder, Location loc, mlir::IntegerAttr attr)
Definition SeqOps.cpp:1065
std::unique_ptr< mlir::Pass > createLowerSeqShiftRegPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition seq.py:1