13 #include "../PassDetails.h"
20 #include "mlir/Transforms/DialectConversion.h"
22 using namespace circt;
33 using OpConversionPattern::OpConversionPattern;
36 matchAndRewrite(ChannelBufferOp buffer, OpAdaptor adaptor,
37 ConversionPatternRewriter &rewriter)
const final;
41 LogicalResult ChannelBufferLowering::matchAndRewrite(
42 ChannelBufferOp buffer, OpAdaptor adaptor,
43 ConversionPatternRewriter &rewriter)
const {
44 auto loc = buffer.getLoc();
46 auto type = buffer.getType();
49 auto stages = buffer.getStagesAttr();
50 uint64_t numStages = 1;
53 numStages = stages.getValue().getLimitedValue();
55 Value input = buffer.getInput();
56 StringAttr bufferName = buffer.getNameAttr();
57 for (uint64_t i = 0; i < numStages; ++i) {
59 auto stage = rewriter.create<PipelineStageOp>(loc, type, buffer.getClk(),
60 buffer.getRst(), input);
62 SmallString<64> stageName(
63 {bufferName.getValue(),
"_stage", std::to_string(i)});
64 stage->setAttr(
"name",
StringAttr::get(rewriter.getContext(), stageName));
70 rewriter.replaceOp(buffer, input);
78 using OpConversionPattern::OpConversionPattern;
81 matchAndRewrite(ESIPureModuleOp pureMod, OpAdaptor adaptor,
82 ConversionPatternRewriter &rewriter)
const final;
87 PureModuleLowering::matchAndRewrite(ESIPureModuleOp pureMod, OpAdaptor adaptor,
88 ConversionPatternRewriter &rewriter)
const {
89 auto loc = pureMod.getLoc();
90 Block *body = &pureMod.getBody().front();
94 DenseMap<StringAttr, ESIPureModuleInputOp> inputPortNames;
96 SmallVector<hw::PortInfo> ports;
98 SmallVector<ESIPureModuleInputOp>
inputs;
99 SmallVector<ESIPureModuleOutputOp>
outputs;
100 SmallVector<Attribute> params;
102 for (Operation &op : llvm::make_early_inc_range(body->getOperations())) {
103 if (
auto port = dyn_cast<ESIPureModuleInputOp>(op)) {
107 auto existingPort = inputPortNames.find(port.getNameAttr());
108 if (existingPort != inputPortNames.end()) {
109 rewriter.replaceAllUsesWith(port.getResult(),
110 existingPort->getSecond().getResult());
111 rewriter.eraseOp(port);
116 hw::PortInfo{{port.getNameAttr(), port.getResult().getType(),
122 }
else if (
auto port = dyn_cast<ESIPureModuleOutputOp>(op)) {
124 hw::PortInfo{{port.getNameAttr(), port.getValue().getType(),
130 }
else if (
auto param = dyn_cast<ESIPureModuleParamOp>(op)) {
133 rewriter.eraseOp(param);
139 loc, pureMod.getNameAttr(), ports,
ArrayAttr::get(getContext(), params));
140 hwMod->setDialectAttrs(pureMod->getDialectAttrs());
141 rewriter.eraseBlock(hwMod.getBodyBlock());
142 rewriter.inlineRegionBefore(*body->getParent(), hwMod.getBodyRegion(),
143 hwMod.getBodyRegion().end());
144 body = hwMod.getBodyBlock();
147 for (
auto input :
inputs) {
148 BlockArgument newArg;
149 rewriter.updateRootInPlace(hwMod, [&]() {
150 newArg = body->addArgument(input.getResult().getType(), input.getLoc());
152 rewriter.replaceAllUsesWith(input.getResult(), newArg);
153 rewriter.eraseOp(input);
157 SmallVector<Value> hwOutputOperands;
159 hwOutputOperands.push_back(output.getValue());
160 rewriter.eraseOp(output);
162 rewriter.setInsertionPointToEnd(body);
163 rewriter.create<hw::OutputOp>(pureMod.getLoc(), hwOutputOperands);
166 rewriter.eraseOp(pureMod);
172 struct ESIToPhysicalPass :
public LowerESIToPhysicalBase<ESIToPhysicalPass> {
173 void runOnOperation()
override;
177 void ESIToPhysicalPass::runOnOperation() {
179 ConversionTarget target(getContext());
180 target.markUnknownOpDynamicallyLegal([](Operation *) {
return true; });
181 target.addIllegalOp<ChannelBufferOp>();
182 target.addIllegalOp<ESIPureModuleOp>();
185 RewritePatternSet
patterns(&getContext());
186 patterns.insert<ChannelBufferLowering>(&getContext());
187 patterns.insert<PureModuleLowering>(&getContext());
191 applyPartialConversion(getOperation(), target, std::move(
patterns))))
195 std::unique_ptr<OperationPass<ModuleOp>>
197 return std::make_unique<ESIToPhysicalPass>();
llvm::SmallVector< StringAttr > inputs
llvm::SmallVector< StringAttr > outputs
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
std::unique_ptr< OperationPass< ModuleOp > > createESIPhysicalLoweringPass()
This file defines an intermediate representation for circuits acting as an abstraction for constraint...