11#include "../PassDetail.h"
18#include "llvm/Support/Debug.h"
19#include <llvm/ADT/APInt.h>
22#include "xaiengine/xaiegbl_defs.h"
24#include "xaiengine/xaie_txn.h"
33#define GEN_PASS_DEF_CONVERTAIETOCONTROLPACKETS
34#define GEN_PASS_DEF_CONVERTAIETOTRANSACTION
35#include "aie/Conversion/Passes.h.inc"
38#define DEBUG_TYPE "aie-convert-to-config"
49struct TransactionBinaryOperation {
50 struct XAie_TxnCmd cmd = {};
61 struct LoadPdiPayload {
67 struct AddressPatchPayload {
74 std::optional<SyncPayload> sync;
75 std::optional<LoadPdiPayload> loadPdi;
76 std::optional<AddressPatchPayload> addressPatch;
78 TransactionBinaryOperation() =
default;
80 TransactionBinaryOperation(
XAie_TxnOpcode opc, uint32_t mask, uint64_t addr,
81 uint32_t value,
const uint8_t *data,
87 cmd.DataPtr =
reinterpret_cast<uint64_t
>(data);
92constexpr size_t kTxnHeaderBytes = 16;
94struct TxnPreemptHeader {
100struct TxnLoadPdiHeader {
111static std::optional<int>
112parseTransactionBinary(
const std::vector<uint8_t> &data,
113 std::vector<TransactionBinaryOperation> &ops) {
115 if (data.size() < kTxnHeaderBytes) {
116 llvm::errs() <<
"Transaction binary is too small for header\n";
120 uint32_t
major = data[0];
121 uint32_t
minor = data[1];
122 uint32_t num_cols = data[4];
124 uint32_t num_ops, txn_size;
125 std::memcpy(&num_ops, &data[8], 4);
126 std::memcpy(&txn_size, &data[12], 4);
128 LLVM_DEBUG(llvm::dbgs() <<
"Major: " << major <<
"\n");
129 LLVM_DEBUG(llvm::dbgs() <<
"Minor: " << minor <<
"\n");
130 LLVM_DEBUG(llvm::dbgs() <<
"DevGen: " << data[2] <<
"\n");
131 LLVM_DEBUG(llvm::dbgs() <<
"NumRows: " << data[3] <<
"\n");
132 LLVM_DEBUG(llvm::dbgs() <<
"NumCols: " << num_cols <<
"\n");
133 LLVM_DEBUG(llvm::dbgs() <<
"NumMemTileRows: " << data[5] <<
"\n");
134 LLVM_DEBUG(llvm::dbgs() <<
"NumOps: " << num_ops <<
"\n");
135 LLVM_DEBUG(llvm::dbgs() <<
"TxnSize: " << txn_size <<
" bytes\n");
137 size_t i = kTxnHeaderBytes;
139 auto requireBytes = [&](
size_t offset,
size_t length) ->
bool {
140 if (offset + length > data.size()) {
141 llvm::errs() <<
"Transaction binary truncated while parsing opcode\n";
147 auto read32 = [&](
size_t offset) -> uint32_t {
149 std::memcpy(&value, data.data() + offset,
sizeof(uint32_t));
154 auto convertOpcode = [](uint8_t opc) -> std::optional<uint8_t> {
165 llvm::errs() <<
"Unhandled opcode: " << std::to_string(opc) <<
"\n";
173 if (major == 0 && minor == 1) {
174 while (i < data.size()) {
175 auto maybeOpcode = convertOpcode(data[i]);
179 LLVM_DEBUG(llvm::dbgs() <<
"opcode: " + std::to_string(opcode) <<
"\n");
181 TransactionBinaryOperation op;
182 op.cmd.Opcode = opcode;
186 LLVM_DEBUG(llvm::dbgs() <<
"opcode: WRITE (0x00)\n");
187 if (!requireBytes(i, 24))
189 uint32_t addrLo = read32(i + 8);
190 uint32_t addrHi = read32(i + 12);
191 uint32_t
value = read32(i + 16);
192 uint32_t opSize = read32(i + 20);
193 if (!requireBytes(i, opSize))
195 uint64_t addr = (
static_cast<uint64_t
>(addrHi) << 32) | addrLo;
196 op.cmd.RegOff = addr;
197 op.cmd.Value =
value;
203 LLVM_DEBUG(llvm::dbgs() <<
"opcode: BLOCKWRITE (0x01)\n");
204 if (!requireBytes(i, 16))
206 uint32_t addr = read32(i + 8);
207 uint32_t opSize = read32(i + 12);
208 if (opSize < 16 || !requireBytes(i, opSize))
210 const uint8_t *payload = data.data() + i + 16;
211 uint32_t payloadBytes = opSize - 16;
212 op.cmd.RegOff = addr;
213 op.cmd.DataPtr =
reinterpret_cast<uint64_t
>(payload);
214 op.cmd.Size = payloadBytes;
219 LLVM_DEBUG(llvm::dbgs() <<
"opcode: MASKWRITE (0x03)\n");
220 if (!requireBytes(i, 28))
222 uint32_t addrLo = read32(i + 8);
223 uint32_t addrHi = read32(i + 12);
224 uint32_t
value = read32(i + 16);
225 uint32_t mask = read32(i + 20);
226 uint32_t opSize = read32(i + 24);
227 if (!requireBytes(i, opSize))
229 uint64_t addr = (
static_cast<uint64_t
>(addrHi) << 32) | addrLo;
230 op.cmd.RegOff = addr;
231 op.cmd.Value =
value;
233 op.cmd.Size = opSize;
238 uint32_t opSize = read32(i + 4);
239 if (opSize < 16 || !requireBytes(i, opSize))
241 uint32_t descriptor = read32(i + 8);
242 uint32_t config = read32(i + 12);
243 TransactionBinaryOperation::SyncPayload payload{
244 static_cast<int32_t
>((descriptor >> 16) & 0xff),
245 static_cast<int32_t
>((descriptor >> 8) & 0xff),
246 static_cast<int32_t
>(descriptor & 0xff),
247 static_cast<int32_t
>((config >> 24) & 0xff),
248 static_cast<int32_t
>((config >> 16) & 0xff),
249 static_cast<int32_t
>((config >> 8) & 0xff)};
251 op.cmd.Size = opSize;
256 LLVM_DEBUG(llvm::dbgs() <<
"opcode: LOAD_PDI (0x08)\n");
257 constexpr size_t opSize =
sizeof(TxnLoadPdiHeader);
258 if (!requireBytes(i, opSize))
260 TxnLoadPdiHeader header;
261 std::memcpy(&header, data.data() + i, opSize);
262 TransactionBinaryOperation::LoadPdiPayload payload{
263 header.id, header.size, header.address};
264 op.loadPdi = payload;
265 op.cmd.Size = opSize;
270 uint32_t opSize = read32(i + 4);
271 if (opSize < 44 || !requireBytes(i, opSize))
273 uint32_t action = read32(i + 20);
274 uint32_t addr = read32(i + 24);
275 int32_t argIdx =
static_cast<int32_t
>(read32(i + 32));
276 int32_t argPlus =
static_cast<int32_t
>(read32(i + 40));
277 TransactionBinaryOperation::AddressPatchPayload payload{
278 action, addr, argIdx, argPlus};
279 op.addressPatch = payload;
280 op.cmd.Size = opSize;
285 LLVM_DEBUG(llvm::dbgs() <<
"opcode: PREEMPT (0x06)\n");
286 constexpr size_t opSize =
sizeof(TxnPreemptHeader);
287 if (!requireBytes(i, opSize))
290 reinterpret_cast<const TxnPreemptHeader *
>(data.data() + i);
291 op.cmd.Value = header->level;
292 op.cmd.Size = opSize;
297 llvm::errs() <<
"Unhandled opcode: " << std::to_string(opcode)
298 <<
" for v0.1 transaction\n";
302 ops.push_back(std::move(op));
304 }
else if (major == 1 && minor == 0) {
305 while (i < data.size()) {
306 auto maybeOpcode = convertOpcode(data[i]);
310 LLVM_DEBUG(llvm::dbgs() <<
"opcode: " + std::to_string(opcode) <<
"\n");
312 TransactionBinaryOperation op;
313 op.cmd.Opcode = opcode;
317 LLVM_DEBUG(llvm::dbgs() <<
"opcode: WRITE (0x00)\n");
318 if (!requireBytes(i, 12))
320 uint32_t addr = read32(i + 4);
321 uint32_t
value = read32(i + 8);
322 op.cmd.RegOff = addr;
323 op.cmd.Value =
value;
329 LLVM_DEBUG(llvm::dbgs() <<
"opcode: BLOCKWRITE (0x01)\n");
330 if (!requireBytes(i, 12))
332 uint32_t addr = read32(i + 4);
333 uint32_t opSize = read32(i + 8);
334 if (opSize < 12 || !requireBytes(i, opSize))
336 const uint8_t *payload = data.data() + i + 12;
337 uint32_t payloadBytes = opSize - 12;
338 op.cmd.RegOff = addr;
339 op.cmd.DataPtr =
reinterpret_cast<uint64_t
>(payload);
340 op.cmd.Size = payloadBytes;
345 LLVM_DEBUG(llvm::dbgs() <<
"opcode: MASKWRITE (0x03)\n");
346 if (!requireBytes(i, 16))
348 uint32_t addr = read32(i + 4);
349 uint32_t
value = read32(i + 8);
350 uint32_t mask = read32(i + 12);
351 op.cmd.RegOff = addr;
352 op.cmd.Value =
value;
359 uint32_t opSize = read32(i + 4);
360 if (opSize < 16 || !requireBytes(i, opSize))
362 uint32_t descriptor = read32(i + 8);
363 uint32_t config = read32(i + 12);
364 TransactionBinaryOperation::SyncPayload payload{
365 static_cast<int32_t
>((descriptor >> 16) & 0xff),
366 static_cast<int32_t
>((descriptor >> 8) & 0xff),
367 static_cast<int32_t
>(descriptor & 0xff),
368 static_cast<int32_t
>((config >> 24) & 0xff),
369 static_cast<int32_t
>((config >> 16) & 0xff),
370 static_cast<int32_t
>((config >> 8) & 0xff)};
372 op.cmd.Size = opSize;
377 LLVM_DEBUG(llvm::dbgs() <<
"opcode: LOAD_PDI (0x08)\n");
378 constexpr size_t opSize =
sizeof(TxnLoadPdiHeader);
379 if (!requireBytes(i, opSize))
381 TxnLoadPdiHeader header;
382 std::memcpy(&header, data.data() + i, opSize);
383 TransactionBinaryOperation::LoadPdiPayload payload{
384 header.id, header.size, header.address};
385 op.loadPdi = payload;
386 op.cmd.Size = opSize;
391 uint32_t opSize = read32(i + 4);
392 if (opSize < 44 || !requireBytes(i, opSize))
394 uint32_t action = read32(i + 20);
395 uint32_t addr = read32(i + 24);
396 int32_t argIdx =
static_cast<int32_t
>(read32(i + 32));
397 int32_t argPlus =
static_cast<int32_t
>(read32(i + 40));
398 TransactionBinaryOperation::AddressPatchPayload payload{
399 action, addr, argIdx, argPlus};
400 op.addressPatch = payload;
401 op.cmd.Size = opSize;
406 LLVM_DEBUG(llvm::dbgs() <<
"opcode: PREEMPT (0x06)\n");
407 constexpr size_t opSize =
sizeof(TxnPreemptHeader);
408 if (!requireBytes(i, opSize))
411 reinterpret_cast<const TxnPreemptHeader *
>(data.data() + i);
412 op.cmd.Value = header->level;
413 op.cmd.Size = opSize;
418 llvm::errs() <<
"Unhandled opcode: " << std::to_string(opcode)
419 <<
" for v1.0 transaction\n";
423 ops.push_back(std::move(op));
426 llvm::errs() <<
"Unsupported TXN binary version: " <<
major <<
"." <<
minor
434static LogicalResult generateTransactions(
AIERTControl &ctl,
435 const StringRef workDirPath,
436 DeviceOp &targetOp,
bool aieSim,
437 bool enableElfs,
bool enableInit,
439 if (enableElfs && !targetOp.getOps<CoreOp>().empty() &&
440 failed(ctl.
addAieElfs(targetOp, workDirPath, aieSim)))
444 if (enableCores && !targetOp.getOps<CoreOp>().empty() &&
453emitTransactionOps(OpBuilder &builder,
454 std::vector<TransactionBinaryOperation> &operations,
455 std::vector<memref::GlobalOp> &global_data) {
457 auto loc = builder.getUnknownLoc();
460 for (
auto [op, payload] :
llvm::zip(operations, global_data)) {
463 AIEX::NpuWrite32Op::create(builder, loc, op.cmd.RegOff, op.cmd.Value,
464 nullptr,
nullptr,
nullptr);
466 auto memref = memref::GetGlobalOp::create(builder, loc, payload.getType(),
468 AIEX::NpuBlockWriteOp::create(
469 builder, loc, builder.getUI32IntegerAttr(op.cmd.RegOff),
470 memref.getResult(),
nullptr,
nullptr,
nullptr);
472 AIEX::NpuMaskWrite32Op::create(builder, loc, op.cmd.RegOff, op.cmd.Value,
473 op.cmd.Mask,
nullptr,
nullptr,
nullptr);
476 llvm::errs() <<
"Missing sync payload while emitting transaction\n";
479 const TransactionBinaryOperation::SyncPayload &sync = *op.sync;
480 AIEX::NpuSyncOp::create(builder, loc,
481 builder.getI32IntegerAttr(sync.column),
482 builder.getI32IntegerAttr(sync.row),
483 builder.getI32IntegerAttr(sync.direction),
484 builder.getI32IntegerAttr(sync.channel),
485 builder.getI32IntegerAttr(sync.columnCount),
486 builder.getI32IntegerAttr(sync.rowCount));
487 }
else if (op.cmd.Opcode == 0x8 ) {
489 llvm::errs() <<
"Missing load_pdi payload while emitting transaction\n";
492 const TransactionBinaryOperation::LoadPdiPayload &payloadInfo =
495 builder.getI32IntegerAttr(
static_cast<int32_t
>(payloadInfo.id));
496 IntegerAttr sizeAttr =
497 builder.getI32IntegerAttr(
static_cast<int32_t
>(payloadInfo.size));
500 IntegerType::get(builder.getContext(), 64, IntegerType::Unsigned);
501 IntegerAttr addressAttr =
502 IntegerAttr::get(ui64Ty, llvm::APInt(64, payloadInfo.address));
504 AIEX::NpuLoadPdiOp::create(builder, loc,
nullptr, idAttr, sizeAttr,
507 if (!op.addressPatch) {
509 <<
"Missing address_patch payload while emitting transaction\n";
512 const TransactionBinaryOperation::AddressPatchPayload &
patch =
514 AIEX::NpuAddressPatchOp::create(builder, loc,
515 builder.getUI32IntegerAttr(
patch.addr),
516 builder.getI32IntegerAttr(
patch.argIdx),
517 builder.getI32IntegerAttr(
patch.argPlus));
518 }
else if (op.cmd.Opcode == 0x6 ) {
520 IntegerType::get(builder.getContext(), 8, IntegerType::Unsigned);
521 auto levelAttr = IntegerAttr::get(ui8Ty, llvm::APInt(8, op.cmd.Value));
522 AIEX::NpuPreemptOp::create(builder, loc, levelAttr);
524 llvm::errs() <<
"Unhandled txn opcode: " << op.cmd.Opcode <<
"\n";
534emitControlPacketOps(OpBuilder &builder,
535 std::vector<TransactionBinaryOperation> &operations,
536 std::vector<memref::GlobalOp> &global_data) {
538 auto loc = builder.getUnknownLoc();
539 auto ctx = builder.getContext();
542 for (
auto [op, payload] :
llvm::zip(operations, global_data)) {
545 AIEX::NpuControlPacketOp::create(
546 builder, loc, builder.getUI32IntegerAttr(op.cmd.RegOff),
nullptr,
547 builder.getI32IntegerAttr(0),
548 builder.getI32IntegerAttr(0),
549 DenseI32ArrayAttr::get(ctx, ArrayRef<int32_t>(op.cmd.Value)));
551 if (!payload.getInitialValue())
553 auto blockWriteData =
554 dyn_cast<DenseIntElementsAttr>(*payload.getInitialValue());
555 if (!blockWriteData) {
557 "Global symbol initial value is not a dense int array");
560 auto blockWriteDataValues = blockWriteData.getValues<int32_t>();
562 int currAddr = op.cmd.RegOff;
563 for (
size_t i = 0; i < blockWriteDataValues.size(); i += 4) {
564 auto last = std::min(blockWriteDataValues.size(), i + 4);
565 SmallVector<int32_t> splitData =
566 SmallVector<int32_t>(blockWriteDataValues.begin() + i,
567 blockWriteDataValues.begin() + last);
568 AIEX::NpuControlPacketOp::create(
569 builder, loc, builder.getUI32IntegerAttr(currAddr),
nullptr,
570 builder.getI32IntegerAttr(0),
571 builder.getI32IntegerAttr(0),
572 DenseI32ArrayAttr::get(ctx, ArrayRef<int32_t>(splitData)));
573 currAddr += splitData.size() *
sizeof(int32_t);
577 AIEX::NpuControlPacketOp::create(
578 builder, loc, builder.getUI32IntegerAttr(op.cmd.RegOff),
nullptr,
579 builder.getI32IntegerAttr(0),
580 builder.getI32IntegerAttr(0),
581 DenseI32ArrayAttr::get(ctx, ArrayRef<int32_t>(op.cmd.Value)));
583 llvm::errs() <<
"Unhandled txn opcode: " << op.cmd.Opcode <<
"\n";
593 SmallVector<AIEX::NpuControlPacketOp> ctrlPktOps;
595 [&](AIEX::NpuControlPacketOp cpOp) { ctrlPktOps.push_back(cpOp); });
596 if (ctrlPktOps.empty())
599 SmallVector<Operation *> erased;
600 int addrBuffer = ctrlPktOps[0].getAddress();
601 AIEX::NpuControlPacketOp ctrlPktBuffer = ctrlPktOps[0];
602 for (
size_t i = 1; i < ctrlPktOps.size(); i++) {
603 int currentAddrBuffer = ctrlPktOps[i].getAddress();
604 if (addrBuffer != currentAddrBuffer) {
605 addrBuffer = currentAddrBuffer;
606 ctrlPktBuffer = ctrlPktOps[i];
609 auto bufferedData = ctrlPktBuffer.getData().value();
610 auto currentData = ctrlPktOps[i].getData().value();
611 SmallVector<int> newData;
612 for (
unsigned j = 0; j < std::max(bufferedData.size(), currentData.size());
614 if (j < std::min(bufferedData.size(), currentData.size())) {
615 newData.push_back(bufferedData[j] | currentData[j]);
618 newData.push_back(j < bufferedData.size() ? bufferedData[j]
621 ctrlPktBuffer.getProperties().data = DenseI32ArrayAttr::get(
622 ctrlPktBuffer->getContext(), ArrayRef<int>{newData});
623 erased.push_back(ctrlPktOps[i]);
626 for (
auto e : erased)
634static LogicalResult convertTransactionOpsToMLIR(
636 std::vector<TransactionBinaryOperation> &operations,
637 std::string blockwrite_prefix =
"config_blockwrite_data_") {
639 auto loc = builder.getUnknownLoc();
643 std::vector<memref::GlobalOp> global_data;
646 llvm::dyn_cast<DeviceOp>(builder.getBlock()->getParentOp());
648 device = builder.getBlock()->getParentOp()->getParentOfType<DeviceOp>();
650 OpBuilder::InsertionGuard guard(builder);
651 builder.setInsertionPointToStart(device.getBody());
653 for (
auto &op : operations) {
655 global_data.push_back(
nullptr);
658 uint32_t size = op.cmd.Size / 4;
659 const uint32_t *d =
reinterpret_cast<const uint32_t *
>(op.cmd.DataPtr);
660 std::vector<uint32_t> data32(d, d + size);
662 std::string name = blockwrite_prefix;
664 name = blockwrite_prefix + std::to_string(
id++);
665 }
while (device.lookupSymbol(name));
667 MemRefType memrefType = MemRefType::get({size}, builder.getI32Type());
668 TensorType tensorType =
669 RankedTensorType::get({size}, builder.getI32Type());
670 auto global = memref::GlobalOp::create(
671 builder, loc, name, builder.getStringAttr(
"private"), memrefType,
672 DenseElementsAttr::get<uint32_t>(tensorType, data32),
true,
nullptr);
673 global_data.push_back(global);
678 if (outputType == AIE::AIEToConfigurationOutputType::Transaction) {
679 if (failed(emitTransactionOps(builder, operations, global_data)))
681 }
else if (outputType == AIE::AIEToConfigurationOutputType::ControlPacket) {
682 if (failed(emitControlPacketOps(builder, operations, global_data)))
688 llvm_unreachable(
"bad output type");
698std::optional<mlir::ModuleOp>
700 std::vector<uint8_t> &binary) {
703 std::vector<TransactionBinaryOperation> operations;
704 auto c = parseTransactionBinary(binary, operations);
706 llvm::errs() <<
"Failed to parse binary\n";
711 auto loc = mlir::UnknownLoc::get(ctx);
714 auto module = ModuleOp::create(loc);
715 OpBuilder builder(module.getBodyRegion());
716 builder.setInsertionPointToStart(module.getBody());
719 std::vector<AIEDevice> devices{AIEDevice::npu1_1col, AIEDevice::npu1_2col,
720 AIEDevice::npu1_3col, AIEDevice::npu1};
721 auto device = DeviceOp::create(builder, loc, devices[columns - 1],
722 DeviceOp::getDefaultDeviceName());
723 device.getRegion().emplaceBlock();
724 DeviceOp::ensureTerminator(device.getBodyRegion(), builder, loc);
725 builder.setInsertionPointToStart(device.getBody());
728 if (failed(convertTransactionOpsToMLIR(
729 builder, AIE::AIEToConfigurationOutputType::Transaction, operations)))
736 OpBuilder &builder, xilinx::AIE::DeviceOp device, llvm::StringRef clElfDir,
738 std::string blockwrite_prefix) {
746 bool xaieDebug =
false;
755 bool generateElfs =
true;
756 if (failed(generateTransactions(ctl, clElfDir, device, aieSim, generateElfs,
764 std::vector<TransactionBinaryOperation> operations;
765 if (!parseTransactionBinary(txn_data, operations)) {
766 llvm::errs() <<
"Failed to parse binary\n";
770 if (failed(convertTransactionOpsToMLIR(builder, outputType, operations,
771 blockwrite_prefix))) {
779convertAIEToConfiguration(AIE::DeviceOp device, StringRef clElfDir,
782 OpBuilder builder(device.getBodyRegion());
787 auto loc = builder.getUnknownLoc();
788 SmallVector<AIEX::ConfigureOp> configureOps;
789 device.walk([&](AIEX::ConfigureOp op) { configureOps.push_back(op); });
791 if (configureOps.empty()) {
794 std::string seq_name =
"configure";
795 while (device.lookupSymbol(seq_name))
796 seq_name =
"configure" + std::to_string(
id++);
797 StringAttr seq_sym_name = builder.getStringAttr(seq_name);
798 auto seq = AIE::RuntimeSequenceOp::create(builder, loc, seq_sym_name);
799 seq.getBody().push_back(
new Block);
800 builder.setInsertionPointToStart(&seq.getBody().front());
802 builder.setInsertionPoint(configureOps.front());
811 if (!configureOps.empty()) {
813 builder.getBlock()->getOperations().splice(
814 builder.getInsertionPoint(),
815 configureOps.front().getBody().front().getOperations());
816 configureOps.front().erase();
824template <
typename BaseClass, AIE::AIEToConfigurationOutputType MyOutputType>
825struct ConvertAIEToConfigurationPass : BaseClass {
826 std::string &ref_clElfDir;
827 std::string &ref_clDeviceName;
828 ConvertAIEToConfigurationPass(std::string &clElfDir,
829 std::string &clDeviceName)
830 : ref_clElfDir(clElfDir), ref_clDeviceName(clDeviceName) {}
832 void getDependentDialects(DialectRegistry ®istry)
const override {
833 registry.insert<memref::MemRefDialect, AIEX::AIEXDialect>();
836 void runOnOperation()
override {
837 AIE::DeviceOp deviceOp = BaseClass::getOperation();
838 if (!ref_clDeviceName.empty() &&
839 deviceOp.getSymName() != ref_clDeviceName) {
843 convertAIEToConfiguration(deviceOp, ref_clElfDir, MyOutputType))) {
844 return BaseClass::signalPassFailure();
849struct ConvertAIEToTransactionPass
850 : ConvertAIEToConfigurationPass<
851 xilinx::impl::ConvertAIEToTransactionBase<
852 ConvertAIEToTransactionPass>,
853 AIE::AIEToConfigurationOutputType::Transaction> {
854 ConvertAIEToTransactionPass()
855 : ConvertAIEToConfigurationPass<
856 xilinx::impl::ConvertAIEToTransactionBase<
857 ConvertAIEToTransactionPass>,
862struct ConvertAIEToControlPacketsPass
863 : ConvertAIEToConfigurationPass<
864 xilinx::impl::ConvertAIEToControlPacketsBase<
865 ConvertAIEToControlPacketsPass>,
866 AIE::AIEToConfigurationOutputType::ControlPacket> {
867 ConvertAIEToControlPacketsPass()
868 : ConvertAIEToConfigurationPass<
869 xilinx::impl::ConvertAIEToControlPacketsBase<
870 ConvertAIEToControlPacketsPass>,
877std::unique_ptr<mlir::OperationPass<xilinx::AIE::DeviceOp>>
879 return std::make_unique<ConvertAIEToTransactionPass>();
882std::unique_ptr<mlir::OperationPass<xilinx::AIE::DeviceOp>>
884 return std::make_unique<ConvertAIEToControlPacketsPass>();
@ XAIE_IO_CUSTOM_OP_DDR_PATCH
LogicalResult orConsecutiveWritesOnSameAddr(Block *body)
bool hasProperty(ModelProperty Prop) const
std::shared_ptr< Value > value()
Include the generated interface declarations.
std::unique_ptr< mlir::OperationPass< xilinx::AIE::DeviceOp > > createConvertAIEToTransactionPass()
AIEToConfigurationOutputType
mlir::LogicalResult generateAndInsertConfigOps(mlir::OpBuilder &builder, xilinx::AIE::DeviceOp device, llvm::StringRef clElfDir="", AIEToConfigurationOutputType outputType=AIEToConfigurationOutputType::Transaction, std::string blockwrite_prefix="config_blockwrite_data_")
std::optional< mlir::ModuleOp > convertTransactionBinaryToMLIR(mlir::MLIRContext *ctx, std::vector< uint8_t > &binary)
std::unique_ptr< mlir::OperationPass< xilinx::AIE::DeviceOp > > createConvertAIEToControlPacketsPass()
mlir::LogicalResult addAieElfs(DeviceOp &targetOp, const mlir::StringRef workDirPath, bool aieSim)
mlir::LogicalResult setIOBackend(bool aieSim, bool xaieDebug)
std::vector< uint8_t > exportSerializedTransaction()
mlir::LogicalResult addCoreEnable(DeviceOp &targetOp)
mlir::LogicalResult addInitConfig(DeviceOp &targetOp)