CIRCT  20.0.0git
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 
10 #include "circt/Dialect/SV/SVOps.h"
14 #include "mlir/Pass/Pass.h"
15 #include "mlir/Transforms/DialectConversion.h"
16 #include "llvm/ADT/TypeSwitch.h"
17 
18 namespace circt {
19 namespace seq {
20 #define GEN_PASS_DEF_LOWERSEQSHIFTREG
21 #include "circt/Dialect/Seq/SeqPasses.h.inc"
22 } // namespace seq
23 } // namespace circt
24 
25 using namespace circt;
26 using namespace seq;
27 
28 namespace {
29 
30 struct ShiftRegLowering : public OpConversionPattern<seq::ShiftRegOp> {
31 public:
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 
64 struct LowerSeqShiftRegPass
65  : public circt::seq::impl::LowerSeqShiftRegBase<LowerSeqShiftRegPass> {
66  void runOnOperation() override;
67 };
68 
69 } // namespace
70 
71 void 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 
85 std::unique_ptr<Pass> circt::seq::createLowerSeqShiftRegPass() {
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: DebugAnalysis.h:21
Definition: seq.py:1