18#include "mlir/Dialect/Arith/IR/Arith.h"
19#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
20#include "mlir/Dialect/Func/IR/FuncOps.h"
21#include "mlir/Dialect/MemRef/IR/MemRef.h"
22#include "mlir/IR/SymbolTable.h"
23#include "mlir/Interfaces/DataLayoutInterfaces.h"
24#include "mlir/Interfaces/SideEffectInterfaces.h"
26#include "mlir/Tools/mlir-translate/MlirTranslateMain.h"
27#include "llvm/ADT/DenseMap.h"
29#include "mlir/Dialect/Utils/StaticValueUtils.h"
30#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/TypeSwitch.h"
32#include "llvm/Support/Format.h"
33#include "llvm/Support/FormatVariadic.h"
34#include "llvm/Support/JSON.h"
35#include "llvm/Support/raw_ostream.h"
52llvm::MutableArrayRef<uint32_t>
53reserveAndGetTail(std::vector<uint32_t> &instructions, uint64_t tailSize) {
54 auto oldSize = instructions.size();
55 auto newSize = oldSize + tailSize;
56 instructions.resize(newSize, 0);
57 return llvm::MutableArrayRef<uint32_t>(instructions.data() + oldSize,
64LogicalResult appendSync(std::vector<uint32_t> &instructions, NpuSyncOp op) {
67 std::optional<uint32_t> direction =
69 std::optional<uint32_t> channel =
71 std::optional<uint32_t> columnNum =
74 if (!column || !row || !direction || !channel || !columnNum || !rowNum)
75 return op.emitOpError(
"Cannot translate sync with non-constant operands to "
76 "a static TXN binary");
78 *channel, *columnNum, *rowNum);
82LogicalResult appendWrite32(std::vector<uint32_t> &instructions,
85 return op.emitOpError(
"Cannot translate symbolic address");
86 std::optional<uint32_t> address = op.getAbsoluteAddress();
88 if (!address || !value)
89 return op.emitOpError(
90 "Cannot translate write32 with non-constant address or value "
91 "to a static TXN binary");
96LogicalResult appendMaskWrite32(std::vector<uint32_t> &instructions,
97 NpuMaskWrite32Op op) {
99 return op.emitOpError(
"Cannot translate symbolic address");
100 std::optional<uint32_t> address = op.getAbsoluteAddress();
103 if (!address || !value || !mask)
104 return op.emitOpError(
"Cannot translate maskwrite32 with non-constant "
105 "address, value, or mask to a static TXN binary");
110LogicalResult appendMaskPoll(std::vector<uint32_t> &instructions,
113 return op.emitOpError(
"Cannot translate symbolic address");
114 std::optional<uint32_t> address = op.getAbsoluteAddress();
117 if (!address || !value || !mask)
118 return op.emitOpError(
"Cannot translate maskpoll with non-constant "
119 "address, value, or mask to a static TXN binary");
124void appendLoadPdi(std::vector<uint32_t> &instructions, NpuLoadPdiOp op) {
129LogicalResult appendAddressPatch(std::vector<uint32_t> &instructions,
130 NpuAddressPatchOp op,
bool foldDDRAddrOffset) {
132 return op.emitOpError(
"Cannot translate address_patch with a runtime "
133 "register address (addr_val) to a static TXN binary; "
134 "the runtime-bd_id pool path targets the C++ TXN "
136 std::optional<uint64_t> argPlus =
139 return op.emitOpError(
"Cannot translate address_patch with non-constant "
140 "arg_plus to a static TXN binary");
141 std::optional<uint32_t> argIdx = op.getArgIdx();
143 return op.emitOpError(
"address_patch still names its host buffer by SSA "
144 "value; run -aie-resolve-address-patch-buffers");
146 *argPlus, foldDDRAddrOffset);
161static DenseIntElementsAttr cachedBlockWriteData(
162 NpuBlockWriteOp op, mlir::SymbolTable &symTab,
163 llvm::DenseMap<mlir::StringAttr, DenseIntElementsAttr> &cache) {
164 auto getGlobal = op.getData().getDefiningOp<mlir::memref::GetGlobalOp>();
166 return op.getDataWords();
168 mlir::StringAttr key = getGlobal.getNameAttr().getRootReference();
169 auto it = cache.find(key);
170 if (it != cache.end())
175 mlir::DataLayout dataLayout = mlir::DataLayout::closest(op);
176 if (dataLayout.getTypeSizeInBits(
177 mlir::cast<mlir::MemRefType>(op.getData().getType())
178 .getElementType()) != 32)
179 return op.getDataWords();
180 DenseIntElementsAttr data;
182 dyn_cast_if_present<mlir::memref::GlobalOp>(symTab.lookup(key)))
183 if (
auto initVal = global.getInitialValue())
184 data = dyn_cast<DenseIntElementsAttr>(*initVal);
186 data = op.getDataWords();
191LogicalResult appendBlockWrite(
192 std::vector<uint32_t> &instructions, NpuBlockWriteOp op,
193 std::optional<uint32_t> address, mlir::SymbolTable &symTab,
194 llvm::DenseMap<mlir::StringAttr, DenseIntElementsAttr> &dataCache) {
196 return op.emitOpError(
197 "Cannot translate blockwrite with unresolved address to a static TXN "
199 DenseIntElementsAttr data = cachedBlockWriteData(op, symTab, dataCache);
203 std::vector<uint32_t> payload;
204 payload.reserve(data.size());
205 if (
auto words = data.tryGetValues<uint32_t>(); succeeded(words))
207 payload.assign(words->begin(), words->end());
210 payload.push_back(d.getZExtValue());
214 auto col = op.getColumn();
215 auto row = op.getRow();
216 uint32_t colVal = 0, rowVal = 0;
222 payload.size(), colVal, rowVal);
226void appendPreempt(std::vector<uint32_t> &instructions, NpuPreemptOp op) {
230void appendCreateScratchpad(std::vector<uint32_t> &instructions,
231 NpuCreateScratchpadOp op) {
238 auto words = reserveAndGetTail(instructions, 4);
241 words[0] |= (
static_cast<uint32_t
>(op.getUsageType()) << 8);
242 words[1] = op.getSize();
250LogicalResult appendUpdateRegFromScratchpad(std::vector<uint32_t> &instructions,
251 NpuUpdateFromScratchpadOp op,
253 std::optional<uint32_t> address = op.getAbsoluteAddress(&names);
255 return op.emitOpError(
"Cannot translate update_from_scratchpad with "
256 "unresolved address to a static TXN binary");
264 auto words = reserveAndGetTail(instructions, 3);
267 words[0] |= (
static_cast<uint32_t
>(op.getStateTableIdx()) << 8);
268 words[0] |= (
static_cast<uint32_t
>(op.getFunc()) << 16);
269 words[1] = op.getFuncArg();
282 static std::unique_ptr<xilinx::AIE::RegisterDatabase> db = []() {
293static llvm::StringRef
294lookupRegisterByAddress(uint64_t address,
const AIETargetModel &tm,
296 std::string &outModule) {
302 uint8_t col =
static_cast<uint8_t
>((address >> colShift) & 0xFF);
303 uint8_t row =
static_cast<uint8_t
>((address >> rowShift) & 0xFF);
304 uint64_t baseMask = (uint64_t{1} << rowShift) - 1;
305 uint32_t offset =
static_cast<uint32_t
>(address & baseMask);
309 StringRef moduleName;
313 moduleName =
"memory_tile";
322 outModule =
"memory";
328 outModule = moduleName.str();
334static void pushLocEntry(std::vector<TxnLocEntry> *locmap,
335 uint32_t byteOffsetBefore, uint32_t byteOffsetAfter,
336 StringRef opcodeName, StringRef sourceOpName,
337 std::optional<uint64_t> address, mlir::Operation *op,
343 e.
byteSize = byteOffsetAfter - byteOffsetBefore;
347 e.
loc = op->getLoc();
350 lookupRegisterByAddress(*address, tm, getRegDB(), e.
registerModule);
355 locmap->push_back(std::move(e));
360 TxnEncoder(DeviceOp device, std::vector<uint32_t> &instructions,
361 std::vector<TxnLocEntry> *locmap,
bool foldDDRAddrOffset,
362 NpuConfigCache &configs)
364 symTab(device.getOperation()), names(device.getOperation()),
365 configs(configs), instructions(instructions), locmap(locmap),
366 foldDDRAddrOffset(foldDDRAddrOffset) {}
368 void encode(Operation &o);
369 LogicalResult encodeConfig(DeviceOp configured,
bool teardown,
370 NpuConfigCache::Config &config);
371 void appendConfig(Operation *op, FlatSymbolRefAttr deviceRef,
bool teardown);
374 const AIETargetModel &tm;
378 mlir::SymbolTable symTab;
380 llvm::DenseMap<mlir::StringAttr, DenseIntElementsAttr> blockWriteDataCache;
381 NpuConfigCache &configs;
382 std::vector<uint32_t> &instructions;
383 std::vector<TxnLocEntry> *locmap;
384 bool foldDDRAddrOffset;
390 LogicalResult result = success();
396LogicalResult TxnEncoder::encodeConfig(DeviceOp configured,
bool teardown,
398 MLIRContext *ctx = device.getContext();
399 ctx->getOrLoadDialect<arith::ArithDialect>();
400 ctx->getOrLoadDialect<memref::MemRefDialect>();
401 OpBuilder builder(ctx);
402 OwningOpRef<ModuleOp> scratch = ModuleOp::create(device.getLoc());
403 builder.setInsertionPointToStart(scratch->getBody());
405 DeviceOp::create(builder, device.getLoc(), configured.getDevice(),
406 configured.getSymName());
407 holder.getRegion().emplaceBlock();
408 DeviceOp::ensureTerminator(holder.getBodyRegion(), builder, device.getLoc());
409 builder.setInsertionPointToStart(holder.getBody());
410 auto seq = RuntimeSequenceOp::create(
411 builder, device.getLoc(), builder.getStringAttr(
"configure"), BoolAttr{},
412 TraceBufferAttr{}, ArrayAttr{}, ArrayAttr{});
413 Block *body =
new Block;
414 seq.getBody().push_back(body);
415 builder.setInsertionPointToStart(body);
416 BlockwriteData payloads(holder, teardown ?
"teardown_" :
"loadpdi_");
423 TxnEncoder encoder(holder, config.
words, &config.
locmap, foldDDRAddrOffset,
425 for (Operation &op : *body)
427 config.
count = encoder.count;
428 return encoder.result;
431void TxnEncoder::appendConfig(Operation *op, FlatSymbolRefAttr deviceRef,
433 auto configured = dyn_cast_or_null<DeviceOp>(
434 SymbolTable::lookupSymbolIn(device->getParentOp(), deviceRef));
435 const NpuConfigCache::Config *config =
438 [&](NpuConfigCache::Config &c) {
439 return encodeConfig(configured, teardown, c);
443 op->emitOpError(teardown ?
"cannot generate the teardown of "
444 :
"cannot generate the configuration of ")
449 uint32_t base =
static_cast<uint32_t
>(instructions.size() *
sizeof(uint32_t));
450 llvm::append_range(instructions, config->
words);
451 count += config->
count;
453 for (TxnLocEntry entry : config->
locmap) {
455 locmap->push_back(std::move(entry));
459void TxnEncoder::encode(Operation &o) {
460 auto byteOffset = [&]() -> uint32_t {
461 return static_cast<uint32_t
>(instructions.size() *
sizeof(uint32_t));
463 llvm::TypeSwitch<Operation *>(&o)
464 .Case<cf::AssertOp>([&](
auto op) {
469 auto c = getConstantIntValue(op.getArg());
471 op.emitOpError(
"is violated at compile time: ") << op.getMsg();
474 op.emitOpError(
"runtime check cannot be encoded in a static TXN "
475 "binary; use the C++ builder (--aie-npu-to-cpp) "
476 "or specialize the value: ")
481 .Case<NpuSyncOp>([&](
auto op) {
483 uint32_t before = byteOffset();
484 if (failed(appendSync(instructions, op)))
486 pushLocEntry(locmap, before, byteOffset(),
"TCT",
487 op->getName().getStringRef(), std::nullopt, op, tm);
489 .Case<NpuWrite32Op>([&](
auto op) {
491 uint32_t before = byteOffset();
492 uint64_t addr = op.getAbsoluteAddress().value_or(0);
493 if (failed(appendWrite32(instructions, op)))
495 pushLocEntry(locmap, before, byteOffset(),
"WRITE32",
496 op->getName().getStringRef(), addr, op, tm);
498 .Case<NpuBlockWriteOp>([&](
auto op) {
500 uint32_t before = byteOffset();
501 std::optional<uint32_t> addr = op.getAbsoluteAddress(&names);
502 if (failed(appendBlockWrite(instructions, op, addr, symTab,
503 blockWriteDataCache)))
505 pushLocEntry(locmap, before, byteOffset(),
"BLOCKWRITE",
506 op->getName().getStringRef(), addr.value_or(0), op, tm);
508 .Case<NpuBlockWriteValuesOp>([&](
auto op) {
511 op.emitOpError(
"cannot translate a runtime-valued blockwrite "
512 "payload to a static TXN binary; this op is "
513 "supported only by the C++ TXN target "
514 "(--aie-npu-to-cpp)");
517 .Case<NpuMaskWrite32Op>([&](
auto op) {
519 uint32_t before = byteOffset();
520 uint64_t addr = op.getAbsoluteAddress().value_or(0);
521 if (failed(appendMaskWrite32(instructions, op)))
523 pushLocEntry(locmap, before, byteOffset(),
"MASKWRITE",
524 op->getName().getStringRef(), addr, op, tm);
526 .Case<NpuMaskPollOp>([&](
auto op) {
528 uint32_t before = byteOffset();
529 uint64_t addr = op.getAbsoluteAddress().value_or(0);
530 if (failed(appendMaskPoll(instructions, op)))
532 pushLocEntry(locmap, before, byteOffset(),
"MASKPOLL",
533 op->getName().getStringRef(), addr, op, tm);
535 .Case<NpuLoadPdiOp>([&](
auto op) {
537 uint32_t before = byteOffset();
538 appendLoadPdi(instructions, op);
539 pushLocEntry(locmap, before, byteOffset(),
"LOAD_PDI",
540 op->getName().getStringRef(), std::nullopt, op, tm);
542 .Case<NpuAddressPatchOp>([&](
auto op) {
544 uint32_t before = byteOffset();
545 if (failed(appendAddressPatch(instructions, op, foldDDRAddrOffset)))
547 pushLocEntry(locmap, before, byteOffset(),
"ADDRESS_PATCH",
548 op->getName().getStringRef(), op.getAddr(), op, tm);
550 .Case<NpuPreemptOp>([&](
auto op) {
552 uint32_t before = byteOffset();
553 appendPreempt(instructions, op);
554 pushLocEntry(locmap, before, byteOffset(),
"PREEMPT",
555 op->getName().getStringRef(), std::nullopt, op, tm);
557 .Case<NpuCreateScratchpadOp>([&](
auto op) {
559 uint32_t before = byteOffset();
560 appendCreateScratchpad(instructions, op);
561 pushLocEntry(locmap, before, byteOffset(),
"CREATE_SCRATCHPAD",
562 op->getName().getStringRef(), std::nullopt, op, tm);
564 .Case<NpuUpdateFromScratchpadOp>([&](
auto op) {
566 uint32_t before = byteOffset();
567 if (failed(appendUpdateRegFromScratchpad(instructions, op, names)))
569 pushLocEntry(locmap, before, byteOffset(),
"UPDATE_FROM_SCRATCHPAD",
570 op->getName().getStringRef(), std::nullopt, op, tm);
572 .Case<NpuWriteConfigOp>([&](
auto op) {
573 appendConfig(op, op.getDeviceRefAttr(),
false);
575 .Case<NpuWriteTeardownOp>([&](
auto op) {
576 appendConfig(op, op.getDeviceRefAttr(),
true);
578 .Default([&](Operation *op) {
582 if (isMemoryEffectFree(op) || op->hasTrait<OpTrait::IsTerminator>() ||
583 isa<NpuControlPacketOp>(op))
585 op->emitOpError(
"has no static TXN encoding");
593 Operation *device,
bool teardown,
594 llvm::function_ref<LogicalResult(
Config &)> encode) {
595 std::lock_guard<std::mutex> lock(mutex);
596 auto [it, inserted] = configs[teardown].try_emplace(device);
598 auto config = std::make_unique<Config>();
599 if (succeeded(encode(*config)))
600 it->second = std::move(config);
602 return it->second.get();
606 mlir::ModuleOp moduleOp, std::vector<uint32_t> &instructions,
607 StringRef deviceName, StringRef sequenceName,
608 std::vector<TxnLocEntry> *locmap,
bool foldDDRAddrOffset,
612 DeviceOp::getForSymbolInModuleOrError(moduleOp, deviceName);
626 AIE::RuntimeSequenceOp seq =
627 AIE::RuntimeSequenceOp::getForSymbolInDeviceOrError(deviceOp,
634 TxnEncoder encoder(deviceOp, instructions, locmap, foldDDRAddrOffset,
635 configs ? *configs : ownConfigs);
636 for (Block &block : seq.getBody())
637 for (Operation &o : block)
639 if (failed(encoder.result))
648 ModuleOp module, std::vector<uint32_t> &instructions, StringRef deviceName,
649 StringRef sequenceName, std::vector<TxnLocEntry> *locmap) {
651 AIE::DeviceOp::getForSymbolInModuleOrError(module, deviceName);
655 AIE::RuntimeSequenceOp seq =
656 AIE::RuntimeSequenceOp::getForSymbolInDeviceOrError(deviceOp,
662 const AIETargetModel &tm = deviceOp.getTargetModel();
663 Block &entry = seq.getBody().front();
664 for (
auto &o : entry) {
665 auto packetOp = dyn_cast<AIEX::NpuControlPacketOp>(o);
670 static_cast<uint32_t
>(instructions.size() *
sizeof(uint32_t));
673 auto data = packetOp.getData();
682 auto words = reserveAndGetTail(instructions, 2 + size);
684 std::optional<uint32_t> length = packetOp.getLength();
688 auto parity = [](uint32_t n) {
698 int col = packetOp.getColumnFromAddr();
699 int row = packetOp.getRowFromAddr();
700 DeviceOp deviceOp2 = packetOp->getParentOfType<AIE::DeviceOp>();
701 OpBuilder builder2 = OpBuilder::atBlockBegin(deviceOp2.getBody());
702 auto destTile = TileOp::getOrCreate(builder2, deviceOp2, col, row);
703 auto info = destTile->getAttrOfType<AIE::PacketInfoAttr>(
"controller_id");
706 hdr = (info.getPktType() & 0x7) << 12 | (info.assignedId() & 0xff);
707 words[0] = hdr | (0x1 & parity(hdr)) << 31;
714 bool sizeFromLength = !data && length;
715 const char *what = sizeFromLength ?
"length" :
"payload";
717 return packetOp.emitOpError()
719 <<
" is empty; a control packet must carry at least 1 "
721 if (size > AIEX::NpuControlPacketOp::getMaxDataWords())
722 return packetOp.emitOpError()
723 << what <<
" is " << size
724 <<
" words; a control packet carries at most "
725 << AIEX::NpuControlPacketOp::getMaxDataWords()
726 <<
" on the wire. Run --aie-legalize-control-packet before "
729 uint32_t addr = packetOp.getAddress() & 0xFFFFF;
730 uint32_t beats = size - 1;
731 uint32_t opc = packetOp.getOpcode();
732 uint32_t
id = packetOp.getStreamId();
733 hdr =
id << 24 | opc << 22 | beats << 20 | addr;
734 words[1] = hdr | (0x1 & parity(hdr)) << 31;
737 if (opc == 0x0 || opc == 0x2) {
739 return packetOp.emitOpError(
740 "control packet with a write opcode requires a data payload");
741 for (
unsigned i = 0; i < size; i++)
742 words[i + 2] = (*data)[i];
746 static_cast<uint32_t
>(instructions.size() *
sizeof(uint32_t));
747 pushLocEntry(locmap, before, after,
"CONTROL_PACKET",
748 packetOp->getName().getStringRef(), packetOp.getAddress(),
757static llvm::json::Value locToJSON(mlir::Location loc) {
758 using namespace llvm;
759 if (
auto f = dyn_cast<mlir::FileLineColLoc>(loc))
760 return json::Value(json::Object{
762 {
"file", f.getFilename().str()},
763 {
"line",
static_cast<int64_t
>(f.getLine())},
764 {
"col",
static_cast<int64_t
>(f.getColumn())},
766 if (
auto n = dyn_cast<mlir::NameLoc>(loc)) {
767 json::Object o{{
"kind",
"name"}, {
"name", n.getName().str()}};
768 o[
"child"] = locToJSON(n.getChildLoc());
769 return json::Value(std::move(o));
771 if (
auto fused = dyn_cast<mlir::FusedLoc>(loc)) {
772 json::Array children;
773 for (mlir::Location c : fused.getLocations())
774 children.push_back(locToJSON(c));
776 json::Object{{
"kind",
"fused"}, {
"children", std::move(children)}});
778 if (
auto cs = dyn_cast<mlir::CallSiteLoc>(loc))
779 return json::Value(json::Object{
780 {
"kind",
"callsite"},
781 {
"callee", locToJSON(cs.getCallee())},
782 {
"caller", locToJSON(cs.getCaller())},
784 if (isa<mlir::OpaqueLoc>(loc))
785 return json::Value(json::Object{{
"kind",
"opaque"}});
786 return json::Value(json::Object{{
"kind",
"unknown"}});
790 llvm::StringRef deviceName,
791 llvm::StringRef binaryName,
792 const std::vector<TxnLocEntry> &locmap) {
793 llvm::json::Object root;
795 root[
"device"] = deviceName.str();
796 root[
"binary"] = binaryName.str();
798 llvm::json::Array opsArr;
799 for (
const auto &e : locmap) {
800 llvm::json::Object o;
801 o[
"byte_offset"] =
static_cast<int64_t
>(e.
byteOffset);
802 o[
"byte_size"] =
static_cast<int64_t
>(e.
byteSize);
806 o[
"address"] = llvm::formatv(
"{0:X}", *e.
address).str();
812 o[
"loc"] = locToJSON(*e.
loc);
813 opsArr.push_back(std::move(o));
815 root[
"operations"] = std::move(opsArr);
817 output << llvm::formatv(
"{0:2}\n", llvm::json::Value(std::move(root)));
bool isMemTile(int col, int row) const
Return true if the given tile is a Mem tile.
bool isShimPLTile(int col, int row) const
Return true if the given tile is a ShimPL tile.
virtual int rows() const =0
Return the number of rows in the device.
bool isShimNOCTile(int col, int row) const
Return true if the given tile is a ShimNOC tile.
virtual uint32_t getColumnShift() const =0
virtual int columns() const =0
Return the number of columns in the device.
virtual uint32_t getNumMemTileRows() const =0
virtual uint32_t getRowShift() const =0
const Config * getOrEncode(mlir::Operation *device, bool teardown, llvm::function_ref< mlir::LogicalResult(Config &)> encode)
Register and event database for a specific architecture.
static std::unique_ptr< RegisterDatabase > loadAIE2()
Load database for AIE2 architecture.
const RegisterInfo * lookupRegisterByOffset(uint32_t offset, llvm::StringRef module) const
Lookup register by tile-relative offset and module name.
void txn_append_maskpoll32(std::vector< uint32_t > &txn, uint32_t addr, uint32_t val, uint32_t mask)
void txn_append_loadpdi(std::vector< uint32_t > &txn, uint32_t id, uint32_t size, uint64_t addr)
void txn_append_write32(std::vector< uint32_t > &txn, uint32_t addr, uint32_t val)
void txn_init(std::vector< uint32_t > &txn)
void txn_append_sync(std::vector< uint32_t > &txn, uint32_t col, uint32_t row, uint32_t dir, uint32_t chan, uint32_t ncol, uint32_t nrow)
void txn_append_preempt(std::vector< uint32_t > &txn, uint32_t level)
void txn_append_arg_patch(std::vector< uint32_t > &txn, uint32_t addr, int32_t arg_idx, uint64_t arg_plus, bool fold_ddr_addr_offset)
TxnDeviceInfo txn_device_info(uint8_t dev_gen, uint8_t num_rows, uint8_t num_cols, uint8_t num_memtile_rows)
@ TXN_OPC_CREATE_SCRATCHPAD
void txn_append_maskwrite32(std::vector< uint32_t > &txn, uint32_t addr, uint32_t val, uint32_t mask)
void txn_append_blockwrite(std::vector< uint32_t > &txn, uint32_t addr, const uint32_t *data, size_t count, uint32_t col=0, uint32_t row=0)
void txn_prepend_header(std::vector< uint32_t > &txn, uint32_t op_count, TxnDeviceInfo info={})
std::optional< uint64_t > getConstantInt64Operand(mlir::Value v)
std::optional< uint32_t > getConstantIntOperand(mlir::Value v)
void emitNpuLocmapJSON(llvm::raw_ostream &output, llvm::StringRef deviceName, llvm::StringRef binaryName, const std::vector< TxnLocEntry > &locmap)
uint8_t txnDeviceGen(const AIETargetModel &tm)
Device generation ID written into the TXN header (aie_runtime::TxnDeviceInfo::devGen).
mlir::LogicalResult AIETranslateControlPacketsToUI32Vec(mlir::ModuleOp, std::vector< uint32_t > &, llvm::StringRef deviceName="", llvm::StringRef sequenceName="", std::vector< TxnLocEntry > *locmap=nullptr)
mlir::LogicalResult AIETranslateNpuToBinary(mlir::ModuleOp, std::vector< uint32_t > &, llvm::StringRef deviceName="", llvm::StringRef sequenceName="", std::vector< TxnLocEntry > *locmap=nullptr, bool foldDDRAddrOffset=true, NpuConfigCache *configs=nullptr)
mlir::LogicalResult generateAndInsertConfigOps(mlir::OpBuilder &builder, xilinx::AIE::DeviceOp device, xilinx::AIEX::BlockwriteData &blockwriteData, llvm::StringRef clElfDir="", AIEToConfigurationOutputType outputType=AIEToConfigurationOutputType::Transaction, bool skipCtrlPktOverlay=false)
const AIETargetModel & getTargetModel(mlir::Operation *op)
mlir::LogicalResult generateAndInsertTeardownOps(mlir::OpBuilder &builder, xilinx::AIE::DeviceOp device, xilinx::AIEX::BlockwriteData &blockwriteData, AIEToConfigurationOutputType outputType=AIEToConfigurationOutputType::Transaction)
std::vector< uint32_t > words
std::vector< TxnLocEntry > locmap
std::optional< uint64_t > address
std::string registerModule
std::optional< mlir::Location > loc