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/ADT/StringRef.h"
18#include "llvm/IR/Module.h"
19
20using namespace mlir;
21using namespace xilinx;
22using namespace xilinx::AIE;
23using namespace xilinx::AIEX;
24
25std::string utohexstr(uint32_t u) { return "0x" + llvm::utohexstr(u); }
26
27namespace xilinx {
28namespace AIE {
29
30LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output,
31 int tileCol, int tileRow,
32 llvm::StringRef deviceName) {
33 DenseMap<TileID, Operation *> tiles;
34 DenseMap<Operation *, SmallVector<BufferOp, 4>> buffers;
35
36 DeviceOp targetOp = AIE::DeviceOp::getForSymbolInModule(module, deviceName);
37 if (!targetOp)
38 module.emitOpError("expected aie.device operation at toplevel");
39
40 collectTiles(targetOp, tiles);
41 collectBuffers(targetOp, buffers);
42
43 // _entry_point _main_init
44 // _symbol _main _after _main_init
45 // _symbol _main_init 0
46 // _reserved DMb 0x00000 0x20000
47 // _symbol a 0x38000 0x2000
48 // _extern a
49 // _stack DM_stack 0x20000 0x400 //stack for core
50 // _reserved DMb 0x40000 0xc0000 // And everything else the core can't
51 // see
52 // // Include all symbols from rom.c
53 // _include _file rom.o
54 for (auto tile : targetOp.getOps<TileOp>())
55 if (tile.colIndex() == tileCol && tile.rowIndex() == tileRow) {
56 const auto &targetModel = getTargetModel(tile);
57 TileID srcCoord = {tile.colIndex(), tile.rowIndex()};
58
59 std::string corefunc = std::string("core_") +
60 std::to_string(tile.getCol()) + "_" +
61 std::to_string(tile.getRow());
62 output << "_entry_point _main_init\n";
63 output << "_symbol " << corefunc << " _after _main_init\n";
64 output << "_symbol _main_init 0\n";
65 int dataMemoryStart = targetModel.getMemSouthBaseAddress();
66 output << "_reserved DMb 0x00000 " << utohexstr(dataMemoryStart)
67 << " // Don't put data in code memory\n";
68
69 int stacksize = 0;
70 if (auto core = tile.getCoreOp())
71 stacksize = core.getStackSize();
72 output << "_stack DM_stack "
73 << utohexstr(targetModel.getMemInternalBaseAddress(srcCoord))
74 << " " << utohexstr(stacksize) << " // stack for core\n";
75
76 auto doBuffer = [&](std::optional<TileID> tile, int offset,
77 const std::string &dir) {
78 if (tile) {
79 output << "// " + dir +
80
81 " -------------------------------------------------\n";
82 uint32_t localMemSize = targetModel.getLocalMemorySize();
83 if (tile != srcCoord)
84 output << "_reserved DMb " << utohexstr(offset) << " "
85 << utohexstr(localMemSize) << " "
86 << " // Don't allocate variables in " << dir
87 << " neighbor\n\n";
88 // TODO How to set as reserved if no buffer exists (or reserve
89 // remaining buffer)
90 if (tiles.count(*tile)) {
91 for (auto buf : buffers[tiles[*tile]]) {
92 std::string bufName(buf.name().getValue());
93 int bufferBaseAddr = getBufferBaseAddress(buf);
94 int numBytes = buf.getAllocationSize();
95 if (buf.getInitialValue() && tile != srcCoord) {
96 output << "// skip initialization of " << buf.name()
97 << " which is initialized "
98 "in the neighboring tile\n";
99 output << "\n";
100 continue;
101 } else if (buf.getInitialValue() && tile == srcCoord) {
102 output << "_overlay " << bufName << " "
103 << utohexstr(offset + bufferBaseAddr) << " // "
104 << numBytes << " bytes\n";
105 } else {
106 output << "_symbol " << bufName << " "
107 << utohexstr(offset + bufferBaseAddr) << " " << numBytes
108 << '\n';
109 output << "_extern " << bufName << "\n";
110 output << "_reserved DMb " << utohexstr(offset + bufferBaseAddr)
111 << " " << numBytes << '\n';
112 }
113 output << "\n";
114 }
115 }
116 } else {
117 uint32_t localMemSize = targetModel.getLocalMemorySize();
118 output << "_reserved DMb " << utohexstr(offset) << " "
119 << utohexstr(localMemSize) << " "
120 << " // No tile with memory exists to the " << dir << ".\n";
121 }
122 };
123
124 output << "\n// mapping neighbors tile memory\n";
125 doBuffer(targetModel.getMemSouth(srcCoord),
126 targetModel.getMemSouthBaseAddress(), std::string("south"));
127 doBuffer(targetModel.getMemWest(srcCoord),
128 targetModel.getMemWestBaseAddress(), std::string("west"));
129 doBuffer(targetModel.getMemNorth(srcCoord),
130 targetModel.getMemNorthBaseAddress(), std::string("north"));
131 doBuffer(targetModel.getMemEast(srcCoord),
132 targetModel.getMemEastBaseAddress(), std::string("east"));
133 output << "// end mapping neighbors tile memory\n\n";
134
135 int addressSpaceSize = 0x100000;
136 int dataMemoryEnd = targetModel.getMemEastBaseAddress() +
137 targetModel.getLocalMemorySize();
138 output << "_reserved DMb " << utohexstr(dataMemoryEnd) << " "
139 << utohexstr(addressSpaceSize - dataMemoryEnd)
140 << " // And everything else the core can't see\n";
141
142 if (auto coreOp = tile.getCoreOp()) {
143 if (auto filesAttr = coreOp.getLinkFiles()) {
144 // Canonical path: link_files populated by aie-assign-core-link-files.
145 for (auto f : filesAttr->getAsRange<mlir::StringAttr>())
146 output << "_include _file " << f.getValue() << "\n";
147 } else if (coreOp.getLinkWith()) {
148 // Deprecated fallback: core-level link_with was not migrated by
149 // aie-assign-core-link-files (e.g., the pass was not run).
150 output << "_include _file " << coreOp.getLinkWith().value().str()
151 << "\n";
152 }
153 }
154 output << "_resolve _main core_" << tile.getCol() << "_" << tile.getRow()
155 << "\n";
156 }
157
158 return success();
159}
160} // namespace AIE
161} // namespace xilinx
std::string utohexstr(uint32_t u)
Include the generated interface declarations.
void collectTiles(DeviceOp &device, llvm::DenseMap< TileID, mlir::Operation * > &tiles)
void collectBuffers(DeviceOp &device, llvm::DenseMap< mlir::Operation *, llvm::SmallVector< BufferOp, 4 > > &buffers)
TileID { friend std::ostream &operator<<(std::ostream &os, const TileID &s) { os<< "TileID("<< s.col<< ", "<< s.row<< ")" TileID
int32_t getBufferBaseAddress(mlir::Operation *bufOp)
mlir::LogicalResult AIETranslateToBCF(mlir::ModuleOp module, llvm::raw_ostream &output, int tileCol, int tileRow, llvm::StringRef deviceName="")
const AIETargetModel & getTargetModel(mlir::Operation *op)