188 DeviceOp device = getOperation();
189 const auto &targetModel = device.getTargetModel();
190 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
192 if (targetModel.getTargetArch() == AIEArch::AIE1)
196 llvm::MapVector<AIE::TileID, AIE::TileOp> tiles;
197 llvm::SmallSet<int, 1> occupiedCols;
198 for (
auto tile : device.getOps<AIE::TileOp>()) {
199 int colIndex = tile.colIndex();
200 int rowIndex = tile.rowIndex();
201 tiles[{colIndex, rowIndex}] = tile;
202 occupiedCols.insert(colIndex);
206 for (
int col : occupiedCols) {
207 builder.setInsertionPointToStart(device.getBody());
208 AIE::TileOp shimTile = TileOp::getOrCreate(builder, device,
col, 0);
210 if (clRouteShimCTRLToTCT ==
"all-tiles" ||
211 clRouteShimCTRLToTCT ==
"shim-only") {
213 SmallVector<AIE::TileOp> tilesOnCol;
214 for (
auto &[tId, tOp] : tiles) {
217 if (clRouteShimCTRLToTCT ==
"shim-only" && !tOp.isShimNOCorPLTile())
219 tilesOnCol.push_back(tOp);
223 builder, device, shimTile, AIE::WireBundle::South, tilesOnCol,
224 AIE::WireBundle::TileControl, 0, tileIDMap,
false);
226 if (clRouteShimDmaToTileCTRL) {
228 SmallVector<AIE::TileOp> tilesOnCol;
229 for (
auto &[tId, tOp] : tiles) {
232 tilesOnCol.push_back(tOp);
236 builder, device, shimTile, AIE::WireBundle::DMA, tilesOnCol,
237 AIE::WireBundle::TileControl, 0, tileIDMap,
true);
244 xilinx::AIE::WireBundle sourceBundle,
245 uint32_t sourceChannel, Value dest,
246 xilinx::AIE::WireBundle destBundle,
247 uint32_t destChannel,
248 mlir::BoolAttr keep_pkt_header =
nullptr,
249 mlir::BoolAttr ctrl_pkt_flow =
nullptr) {
250 OpBuilder::InsertionGuard guard(builder);
252 AIE::PacketFlowOp pktFlow = builder.create<AIE::PacketFlowOp>(
253 builder.getUnknownLoc(), flowID++, keep_pkt_header, ctrl_pkt_flow);
254 Region &r_pktFlow = pktFlow.getPorts();
255 Block *b_pktFlow = builder.createBlock(&r_pktFlow);
256 builder.setInsertionPointToStart(b_pktFlow);
257 builder.create<AIE::PacketSourceOp>(builder.getUnknownLoc(), source,
258 sourceBundle, sourceChannel);
259 builder.create<AIE::PacketDestOp>(builder.getUnknownLoc(), dest, destBundle,
261 builder.create<AIE::EndOp>(builder.getUnknownLoc());
268 WireBundle shimWireBundle,
270 SmallVector<int> availableShimChans;
271 DenseMap<int, AIE::FlowOp> flowOpUsers;
272 const auto &targetModel = device.getTargetModel();
274 for (
auto user : shimTile.getResult().getUsers()) {
275 auto fOp = dyn_cast<AIE::FlowOp>(user);
278 if (isShimMM2S && fOp.getSource() == shimTile &&
279 fOp.getSourceBundle() == shimWireBundle)
280 flowOpUsers[fOp.getSourceChannel()] = fOp;
281 else if (!isShimMM2S && fOp.getDest() == shimTile &&
282 fOp.getDestBundle() == shimWireBundle)
283 flowOpUsers[fOp.getDestChannel()] = fOp;
285 int numShimChans = 0;
287 numShimChans = targetModel.getNumSourceShimMuxConnections(
288 shimTile.colIndex(), shimTile.rowIndex(), shimWireBundle);
290 numShimChans = targetModel.getNumDestShimMuxConnections(
291 shimTile.colIndex(), shimTile.rowIndex(), shimWireBundle);
292 for (
int i = 0; i < numShimChans; i++) {
293 if (!flowOpUsers.count(i))
294 availableShimChans.push_back(i);
297 return availableShimChans;
303 TileOp shimTile, WireBundle shimWireBundle,
304 SmallVector<AIE::TileOp> ctrlTiles,
305 WireBundle ctrlWireBundle,
307 DenseMap<TileID, int> tileIDMap,
309 int ctrlPktFlowID = 0;
310 auto rowToShimChanMap =
314 auto availableShimChans =
317 builder.setInsertionPoint(device.getBody()->getTerminator());
318 for (
auto tOp : ctrlTiles) {
319 if (tOp->hasAttr(
"controller_id"))
321 (
int)tOp->getAttrOfType<AIE::PacketInfoAttr>(
"controller_id")
324 ctrlPktFlowID = tileIDMap[{tOp.colIndex(), tOp.rowIndex()}];
326 if (!llvm::is_contained(availableShimChans,
327 rowToShimChanMap[tOp.rowIndex()]))
329 "failed to generate column control overlay from shim dma to tile "
330 "ctrl ports, because some shim mm2s dma channels were reserved "
331 "from routing control packets.");
333 auto keep_pkt_header = builder.getBoolAttr(
true);
334 auto ctrl_pkt_flow = builder.getBoolAttr(
true);
337 builder, ctrlPktFlowID, shimTile, shimWireBundle,
338 rowToShimChanMap[tOp.rowIndex()], tOp, ctrlWireBundle,
339 coreOrMemChanId, keep_pkt_header, ctrl_pkt_flow);
342 coreOrMemChanId, shimTile, shimWireBundle,
343 rowToShimChanMap[tOp.rowIndex()],
344 keep_pkt_header, ctrl_pkt_flow);
348 if (shimWireBundle != WireBundle::DMA)
351 AIE::DMAChannelDir dir =
352 isShimMM2S ? AIE::DMAChannelDir::MM2S : AIE::DMAChannelDir::S2MM;
353 int chan = rowToShimChanMap[tOp.rowIndex()];
354 int col = shimTile.colIndex();
355 std::string dma_name =
"ctrlpkt";
356 dma_name +=
"_col" + std::to_string(
col);
357 dma_name += isShimMM2S ?
"_mm2s" :
"_s2mm";
358 dma_name +=
"_chan" + std::to_string(chan);
361 if (device.lookupSymbol(dma_name))
364 builder.create<AIE::ShimDMAAllocationOp>(
365 builder.getUnknownLoc(), StringRef(dma_name), dir,
366 rowToShimChanMap[tOp.rowIndex()], shimTile.colIndex(),
false);
367 MemRefType memref_ty = MemRefType::get(
368 ArrayRef<int64_t>{2048}, IntegerType::get(builder.getContext(), 32),
370 builder.create<memref::GlobalOp>(builder.getUnknownLoc(), dma_name,
371 builder.getStringAttr(
"public"),
372 memref_ty,
nullptr,
false,
nullptr);
378 WireBundle srcBundle,
379 int srcChan, TileOp destTile,
380 WireBundle destBundle,
382 AIE::PacketFlowOp result =
nullptr;
383 device.walk([&](AIE::PacketFlowOp fOp) {
384 for (
auto srcOp : fOp.getOps<AIE::PacketSourceOp>()) {
385 if (srcOp.getTile() == srcTile && srcOp.getBundle() == srcBundle &&
386 srcOp.channelIndex() == srcChan) {
391 for (
auto destOp : fOp.getOps<AIE::PacketDestOp>()) {
392 if (destOp.getTile() == destTile && destOp.getBundle() == destBundle &&
393 destOp.channelIndex() == destChan) {