|
12 | 12 |
|
13 | 13 | #include "../PassDetails.h"
|
14 | 14 |
|
| 15 | +#include "circt/Dialect/Comb/CombOps.h" |
15 | 16 | #include "circt/Dialect/ESI/ESIOps.h"
|
16 | 17 | #include "circt/Dialect/HW/HWOps.h"
|
| 18 | +#include "circt/Dialect/Seq/SeqOps.h" |
17 | 19 | #include "circt/Support/BackedgeBuilder.h"
|
18 | 20 | #include "circt/Support/LLVM.h"
|
19 | 21 |
|
@@ -78,6 +80,64 @@ LogicalResult ChannelBufferLowering::matchAndRewrite(
|
78 | 80 | return success();
|
79 | 81 | }
|
80 | 82 |
|
| 83 | +namespace { |
| 84 | +/// Lower `ChannelBufferOp`s, breaking out the various options. For now, just |
| 85 | +/// replace with the specified number of pipeline stages (since that's the only |
| 86 | +/// option). |
| 87 | +struct FIFOLowering : public OpConversionPattern<FIFOOp> { |
| 88 | +public: |
| 89 | + using OpConversionPattern::OpConversionPattern; |
| 90 | + |
| 91 | + LogicalResult |
| 92 | + matchAndRewrite(FIFOOp, OpAdaptor adaptor, |
| 93 | + ConversionPatternRewriter &rewriter) const final; |
| 94 | +}; |
| 95 | +} // anonymous namespace |
| 96 | + |
| 97 | +LogicalResult |
| 98 | +FIFOLowering::matchAndRewrite(FIFOOp op, OpAdaptor adaptor, |
| 99 | + ConversionPatternRewriter &rewriter) const { |
| 100 | + auto loc = op.getLoc(); |
| 101 | + auto outputType = op.getType(); |
| 102 | + BackedgeBuilder bb(rewriter, loc); |
| 103 | + auto i1 = rewriter.getI1Type(); |
| 104 | + auto c1 = rewriter.create<hw::ConstantOp>(loc, rewriter.getI1Type(), |
| 105 | + rewriter.getBoolAttr(true)); |
| 106 | + if (op.getInput().getType().getDataDelay() != 0) |
| 107 | + return op.emitOpError( |
| 108 | + "currently only supports input channels with zero data delay"); |
| 109 | + |
| 110 | + Backedge inputEn = bb.get(i1); |
| 111 | + auto unwrapPull = rewriter.create<UnwrapFIFOOp>(loc, op.getInput(), inputEn); |
| 112 | + |
| 113 | + Backedge outputRdEn = bb.get(i1); |
| 114 | + auto seqFifo = rewriter.create<seq::FIFOOp>( |
| 115 | + loc, outputType.getInner(), i1, i1, Type(), Type(), unwrapPull.getData(), |
| 116 | + outputRdEn, inputEn, op.getClk(), op.getRst(), op.getDepthAttr(), |
| 117 | + rewriter.getI64IntegerAttr(outputType.getDataDelay()), IntegerAttr(), |
| 118 | + IntegerAttr()); |
| 119 | + auto inputNotEmpty = |
| 120 | + rewriter.create<comb::XorOp>(loc, unwrapPull.getEmpty(), c1); |
| 121 | + inputNotEmpty->setAttr("sv.namehint", |
| 122 | + rewriter.getStringAttr("inputNotEmpty")); |
| 123 | + auto seqFifoNotFull = |
| 124 | + rewriter.create<comb::XorOp>(loc, seqFifo.getFull(), c1); |
| 125 | + seqFifoNotFull->setAttr("sv.namehint", |
| 126 | + rewriter.getStringAttr("seqFifoNotFull")); |
| 127 | + inputEn.setValue( |
| 128 | + rewriter.create<comb::AndOp>(loc, inputNotEmpty, seqFifoNotFull)); |
| 129 | + static_cast<Value>(inputEn).getDefiningOp()->setAttr( |
| 130 | + "sv.namehint", rewriter.getStringAttr("inputEn")); |
| 131 | + |
| 132 | + auto output = |
| 133 | + rewriter.create<WrapFIFOOp>(loc, mlir::TypeRange{outputType, i1}, |
| 134 | + seqFifo.getOutput(), seqFifo.getEmpty()); |
| 135 | + outputRdEn.setValue(output.getRden()); |
| 136 | + |
| 137 | + rewriter.replaceOp(op, output.getChanOutput()); |
| 138 | + return success(); |
| 139 | +} |
| 140 | + |
81 | 141 | namespace {
|
82 | 142 | /// Lower pure modules into hw.modules.
|
83 | 143 | struct PureModuleLowering : public OpConversionPattern<ESIPureModuleOp> {
|
@@ -186,13 +246,12 @@ void ESIToPhysicalPass::runOnOperation() {
|
186 | 246 | // Set up a conversion and give it a set of laws.
|
187 | 247 | ConversionTarget target(getContext());
|
188 | 248 | target.markUnknownOpDynamicallyLegal([](Operation *) { return true; });
|
189 |
| - target.addIllegalOp<ChannelBufferOp>(); |
190 |
| - target.addIllegalOp<ESIPureModuleOp>(); |
| 249 | + target.addIllegalOp<ChannelBufferOp, ESIPureModuleOp, FIFOOp>(); |
191 | 250 |
|
192 | 251 | // Add all the conversion patterns.
|
193 | 252 | RewritePatternSet patterns(&getContext());
|
194 |
| - patterns.insert<ChannelBufferLowering>(&getContext()); |
195 |
| - patterns.insert<PureModuleLowering>(&getContext()); |
| 253 | + patterns.insert<ChannelBufferLowering, PureModuleLowering, FIFOLowering>( |
| 254 | + &getContext()); |
196 | 255 |
|
197 | 256 | // Run the conversion.
|
198 | 257 | if (failed(
|
|
0 commit comments