@@ -747,11 +747,16 @@ struct AIEObjectFifoStatefulTransformPass
747747 void createBd (OpBuilder &builder , LockOp acqLock , int acqMode ,
748748 LockAction acqLockAction , LockOp relLock , int relMode ,
749749 MyOp buff , int offset , int len , Block *succ ,
750- BDDimLayoutArrayAttr dims , BDPadLayoutArrayAttr padDimensions ) {
750+ BDDimLayoutArrayAttr dims , BDPadLayoutArrayAttr padDimensions ,
751+ std ::optional <PacketInfoAttr > bdPacket ) {
751752 if (acqLock)
752753 builder.create<UseLockOp >(builder.getUnknownLoc(), acqLock , acqLockAction ,
753754 acqMode);
754-
755+ if (bdPacket) {
756+ builder.create<DMABDPACKETOp >(builder.getUnknownLoc(),
757+ bdPacket->getPktType(),
758+ bdPacket->getPktId());
759+ }
755760 if (!dims.getValue ().empty() && padDimensions) {
756761 builder.create<DMABDOp >(builder.getUnknownLoc(), buff , offset , len , dims ,
757762 padDimensions);
@@ -775,6 +780,7 @@ struct AIEObjectFifoStatefulTransformPass
775780 DMAChannelDir channelDir , size_t lockIndex , Block *succ ,
776781 BDDimLayoutArrayAttr dims ,
777782 BDPadLayoutArrayAttr padDimensions ,
783+ std ::optional <PacketInfoAttr > bdPacket ,
778784 bool distribOrJoin = false ) {
779785 LockOp acqLock;
780786 LockOp relLock;
@@ -808,26 +814,27 @@ struct AIEObjectFifoStatefulTransformPass
808814 }
809815 }
810816 createBd(builder , acqLock , acqMode , acqLockAction , relLock , relMode , buff ,
811- offset , len , succ , dims , padDimensions);
817+ offset , len , succ , dims , padDimensions , bdPacket );
812818 }
813819
814820 /// Function that either calls createAIETileDMA(), createShimDMA() or
815821 /// createMemTileDMA() based on op tile row value.
816822 void createDMA (DeviceOp &device , OpBuilder &builder , ObjectFifoCreateOp op ,
817823 DMAChannelDir channelDir , int channelIndex , int lockMode ,
818- BDDimLayoutArrayAttr dims , BDPadLayoutArrayAttr pad_dims ) {
824+ BDDimLayoutArrayAttr dims , BDPadLayoutArrayAttr pad_dims ,
825+ std ::optional <PacketInfoAttr > bdPacket ) {
819826 if (op.getProducerTileOp().isShimTile()) {
820827 createShimDMA(device , builder , op , channelDir , channelIndex , lockMode ,
821- dims);
828+ dims , bdPacket );
822829 } else if (op.getProducerTileOp().isMemTile()) {
823830 BDPadLayoutArrayAttr padDims = nullptr;
824831 if (channelDir == DMAChannelDir::MM2 S && pad_dims)
825832 padDims = pad_dims;
826833 createMemTileDMA(device , builder , op , channelDir , channelIndex , lockMode ,
827- dims , padDims);
834+ dims , padDims , bdPacket );
828835 } else {
829836 createAIETileDMA(device , builder , op , channelDir , channelIndex , lockMode ,
830- dims);
837+ dims , bdPacket );
831838 }
832839 }
833840
@@ -836,7 +843,8 @@ struct AIEObjectFifoStatefulTransformPass
836843 void createAIETileDMA (DeviceOp &device , OpBuilder &builder ,
837844 ObjectFifoCreateOp op , DMAChannelDir channelDir ,
838845 int channelIndex , int lockMode ,
839- BDDimLayoutArrayAttr dims ) {
846+ BDDimLayoutArrayAttr dims ,
847+ std ::optional <PacketInfoAttr > bdPacket ) {
840848 size_t numBlocks = op.size();
841849 if (numBlocks == 0 )
842850 return;
@@ -921,8 +929,8 @@ struct AIEObjectFifoStatefulTransformPass
921929 builder.setInsertionPointToStart(curr);
922930 createBdBlock<BufferOp >(builder , target , lockMode , acqNum , relNum ,
923931 buffersPerFifo[target ][elemIndex ], /*offset*/ 0 ,
924- len , channelDir , elemIndex , succ , dims ,
925- nullptr );
932+ len , channelDir , elemIndex , succ , dims , nullptr ,
933+ bdPacket );
926934 curr = succ;
927935 totalBlocks++;
928936 }
@@ -934,8 +942,8 @@ struct AIEObjectFifoStatefulTransformPass
934942 /// It uses creatBdBlock(), see there for lockMode input.
935943 void createShimDMA (DeviceOp &device , OpBuilder &builder ,
936944 ObjectFifoCreateOp op , DMAChannelDir channelDir ,
937- int channelIndex , int lockMode ,
938- BDDimLayoutArrayAttr dims ) {
945+ int channelIndex , int lockMode , BDDimLayoutArrayAttr dims ,
946+ std :: optional < PacketInfoAttr > bdPacket ) {
939947 size_t numBlocks = externalBuffersPerFifo[op ].size();
940948 if (numBlocks == 0 )
941949 return;
@@ -998,7 +1006,7 @@ struct AIEObjectFifoStatefulTransformPass
9981006 createBdBlock<ExternalBufferOp >(builder , op , lockMode , acqNum , relNum ,
9991007 externalBuffersPerFifo[op ][elemIndex ],
10001008 /*offset*/ 0 , len , channelDir , elemIndex ,
1001- succ , dims , nullptr);
1009+ succ , dims , nullptr , bdPacket );
10021010 curr = succ;
10031011 elemIndex++;
10041012 }
@@ -1010,7 +1018,8 @@ struct AIEObjectFifoStatefulTransformPass
10101018 ObjectFifoCreateOp op , DMAChannelDir channelDir ,
10111019 int channelIndex , int lockMode ,
10121020 BDDimLayoutArrayAttr dims ,
1013- BDPadLayoutArrayAttr padDimensions ) {
1021+ BDPadLayoutArrayAttr padDimensions ,
1022+ std ::optional <PacketInfoAttr > bdPacket ) {
10141023 size_t numBlocks = op.size();
10151024 if (numBlocks == 0 )
10161025 return;
@@ -1174,7 +1183,7 @@ struct AIEObjectFifoStatefulTransformPass
11741183 createBdBlock<BufferOp >(builder , target , lockMode , acqNum , relNum ,
11751184 buffersPerFifo[target ][elemIndex ], offset ,
11761185 lenOut , channelDir , lockIndex , succ , dims ,
1177- padDimensions , distribOrJoin);
1186+ padDimensions , bdPacket , distribOrJoin);
11781187 curr = succ;
11791188 totalBlocks++;
11801189 }
@@ -1631,12 +1640,16 @@ struct AIEObjectFifoStatefulTransformPass
16311640 void createObjectFifoAllocationInfo (OpBuilder &builder , MLIRContext *ctx ,
16321641 FlatSymbolRefAttr obj_fifo , int colIndex ,
16331642 DMAChannelDir channelDir ,
1634- int channelIndex , bool plio ) {
1643+ int channelIndex , bool plio ,
1644+ std ::optional <PacketInfoAttr > packet ) {
1645+ PacketInfoAttr packetInfo = nullptr;
1646+ if (packet)
1647+ packetInfo = *packet;
16351648 builder.create<ShimDMAAllocationOp >(builder.getUnknownLoc(), obj_fifo ,
16361649 DMAChannelDirAttr::get(ctx , channelDir),
16371650 builder.getI64 IntegerAttr(channelIndex),
16381651 builder.getI64 IntegerAttr(colIndex),
1639- builder.getBoolAttr(plio));
1652+ builder.getBoolAttr(plio), packetInfo );
16401653 }
16411654
16421655 /// Function used to verify that an objectfifo is present in at most one
@@ -1659,6 +1672,18 @@ struct AIEObjectFifoStatefulTransformPass
16591672 }
16601673 }
16611674
1675+ /// Account for already used packet IDs and return next available ID.
1676+ int getStartPacketID (DeviceOp &device ) {
1677+ int packetID = 0 ;
1678+ for (PacketFlowOp packetflow : device.getOps<PacketFlowOp >()) {
1679+ if (packetflow.getID() > packetID) {
1680+ // compute next available ID
1681+ packetID = packetflow.getID() + 1 ;
1682+ }
1683+ }
1684+ return packetID;
1685+ }
1686+
16621687 /// Helper function to assign DMA channel indices for FIFOs based on
16631688 /// cross-tile conditions
16641689 void assignDMAChannelIndices (
@@ -1831,7 +1856,6 @@ struct AIEObjectFifoStatefulTransformPass
18311856 createOp.setElemNumberAttr(
18321857 builder.getI32 IntegerAttr(createOp.size()));
18331858 else {
1834-
18351859 if (!createOp.getInitValues ().has_value()) {
18361860
18371861 int prodMaxAcquire = findObjectFifoSize(
@@ -1845,58 +1869,74 @@ struct AIEObjectFifoStatefulTransformPass
18451869 }
18461870 }
18471871
1848- // Analyze cross-tile buffer allocations and print results
1872+ //===------------------------------------------------------------------===//
1873+ // Create flows and tile DMAs
1874+ //===------------------------------------------------------------------===//
1875+ // Only the objectFifos we split above require DMA communication; the others
1876+ // rely on shared memory and share the same buffers.
1877+
1878+ // analyze cross-tile buffer allocations and print results
18491879 auto crossTileInfos = analyzeCrossTileFIFOBuffers();
18501880
1851- // assign DMA channels for FIFOs
1852- // assign the channel index for fifos that has cross-tile issues first
1853- // use dmaAnalysis.getDMAChannelIndex() to assign index (which internally
1854- // loop over all of available channels and assign from 0 to maximum)
1881+ // maps ends of split FIFO to DMA channels
18551882 std::map<ObjectFifoCreateOp , int > fifo_dma_channel_index ;
18561883
1857- // Assign channel indices for FIFOs with cross-tile issues first
1884+ // assign channel indices for FIFOs with cross-tile issues first
18581885 assignDMAChannelIndices(dmaAnalysis , crossTileInfos , fifo_dma_channel_index ,
18591886 true );
1860-
1861- // Then assign channel indices for FIFOs without cross-tile issues
1887+ // then assign channel indices for FIFOs without cross-tile issues
18621888 assignDMAChannelIndices(dmaAnalysis , crossTileInfos , fifo_dma_channel_index ,
18631889 false );
18641890
1865- //===------------------------------------------------------------------===//
1866- // Create flows and tile DMAs
1867- //===------------------------------------------------------------------===//
1868- // Only the objectFifos we split above require DMA communication; the others
1869- // rely on shared memory and share the same buffers.
1891+ int packetID = getStartPacketID(device);
18701892 for (auto &[producer , consumers ] : splitFifos) {
18711893 int producerChanIndex = fifo_dma_channel_index [producer ];
18721894 if (producerChanIndex == -1 )
18731895 producer.getProducerTileOp().emitOpError(
18741896 " number of output DMA channel exceeded!" );
18751897 DMAChannel producerChan = {DMAChannelDir::MM2S , producerChanIndex };
1898+ std::optional<PacketInfoAttr > bdPacket = {};
1899+ if (clPacketSwObjectFifos) {
1900+ if (packetID > 31 )
1901+ device.emitOpError(" max number of packet IDs reached" );
1902+ bdPacket = {
1903+ AIE::PacketInfoAttr::get(ctx , /*pkt_type*/ 0 , /*pkt_id*/ packetID)};
1904+ packetID++;
1905+ }
18761906 createDMA(device , builder , producer , producerChan.direction ,
18771907 producerChan.channel , 0 , producer.getDimensionsToStreamAttr(),
1878- producer.getPadDimensionsAttr());
1908+ producer.getPadDimensionsAttr(), bdPacket );
18791909 // generate objectFifo allocation info
18801910 builder.setInsertionPoint(device.getBody()->getTerminator());
18811911
18821912 if (producer.getProducerTileOp().isShimTile())
18831913 createObjectFifoAllocationInfo(
18841914 builder , ctx , SymbolRefAttr::get(ctx , producer.getName()),
18851915 producer.getProducerTileOp().colIndex(), producerChan.direction ,
1886- producerChan.channel , producer.getPlio());
1916+ producerChan.channel , producer.getPlio(), bdPacket);
1917+
1918+ PacketFlowOp packetflow;
1919+ if (clPacketSwObjectFifos) {
1920+ // create packet flow
1921+ builder.setInsertionPointAfter(producer);
1922+ packetflow = builder.create<PacketFlowOp >(
1923+ builder.getUnknownLoc(),
1924+ builder.getIntegerAttr(builder.getI8 Type(), bdPacket->getPktId()),
1925+ nullptr , nullptr);
1926+ {
1927+ OpBuilder::InsertionGuard g(builder);
1928+ builder.setInsertionPointToStart(
1929+ &packetflow.getRegion().emplaceBlock());
1930+ builder.create<EndOp >(builder.getUnknownLoc());
1931+ }
1932+ }
18871933
18881934 for (auto consumer : consumers) {
18891935 int consumerChanIndex = fifo_dma_channel_index [consumer ];
18901936 if (consumerChanIndex == -1 )
18911937 consumer.getProducerTileOp().emitOpError(
18921938 " number of input DMA channel exceeded!" );
18931939 DMAChannel consumerChan = {DMAChannelDir::S2MM , consumerChanIndex };
1894- BDDimLayoutArrayAttr consumerDims =
1895- consumer.getDimensionsFromStreamPerConsumer()[0 ];
1896- createDMA(device , builder , consumer , consumerChan.direction ,
1897- consumerChan.channel , 1 , consumerDims , nullptr);
1898- // generate objectFifo allocation info
1899- builder.setInsertionPoint(device.getBody()->getTerminator());
19001940
19011941 // If we have PLIO then figure out the direction and make that a PLIO
19021942 if (producer.getPlio()) {
@@ -1910,19 +1950,42 @@ struct AIEObjectFifoStatefulTransformPass
19101950 producerWireType = WireBundle::DMA;
19111951 consumerWireType = WireBundle::DMA;
19121952 }
1953+ if (clPacketSwObjectFifos) {
1954+ builder.setInsertionPointToStart(&packetflow.getPorts().front());
1955+ builder.create<PacketDestOp >(builder.getUnknownLoc(),
1956+ consumer.getProducerTile(),
1957+ WireBundle::DMA , consumerChan.channel);
1958+ }
1959+
1960+ BDDimLayoutArrayAttr consumerDims =
1961+ consumer.getDimensionsFromStreamPerConsumer()[0 ];
1962+ createDMA(device , builder , consumer , consumerChan.direction ,
1963+ consumerChan.channel , 1 , consumerDims , nullptr , {});
1964+ // generate objectFifo allocation info
1965+ builder.setInsertionPoint(device.getBody()->getTerminator());
19131966
19141967 if (consumer.getProducerTileOp().isShimTile())
19151968 createObjectFifoAllocationInfo(
19161969 builder , ctx , SymbolRefAttr::get(ctx , producer.getName()),
19171970 consumer.getProducerTileOp().colIndex(), consumerChan.direction ,
1918- consumerChan.channel , producer.getPlio());
1971+ consumerChan.channel , producer.getPlio(), {});
1972+
1973+ if (!clPacketSwObjectFifos ) {
1974+ // create flow
1975+ builder.setInsertionPointAfter(producer);
1976+ builder.create<FlowOp >(builder.getUnknownLoc(),
1977+ producer.getProducerTile(), producerWireType ,
1978+ producerChan.channel ,
1979+ consumer.getProducerTile(), consumerWireType ,
1980+ consumerChan.channel);
1981+ }
1982+ }
19191983
1920- // create flow
1921- builder.setInsertionPointAfter(producer);
1922- builder.create<FlowOp >(builder.getUnknownLoc(),
1923- producer.getProducerTile(), producerWireType ,
1924- producerChan.channel , consumer.getProducerTile(),
1925- consumerWireType , consumerChan.channel);
1984+ if (clPacketSwObjectFifos) {
1985+ builder.setInsertionPointToStart(&packetflow.getPorts().front());
1986+ builder.create<PacketSourceOp >(builder.getUnknownLoc(),
1987+ producer.getProducerTile(),
1988+ WireBundle::DMA , producerChan.channel);
19261989 }
19271990 }
19281991
0 commit comments