Expand Up @@ -108,10 +108,10 @@ class DMAChannelAnalysis { for (auto flowOp : device.getOps<FlowOp>()) { if (flowOp.getSourceBundle() == WireBundle::Core) aiestreamsPerTile[{flowOp.getSource(), DMAChannelDir::MM2S, flowOp.getSourceChannel()}] = 1; flowOp.getSourceChannel()}] = 1; if (flowOp.getDestBundle() == WireBundle::Core) aiestreamsPerTile[{flowOp.getDest(), DMAChannelDir::S2MM, flowOp.getDestChannel()}] = 1; flowOp.getDestChannel()}] = 1; } } Expand Down Expand Up @@ -146,21 +146,19 @@ class DMAChannelAnalysis { return -1; } /// Given a tile and DMAChannel, adds entry to aie4StreamsPerTile or /// Given a tile and DMAChannel, adds entry to aie4StreamsPerTile or /// throws an error if the stream is already used. void checkAIEStreamIndex(TileOp tileOp, DMAChannel chan) { if (aiestreamsPerTile.find( {tileOp.getResult(), chan.direction, chan.channel}) == aiestreamsPerTile.end()) { aiestreamsPerTile[{tileOp.getResult(), chan.direction, chan.channel}] = 1; if (aiestreamsPerTile.find({tileOp.getResult(), chan.direction, chan.channel}) == aiestreamsPerTile.end()) { aiestreamsPerTile[{tileOp.getResult(), chan.direction, chan.channel}] = 1; } else { if (chan.direction == DMAChannelDir::MM2S) tileOp.emitOpError("number of output Core channels exceeded!"); else tileOp.emitOpError("number of input Core channels exceeded!"); } } } }; //===----------------------------------------------------------------------===// Expand Down Expand Up @@ -1841,6 +1839,20 @@ struct AIEObjectFifoStatefulTransformPass if (createOp.getDisableSynchronization()) consumerFifo.setDisableSynchronization(true); replaceSplitFifo(createOp, consumerFifo, consumerTileOp); if (createOp.getAieStream()) { int streamEnd = createOp.getAieStream().value(); if (streamEnd > 0) { consumerFifo->setAttr("aie_stream", builder.getI32IntegerAttr(streamEnd)); consumerFifo->setAttr( "aie_stream_port", builder.getI32IntegerAttr(createOp.getAieStreamPort().value())); } if (streamEnd == 1) { createOp->removeAttr("aie_stream"); createOp->removeAttr("aie_stream_port"); } } // identify external buffers that were registered to the consumer fifo if (consumerTile.getDefiningOp<TileOp>().isShimTile()) Expand Down Expand Up @@ -1934,53 +1946,107 @@ struct AIEObjectFifoStatefulTransformPass int packetID = getStartPacketID(device); for (auto &[producer, consumers] : splitFifos) { int producerChanIndex = fifo_dma_channel_index[producer]; if (producerChanIndex == -1) producer.getProducerTileOp().emitOpError( "number of output DMA channel exceeded!"); DMAChannel producerChan = {DMAChannelDir::MM2S, producerChanIndex}; std::optional<PacketInfoAttr> bdPacket = {}; if (clPacketSwObjectFifos) { if (packetID > 31) device.emitOpError("max number of packet IDs reached"); bdPacket = { AIE::PacketInfoAttr::get(ctx, /*pkt_type*/ 0, /*pkt_id*/ packetID)}; packetID++; } createDMA(device, builder, producer, producerChan.direction, producerChan.channel, 0, producer.getDimensionsToStreamAttr(), producer.getPadDimensionsAttr(), bdPacket); // generate objectFifo allocation info builder.setInsertionPoint(device.getBody()->getTerminator()); int producerChanIndex = -1; DMAChannel producerChan; PacketFlowOp packetflow; if (producer.getAieStream()) { int prodStreamEnd = producer.getAieStream().value(); if (prodStreamEnd == 0 || prodStreamEnd == 2) { producerChanIndex = producer.getAieStreamPort().value(); producerChan = {DMAChannelDir::MM2S, producerChanIndex}; dmaAnalysis.checkAIEStreamIndex(producer.getProducerTileOp(), producerChan); } } else { producerChanIndex = fifo_dma_channel_index[producer]; if (producerChanIndex == -1) producer.getProducerTileOp().emitOpError( "number of output DMA channel exceeded!"); producerChan = {DMAChannelDir::MM2S, producerChanIndex}; std::optional<PacketInfoAttr> bdPacket = {}; if (clPacketSwObjectFifos) { if (packetID > 31) device.emitOpError("max number of packet IDs reached"); bdPacket = {AIE::PacketInfoAttr::get(ctx, /*pkt_type*/ 0, /*pkt_id*/ packetID)}; packetID++; } createDMA(device, builder, producer, producerChan.direction, producerChan.channel, 0, producer.getDimensionsToStreamAttr(), producer.getPadDimensionsAttr(), bdPacket); if (producer.getProducerTileOp().isShimTile()) createObjectFifoAllocationInfo( builder, ctx, producer, producer.getProducerTileOp().colIndex(), producerChan.direction, producerChan.channel, producer.getPlio(), bdPacket); // generate objectFifo allocation info builder.setInsertionPoint(device.getBody()->getTerminator()); if (producer.getProducerTileOp().isShimTile()) createObjectFifoAllocationInfo( builder, ctx, producer, producer.getProducerTileOp().colIndex(), producerChan.direction, producerChan.channel, producer.getPlio(), bdPacket); PacketFlowOp packetflow; if (clPacketSwObjectFifos) { // create packet flow builder.setInsertionPointAfter(producer); packetflow = builder.create<PacketFlowOp>( builder.getUnknownLoc( ), builder.getIntegerAttr(builder.getI8Type(), bdPacket->getPktId()), nullptr, nullptr); { OpBuilder::InsertionGuard g( builder); builder.setInsertionPointToStart( &packetflow.getRegion().emplaceBlock ());builder.create<EndOp>(builder.getUnknownLoc()); if (clPacketSwObjectFifos) { // create packet flow builder.setInsertionPointAfter(producer); packetflow = builder.create<PacketFlowOp>( builder.getUnknownLoc(), builder.getIntegerAttr(builder.getI8Type(), bdPacket->getPktId() ), nullptr, nullptr); { OpBuilder::InsertionGuard g(builder); builder.setInsertionPointToStart( &packetflow.getRegion().emplaceBlock()); builder.create<EndOp>(builder.getUnknownLoc ());} } } for (auto consumer : consumers) { int consumerChanIndex = fifo_dma_channel_index[consumer]; if (consumerChanIndex == -1) consumer.getProducerTileOp().emitOpError( "number of input DMA channel exceeded!"); DMAChannel consumerChan = {DMAChannelDir::S2MM, consumerChanIndex}; // if not aie4 stream, create consumer tile DMA int consumerChanIndex = -1; DMAChannel consumerChan; if (consumer.getAieStream()) { int consStreamEnd = consumer.getAieStream().value(); if (consStreamEnd == 1 || consStreamEnd == 2) { consumerChanIndex = consumer.getAieStreamPort().value(); consumerChan = {DMAChannelDir::S2MM, consumerChanIndex}; dmaAnalysis.checkAIEStreamIndex(consumer.getProducerTileOp(), consumerChan); } } else { consumerChanIndex = fifo_dma_channel_index[consumer]; if (consumerChanIndex == -1) consumer.getProducerTileOp().emitOpError( "number of input DMA channel exceeded!"); consumerChan = {DMAChannelDir::S2MM, consumerChanIndex}; BDDimLayoutArrayAttr consumerDims = consumer.getDimensionsFromStreamPerConsumer()[0]; createDMA(device, builder, consumer, consumerChan.direction, consumerChan.channel, 1, consumerDims, nullptr, {}); // generate objectFifo allocation info builder.setInsertionPoint(device.getBody()->getTerminator()); if (!consumer.getAieStream()) { // generate objectFifo allocation info builder.setInsertionPoint(device.getBody()->getTerminator()); if (consumer.getProducerTileOp().isShimTile()) // createObjectFifoAllocationInfo( // builder, ctx, SymbolRefAttr::get(ctx, producer.getName()), // consumer.getProducerTileOp().colIndex(), // consumerChan.direction, consumerChan.channel, // producer.getPlio(), {}); createObjectFifoAllocationInfo( builder, ctx, producer, consumer.getProducerTileOp().colIndex(), consumerChan.direction, consumerChan.channel, producer.getPlio(), {}); } if (clPacketSwObjectFifos) { builder.setInsertionPointToStart(&packetflow.getPorts().front()); builder.create<PacketDestOp>(builder.getUnknownLoc(), consumer.getProducerTile(), WireBundle::DMA, consumerChan.channel); } } // If we have PLIO then figure out the direction and make that a PLIO if (producer.getPlio()) { Expand All @@ -1993,26 +2059,40 @@ struct AIEObjectFifoStatefulTransformPass } else { producerWireType = WireBundle::DMA; consumerWireType = WireBundle::DMA; } if (clPacketSwObjectFifos) { builder.setInsertionPointToStart(&packetflow.getPorts().front()); builder.create<PacketDestOp>(builder.getUnknownLoc(), consumer.getProducerTile(), WireBundle::DMA, consumerChan.channel); if (producer.getAieStream()) { int prodStreamEnd = producer.getAieStream().value(); if (prodStreamEnd == 0 || prodStreamEnd == 2) producerWireType = WireBundle::Core; } if (consumer.getAieStream()) { int consumerStreamEnd = consumer.getAieStream().value(); if (consumerStreamEnd == 1 || consumerStreamEnd == 2) consumerWireType = WireBundle::Core; } } BDDimLayoutArrayAttr consumerDims = consumer.getDimensionsFromStreamPerConsumer()[0]; createDMA(device, builder, consumer, consumerChan.direction, consumerChan.channel, 1, consumerDims, nullptr, {}); // generate objectFifo allocation info builder.setInsertionPoint(device.getBody()->getTerminator()); if (consumer.getProducerTileOp().isShimTile()) createObjectFifoAllocationInfo( builder, ctx, producer, consumer.getProducerTileOp().colIndex(), consumerChan.direction, consumerChan.channel, producer.getPlio(), {}); // if (clPacketSwObjectFifos) { // builder.setInsertionPointToStart(&packetflow.getPorts().front()); // builder.create<PacketDestOp>(builder.getUnknownLoc(), // consumer.getProducerTile(), // WireBundle::DMA, // consumerChan.channel); // } // BDDimLayoutArrayAttr consumerDims = // consumer.getDimensionsFromStreamPerConsumer()[0]; // createDMA(device, builder, consumer, consumerChan.direction, // consumerChan.channel, 1, consumerDims, nullptr, {}); // // generate objectFifo allocation info // builder.setInsertionPoint(device.getBody()->getTerminator()); // if (consumer.getProducerTileOp().isShimTile()) // createObjectFifoAllocationInfo( // builder, ctx, producer, // consumer.getProducerTileOp().colIndex(), // consumerChan.direction, consumerChan.channel, // producer.getPlio(), // {}); if (!clPacketSwObjectFifos) { // create flow Expand Down