Skip to content

Commit

Permalink
Packet flow routing fixup (#690)
Browse files Browse the repository at this point in the history
* Packet flow routing fixup

* Fixup unit tests for updated packet router
  • Loading branch information
erwei-xilinx authored Oct 20, 2023
1 parent 07a4409 commit 7920cd0
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 11 deletions.
71 changes: 64 additions & 7 deletions lib/Dialect/AIE/Transforms/AIECreatePacketFlows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,48 @@ int getAvailableDestChannel(SmallVector<std::pair<Connect, int>, 8> &connects,
return -1;
}

// Same function as above, but scanning from the last connect backwards
int getAvailableDestChannelReverseOrder(
SmallVector<std::pair<Connect, int>, 8> &connects, Port sourcePort,
int flowID, WireBundle destBundle) {

int numChannels;

if (destBundle == WireBundle::North)
numChannels = 6;
else if (destBundle == WireBundle::South || destBundle == WireBundle::East ||
destBundle == WireBundle::West)
numChannels = 4;
else
numChannels = 2;

if (connects.size() == 0)
return numChannels - 1;

for (int i = numChannels - 1; i >= 0; i--) {
Port port = std::make_pair(destBundle, i);
int countFlows = 0;
for (auto conn : connects) {
Port connDest = conn.first.second;
if (connDest == port)
countFlows++;
}
if (countFlows > 0 && countFlows < 32)
return i;
}
for (int i = numChannels - 1; i >= 0; i--) {
Port port = std::make_pair(destBundle, i);
SmallVector<Port, 8> ports;
for (auto connect : connects)
ports.push_back(connect.first.second);

if (std::find(ports.begin(), ports.end(), port) == ports.end())
return i;
}

return -1;
}

void update_coordinates(int &xCur, int &yCur, WireBundle move) {
if (move == WireBundle::East) {
xCur = xCur + 1;
Expand All @@ -118,7 +160,8 @@ void buildPSRoute(
int xSrc, int ySrc, Port sourcePort, int xDest, int yDest, Port destPort,
int flowID,
DenseMap<std::pair<int, int>, SmallVector<std::pair<Connect, int>, 8>>
&switchboxes) {
&switchboxes,
bool reverseOrder = false) {
int xCur = xSrc;
int yCur = ySrc;
WireBundle curBundle;
Expand Down Expand Up @@ -161,8 +204,12 @@ void buildPSRoute(

for (unsigned i = 0; i < moves.size(); i++) {
WireBundle move = moves[i];
curChannel = getAvailableDestChannel(switchboxes[curCoord], lastPort,
flowID, move);
if (reverseOrder)
curChannel = getAvailableDestChannelReverseOrder(
switchboxes[curCoord], lastPort, flowID, move);
else
curChannel = getAvailableDestChannel(switchboxes[curCoord], lastPort,
flowID, move);
if (curChannel == -1)
continue;

Expand Down Expand Up @@ -268,6 +315,8 @@ struct AIERoutePacketFlowsPass
DenseMap<std::pair<PhysPort, int>, SmallVector<PhysPort, 4>> packetFlows;
SmallVector<std::pair<PhysPort, int>, 4> slavePorts;
DenseMap<std::pair<PhysPort, int>, int> slaveAMSels;
// Map from a port to
DenseMap<PhysPort, Attribute> keepPktHeaderAttr;

for (auto tileOp : device.getOps<TileOp>()) {
int col = tileOp.colIndex();
Expand Down Expand Up @@ -299,7 +348,12 @@ struct AIERoutePacketFlowsPass
Port destPort = pktDest.port();

buildPSRoute(xSrc, ySrc, sourcePort, xDest, yDest, destPort, flowID,
switchboxes);
switchboxes, true);

// Assign "keep_pkt_header flag"
if (pktflow->hasAttr("keep_pkt_header"))
keepPktHeaderAttr[std::make_pair(destTile, destPort)] =
StringAttr::get(Op.getContext(), "true");
}
}
}
Expand Down Expand Up @@ -611,9 +665,12 @@ struct AIERoutePacketFlowsPass
amsels.push_back(amselOps[msel]);
}

builder.create<MasterSetOp>(builder.getUnknownLoc(),
builder.getIndexType(), bundle, channel,
amsels);
auto ms_op = builder.create<MasterSetOp>(builder.getUnknownLoc(),
builder.getIndexType(), bundle,
channel, amsels);
if (auto pktFlowAttrs =
keepPktHeaderAttr[std::make_pair(tileOp, tileMaster)])
ms_op->setAttr("keep_pkt_header", pktFlowAttrs);
}

// Generate the packet rules
Expand Down
47 changes: 47 additions & 0 deletions test/create-packet-flows/circuit_and_packet_routing.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===- circuit_and_packet_routing.mlir -------------------------*- MLIR -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// (c) Copyright 2023 Xilinx Inc.
//
//===----------------------------------------------------------------------===//

// RUN: aie-opt --aie-create-packet-flows %s | FileCheck %s

// CHECK-LABEL: module @aie_module {
// CHECK: %[[VAL_0:.*]] = AIE.tile(7, 2)
// CHECK: %[[VAL_1:.*]] = AIE.switchbox(%[[VAL_0:.*]]) {
// CHECK: %[[VAL_2:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_3:.*]] = AIE.masterset(DMA : 1, %[[VAL_2:.*]])
// CHECK: AIE.packetrules(North : 3) {
// CHECK: AIE.rule(31, 10, %[[VAL_2:.*]])
// CHECK: }
// CHECK: }
// CHECK: %[[VAL_5:.*]] = AIE.tile(7, 3)
// CHECK: %[[VAL_6:.*]] = AIE.switchbox(%[[VAL_5:.*]]) {
// CHECK: %[[VAL_7:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_8:.*]] = AIE.masterset(South : 3, %[[VAL_7:.*]])
// CHECK: AIE.packetrules(DMA : 0) {
// CHECK: AIE.rule(31, 10, %[[VAL_7:.*]])
// CHECK: }
// CHECK: }
// CHECK: AIE.flow(%[[VAL_0]], DMA : 1, %[[VAL_5]], DMA : 0)

//
// one circuit routing and one packet routing
//

module @aie_module {
AIE.device(xcvc1902) {
%t70 = AIE.tile(7, 2)
%t71 = AIE.tile(7, 3)

AIE.packet_flow(0xA) {
AIE.packet_source<%t71, DMA : 0>
AIE.packet_dest<%t70, DMA : 1>
}
AIE.flow(%t70, DMA : 1, %t71, DMA : 0)
}
}
68 changes: 68 additions & 0 deletions test/create-packet-flows/packet_routing_keep_pkt_header.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//===- packet_routing_keep_pkt_header.mlir ---------------------*- MLIR -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// (c) Copyright 2023 Xilinx Inc.
//
//===----------------------------------------------------------------------===//

// RUN: aie-opt --aie-create-packet-flows %s | FileCheck %s

// CHECK-LABEL: module @aie_module {
// CHECK: %[[VAL_0:.*]] = AIE.tile(6, 2)
// CHECK: %[[VAL_1:.*]] = AIE.switchbox(%[[VAL_0]]) {
// CHECK: %[[VAL_2:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_3:.*]] = AIE.masterset(DMA : 1, %[[VAL_2]])
// CHECK: AIE.packetrules(North : 3) {
// CHECK: AIE.rule(31, 1, %[[VAL_2]])
// CHECK: }
// CHECK: }
// CHECK: %[[VAL_4:.*]] = AIE.tile(6, 3)
// CHECK: %[[VAL_5:.*]] = AIE.switchbox(%[[VAL_4]]) {
// CHECK: %[[VAL_6:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_7:.*]] = AIE.masterset(South : 3, %[[VAL_6]])
// CHECK: AIE.packetrules(DMA : 0) {
// CHECK: AIE.rule(31, 1, %[[VAL_6]])
// CHECK: }
// CHECK: }
// CHECK: %[[VAL_8:.*]] = AIE.tile(7, 2)
// CHECK: %[[VAL_9:.*]] = AIE.switchbox(%[[VAL_8]]) {
// CHECK: %[[VAL_10:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_11:.*]] = AIE.masterset(DMA : 1, %[[VAL_10]]) {keep_pkt_header = "true"}
// CHECK: AIE.packetrules(North : 3) {
// CHECK: AIE.rule(31, 2, %[[VAL_10]])
// CHECK: }
// CHECK: }
// CHECK: %[[VAL_12:.*]] = AIE.tile(7, 3)
// CHECK: %[[VAL_13:.*]] = AIE.switchbox(%[[VAL_12]]) {
// CHECK: %[[VAL_14:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_15:.*]] = AIE.masterset(South : 3, %[[VAL_14]])
// CHECK: AIE.packetrules(DMA : 0) {
// CHECK: AIE.rule(31, 2, %[[VAL_14]])
// CHECK: }
// CHECK: }

//
// keep_pkt_header attribute overrides the downstream decision to drop the packet header
//

module @aie_module {
AIE.device(xcvc1902) {
%t62 = AIE.tile(6, 2)
%t63 = AIE.tile(6, 3)
%t72 = AIE.tile(7, 2)
%t73 = AIE.tile(7, 3)

AIE.packet_flow(0x1) {
AIE.packet_source<%t63, DMA : 0>
AIE.packet_dest<%t62, DMA : 1>
}

AIE.packet_flow(0x2) {
AIE.packet_source<%t73, DMA : 0>
AIE.packet_dest<%t72, DMA : 1>
} {keep_pkt_header = true}
}
}
4 changes: 2 additions & 2 deletions test/create-packet-flows/test_create_packet_flows_shim0.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
// CHECK: %[[VAL_2:.*]] = AIE.switchbox(%[[VAL_0:.*]]) {
// CHECK: %[[VAL_3:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_4:.*]] = AIE.masterset(South : 3, %[[VAL_3:.*]])
// CHECK: AIE.packetrules(North : 0) {
// CHECK: AIE.packetrules(North : 3) {
// CHECK: AIE.rule(31, 10, %[[VAL_3:.*]])
// CHECK: }
// CHECK: }
// CHECK: %[[VAL_5:.*]] = AIE.tile(7, 1)
// CHECK: %[[VAL_6:.*]] = AIE.switchbox(%[[VAL_5:.*]]) {
// CHECK: %[[VAL_7:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_8:.*]] = AIE.masterset(South : 0, %[[VAL_6:.*]])
// CHECK: %[[VAL_8:.*]] = AIE.masterset(South : 3, %[[VAL_6:.*]])
// CHECK: AIE.packetrules(DMA : 0) {
// CHECK: AIE.rule(31, 10, %[[VAL_7:.*]])
// CHECK: }
Expand Down
4 changes: 2 additions & 2 deletions test/create-packet-flows/test_create_packet_flows_shim1.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// CHECK: }
// CHECK: %[[VAL_2:.*]] = AIE.switchbox(%[[VAL_0:.*]]) {
// CHECK: %[[VAL_3:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_4:.*]] = AIE.masterset(North : 0, %[[VAL_3:.*]])
// CHECK: %[[VAL_4:.*]] = AIE.masterset(North : 5, %[[VAL_3:.*]])
// CHECK: AIE.packetrules(South : 3) {
// CHECK: AIE.rule(31, 3, %[[VAL_3:.*]])
// CHECK: }
Expand All @@ -26,7 +26,7 @@
// CHECK: %[[VAL_6:.*]] = AIE.switchbox(%[[VAL_5:.*]]) {
// CHECK: %[[VAL_7:.*]] = AIE.amsel<0> (0)
// CHECK: %[[VAL_8:.*]] = AIE.masterset(DMA : 0, %[[VAL_7:.*]])
// CHECK: AIE.packetrules(South : 0) {
// CHECK: AIE.packetrules(South : 5) {
// CHECK: AIE.rule(31, 3, %[[VAL_7:.*]])
// CHECK: }
// CHECK: }
Expand Down

0 comments on commit 7920cd0

Please sign in to comment.