MLIR-AIE
AIETargetBCF.cpp
Go to the documentation of this file.
1//===- AIETargetBCF.cpp -----------------------------------------*- C++ -*-===//
2//
3// Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7
11
12#include "mlir/IR/IRMapping.h"
13#include "mlir/Pass/Pass.h"
14#include "mlir/Tools/mlir-translate/MlirTranslateMain.h"
15
16#include "llvm/ADT/StringExtras.h"
17#include "llvm/IR/Module.h"
18
19using namespace mlir;
20using namespace xilinx;
21using namespace xilinx::AIE;
22using namespace xilinx::AIEX;
23
24std::string utohexstr(uint32_t u) { return "0x" + llvm::utohexstr(u); }
25
26namespace xilinx {
27namespace AIE {
28
29LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output,
30 int tileCol, int tileRow) {
31 DenseMap<TileID, Operation *> tiles;
32 DenseMap<Operation *, SmallVector<BufferOp, 4>> buffers;
33
34 if (module.getOps<DeviceOp>().empty())
35 module.emitOpError("expected aie.device operation at toplevel");
36 DeviceOp targetOp = *(module.getOps<DeviceOp>().begin());
37
38 collectTiles(targetOp, tiles);
39 collectBuffers(targetOp, buffers);
40
41 // _entry_point _main_init
42 // _symbol _main _after _main_init
43 // _symbol _main_init 0
44 // _reserved DMb 0x00000 0x20000
45 // _symbol a 0x38000 0x2000
46 // _extern a
47 // _stack DM_stack 0x20000 0x400 //stack for core
48 // _reserved DMb 0x40000 0xc0000 // And everything else the core can't
49 // see
50 // // Include all symbols from rom.c
51 // _include _file rom.o
52 for (auto tile : targetOp.getOps<TileOp>())
53 if (tile.colIndex() == tileCol && tile.rowIndex() == tileRow) {
54 const auto &targetModel = getTargetModel(tile);
55 TileID srcCoord = {tile.colIndex(), tile.rowIndex()};
56
57 std::string corefunc = std::string("core_") +
58 std::to_string(tile.getCol()) + "_" +
59 std::to_string(tile.getRow());
60 output << "_entry_point _main_init\n";
61 output << "_symbol " << corefunc << " _after _main_init\n";
62 output << "_symbol _main_init 0\n";
63 int dataMemoryStart = targetModel.getMemSouthBaseAddress();
64 output << "_reserved DMb 0x00000 " << utohexstr(dataMemoryStart)
65 << " // Don't put data in code memory\n";
66
67 int stacksize = 0;
68 if (auto core = tile.getCoreOp())
69 stacksize = core.getStackSize();
70 output << "_stack DM_stack "
71 << utohexstr(targetModel.getMemInternalBaseAddress(srcCoord))
72 << " " << utohexstr(stacksize) << " // stack for core\n";
73
74 auto doBuffer = [&](std::optional<TileID> tile, int offset,
75 const std::string &dir) {
76 if (tile) {
77 output << "// " + dir +
78
79 " -------------------------------------------------\n";
80 uint32_t localMemSize = targetModel.getLocalMemorySize();
81 if (tile != srcCoord)
82 output << "_reserved DMb " << utohexstr(offset) << " "
83 << utohexstr(localMemSize) << " "
84 << " // Don't allocate variables in " << dir
85 << " neighbor\n\n";
86 // TODO How to set as reserved if no buffer exists (or reserve
87 // remaining buffer)
88 if (tiles.count(*tile)) {
89 for (auto buf : buffers[tiles[*tile]]) {
90 std::string bufName(buf.name().getValue());
91 int bufferBaseAddr = getBufferBaseAddress(buf);
92 int numBytes = buf.getAllocationSize();
93 if (buf.getInitialValue() && tile != srcCoord) {
94 output << "// skip initialization of " << buf.name()
95 << " which is initialized "
96 "in the neighboring tile\n";
97 output << "\n";
98 continue;
99 } else if (buf.getInitialValue() && tile == srcCoord) {
100 output << "_overlay " << bufName << " "
101 << utohexstr(offset + bufferBaseAddr) << " // "
102 << numBytes << " bytes\n";
103 } else {
104 output << "_symbol " << bufName << " "
105 << utohexstr(offset + bufferBaseAddr) << " " << numBytes
106 << '\n';
107 output << "_extern " << bufName << "\n";
108 output << "_reserved DMb " << utohexstr(offset + bufferBaseAddr)
109 << " " << numBytes << '\n';
110 }
111 output << "\n";
112 }
113 }
114 } else {
115 uint32_t localMemSize = targetModel.getLocalMemorySize();
116 output << "_reserved DMb " << utohexstr(offset) << " "
117 << utohexstr(localMemSize) << " "
118 << " // No tile with memory exists to the " << dir << ".\n";
119 }
120 };
121
122 output << "\n// mapping neighbors tile memory\n";
123 doBuffer(targetModel.getMemSouth(srcCoord),
124 targetModel.getMemSouthBaseAddress(), std::string("south"));
125 doBuffer(targetModel.getMemWest(srcCoord),
126 targetModel.getMemWestBaseAddress(), std::string("west"));
127 doBuffer(targetModel.getMemNorth(srcCoord),
128 targetModel.getMemNorthBaseAddress(), std::string("north"));
129 doBuffer(targetModel.getMemEast(srcCoord),
130 targetModel.getMemEastBaseAddress(), std::string("east"));
131 output << "// end mapping neighbors tile memory\n\n";
132
133 int addressSpaceSize = 0x100000;
134 int dataMemoryEnd = targetModel.getMemEastBaseAddress() +
135 targetModel.getLocalMemorySize();
136 output << "_reserved DMb " << utohexstr(dataMemoryEnd) << " "
137 << utohexstr(addressSpaceSize - dataMemoryEnd)
138 << " // And everything else the core can't see\n";
139
140 if (tile.getCoreOp() && tile.getCoreOp().getLinkWith())
141 output << "_include _file "
142 << tile.getCoreOp().getLinkWith().value().str() << "\n";
143 output << "_resolve _main core_" << tile.getCol() << "_" << tile.getRow()
144 << "\n";
145 }
146
147 return success();
148}
149} // namespace AIE
150} // namespace xilinx
std::string utohexstr(uint32_t u)
Include the generated interface declarations.
mlir::LogicalResult AIETranslateToBCF(mlir::ModuleOp module, llvm::raw_ostream &output, int tileCol, int tileRow)
TileID { friend std::ostream &operator<<(std::ostream &os, const TileID &s) { os<< "TileID("<< s.col<< ", "<< s.row<< ")" TileID
int32_t getBufferBaseAddress(mlir::Operation *bufOp)
const AIETargetModel & getTargetModel(mlir::Operation *op)