126 XAie_LocType &tileLoc) {
127 LLVM_DEBUG(llvm::dbgs() <<
"\nstart configuring bds\n");
128 std::optional<int> acqValue, relValue, acqLockId, relLockId;
133 for (
auto op : block.getOps<UseLockOp>()) {
138 lock = cast<LockOp>(op.getLock().getDefiningOp());
139 switch (op.getAction()) {
140 case LockAction::Acquire:
141 case LockAction::AcquireGreaterEqual:
142 acqEn = op.getAcqEn();
143 acqLockId = lock.getLockIDValue();
144 acqValue = op.getLockValue();
146 acqValue.value() = -acqValue.value();
148 case LockAction::Release:
149 relLockId = lock.getLockIDValue();
150 relValue = op.getLockValue();
155 assert(acqValue && relValue && acqLockId && relLockId &&
156 "expected both use_lock(acquire) and use_lock(release) with bd");
160 tileLoc.Col, tileLoc.Row, lock.colIndex(), lock.rowIndex());
161 if (lockOffset && acqLockId)
162 acqLockId.value() += lockOffset.value();
163 if (lockOffset && relLockId)
164 relLockId.value() += lockOffset.value();
169 XAie_Lock acqLock = XAie_LockInit(acqLockId.value(), acqValue.value());
170 XAie_Lock relLock = XAie_LockInit(relLockId.value(), relValue.value());
172 dmaTileBd.DmaMod->SetLock, &dmaTileBd, acqLock,
173 relLock, acqEn, relEn);
179 XAie_LocType &tileLoc,
int bdId,
180 std::optional<int> nextBdId) {
181 std::optional<int> packetType;
182 std::optional<int> packetID;
185 auto maybePacketOps = block.getOps<DMABDPACKETOp>();
186 if (!maybePacketOps.empty()) {
187 assert(llvm::range_size(maybePacketOps) == 1 &&
188 "expected only one dma_bd_packet");
189 auto packetOp = *maybePacketOps.begin();
190 packetType = packetOp.getPacketType();
191 packetID = packetOp.getPacketID();
194 auto bdOp = *block.getOps<DMABDOp>().begin();
205 burstLen / 16, qOs, cache, secure);
209 uint64_t baseAddr = 0;
212 cast<AIE::ExternalBufferOp>(bdOp.getBuffer().getDefiningOp());
216 if (bufferOp.getAddress())
217 baseAddr = bufferOp.getAddress().value();
219 auto bufferOp = cast<AIE::BufferOp>(bdOp.getBuffer().getDefiningOp());
220 if (!bufferOp.getAddress())
221 return bufferOp.emitError(
"buffer must have address assigned");
222 baseAddr = bufferOp.getAddress().value();
228 auto bufferOp = cast<AIE::BufferOp>(bdOp.getBuffer().getDefiningOp());
229 auto bufferRow = bufferOp.getTileOp().getRow();
230 auto bufferCol = bufferOp.getTileOp().getCol();
232 tileLoc.Col, tileLoc.Row, bufferCol, bufferRow);
234 baseAddr += addrOffset.value();
237 std::optional<llvm::ArrayRef<BDDimLayoutAttr>> dims = bdOp.getDimensions();
238 uint64_t lenInBytes = bdOp.getLenInBytes();
239 uint64_t basePlusOffsetInBytes = baseAddr + bdOp.getOffsetInBytes();
242 basePlusOffsetInBytes, lenInBytes);
244 XAie_DmaTensor dmaTileBdTensor = {};
245 dmaTileBdTensor.NumDim = dims->size();
246 dmaTileBdTensor.Dim =
static_cast<XAie_DmaDimDesc *
>(
247 calloc(dmaTileBdTensor.NumDim,
sizeof(XAie_DmaDimDesc)));
248 if (!dmaTileBdTensor.Dim)
249 return bdOp.emitError(
"couldn't allocate array of XAie_DmaDimDesc");
251 double elementWidthIn32bWords =
252 static_cast<double>(bdOp.getBufferElementTypeWidthInBytes()) / 4.0;
253 for (
size_t i = 0; i < dims->size(); i++) {
257 int j = dims->size() - i - 1;
261 stride =
static_cast<uint32_t
>(dims.value()[i].getStride() *
262 elementWidthIn32bWords);
263 size = dims.value()[i].getSize();
265 stride = dims.value()[i].getStride();
266 size =
static_cast<uint16_t
>(dims.value()[i].getSize() *
267 elementWidthIn32bWords);
269 stride = stride > 0 ? stride : 1;
272 dmaTileBdTensor.Dim[j].AieMlDimDesc = {stride, size};
275 &dmaTileBdTensor, basePlusOffsetInBytes,
280 std::optional<llvm::ArrayRef<BDPadLayoutAttr>> padDims =
281 bdOp.getPadDimensions();
284 XAie_DmaPadTensor dmaPadTensor = {};
285 dmaPadTensor.NumDim = padDims->size();
286 dmaPadTensor.PadDesc =
static_cast<XAie_PadDesc *
>(
287 calloc(dmaPadTensor.NumDim,
sizeof(XAie_PadDesc)));
288 if (!dmaPadTensor.PadDesc)
289 return bdOp.emitError(
"couldn't allocate array of XAie_PadDesc");
291 double elementWidthIn32bWords =
292 static_cast<double>(bdOp.getBufferElementTypeWidthInBytes()) / 4.0;
293 for (
size_t i = 0; i < padDims->size(); i++) {
295 int j = padDims->size() - i - 1;
299 before =
static_cast<uint8_t
>(padDims.value()[i].getConstPadBefore());
300 after =
static_cast<uint8_t
>(padDims.value()[i].getConstPadAfter());
302 before =
static_cast<uint8_t
>(padDims.value()[i].getConstPadBefore() *
303 elementWidthIn32bWords);
304 after =
static_cast<uint8_t
>(padDims.value()[i].getConstPadAfter() *
305 elementWidthIn32bWords);
307 dmaPadTensor.PadDesc[j] = {before, after};
313 auto enableNextBd = 1;
315 nextBdId.value(), enableNextBd);
318 if (
auto packetInfo = bdOp.getPacket()) {
319 packetType = packetInfo->getPktType();
320 packetID = packetInfo->getPktId();
325 bdOp.emitError(
"must have packetType with packetID");
326 if (bdOp.getLen() == 0)
327 return bdOp.emitOpError(
328 "For MM2S channels, if Buffer_Length=0 then Enable_Packet must be "
329 "set to 0, otherwise behavior is undefined (3.7.8 arch spec)");
331 bdOp, XAie_DmaSetPkt, &dmaTileBd,
332 XAie_PacketInit(packetID.value(), packetType.value()));
337 LLVM_DEBUG(llvm::dbgs() <<
"\nend configuring bds\n");
377 for (
auto tileOp : targetOp.getOps<TileOp>()) {
378 auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex());
379 if (!tileOp.isShimTile() && tileOp.getCoreOp()) {
383 for (uint8_t l = 0; l <
NUM_LOCKS; l++) {
384 auto locInit = XAie_LockInit(l, 0);
392 targetOp.walk<WalkOrder::PreOrder>([&](LockOp lockOp) {
393 if (lockOp.getLockID() && lockOp.getInit()) {
394 auto tileLoc = XAie_TileLoc(lockOp.getTileOp().colIndex(),
395 lockOp.getTileOp().rowIndex());
396 auto locInit = XAie_LockInit(*lockOp.getLockID(), *lockOp.getInit());
399 LLVM_DEBUG(llvm::dbgs()
400 <<
"lock op missing either id or init" << lockOp <<
"\n");
407 targetOp.walk<WalkOrder::PreOrder>([&](BufferOp bufferOp) {
408 auto initialValue = bufferOp.getInitialValue();
411 mlir::DenseElementsAttr denseInit =
412 dyn_cast<mlir::DenseElementsAttr>(initialValue.value());
415 auto tileLoc = XAie_TileLoc(bufferOp.getTileOp().colIndex(),
416 bufferOp.getTileOp().rowIndex());
417 std::vector<char> byteVec;
418 if (denseInit.getElementType().isIntOrIndex()) {
419 for (
auto intVal : denseInit.getValues<APInt>()) {
421 size_t byteSize = (intVal.getBitWidth() + 7) / 8;
423 std::vector<char> bytes(byteSize);
425 static_cast<const char *
>(
static_cast<const void *
>(&intVal)),
426 static_cast<const char *
>(
static_cast<const void *
>(&intVal)) +
429 byteVec.insert(byteVec.end(), bytes.begin(), bytes.end());
431 }
else if (isa<FloatType>(denseInit.getElementType())) {
432 for (
auto floatVal : denseInit.getValues<APFloat>()) {
433 APInt floatInt = floatVal.bitcastToAPInt();
435 size_t byteSize = (floatInt.getBitWidth() + 7) / 8;
437 std::vector<char> bytes(byteSize);
439 static_cast<const char *
>(
static_cast<const void *
>(&floatInt)),
440 static_cast<const char *
>(
static_cast<const void *
>(&floatInt)) +
443 byteVec.insert(byteVec.end(), bytes.begin(), bytes.end());
446 llvm::outs() <<
"buffer op type not supported for initialization "
451 bufferOp.getAddress().value(), byteVec.data(),
460 for (
auto switchboxOp : targetOp.getOps<SwitchboxOp>()) {
461 int32_t
col = switchboxOp.colIndex();
462 int32_t
row = switchboxOp.rowIndex();
463 XAie_LocType tileLoc = XAie_TileLoc(
col,
row);
465 "Only NPU currently supported");
467 Block &b = switchboxOp.getConnections().front();
468 for (
auto connectOp : b.getOps<ConnectOp>())
470 switchboxOp, XAie_StrmConnCctEnable, &
devInst, tileLoc,
471 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()),
472 connectOp.sourceIndex(),
473 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()),
474 connectOp.destIndex());
476 for (
auto masterSetOp : b.getOps<MasterSetOp>()) {
480 for (
auto val : masterSetOp.getAmsels()) {
481 AMSelOp amsel = cast<AMSelOp>(val.getDefiningOp());
482 arbiter = amsel.arbiterIndex();
483 int msel = amsel.getMselValue();
488 bool keepHeader =
true;
490 if (masterSetOp.getDestBundle() == WireBundle::DMA)
494 if (switchboxOp.rowIndex() == 0 &&
495 masterSetOp.getDestBundle() == WireBundle::South)
499 if (
auto keep = masterSetOp.getKeepPktHeader())
503 keepHeader ? XAIE_SS_PKT_DONOT_DROP_HEADER : XAIE_SS_PKT_DROP_HEADER;
505 masterSetOp, XAie_StrmPktSwMstrPortEnable, &
devInst, tileLoc,
506 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(masterSetOp.getDestBundle()),
507 masterSetOp.destIndex(), dropHeader, arbiter, mask);
510 for (
auto packetRulesOp : b.getOps<PacketRulesOp>()) {
512 Block &block = packetRulesOp.getRules().front();
513 for (
auto slotOp : block.getOps<PacketRuleOp>()) {
514 AMSelOp amselOp = cast<AMSelOp>(slotOp.getAmsel().getDefiningOp());
515 int arbiter = amselOp.arbiterIndex();
516 int msel = amselOp.getMselValue();
519 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(
520 packetRulesOp.getSourceBundle()),
521 packetRulesOp.sourceIndex());
522 auto packetInit = XAie_PacketInit(slotOp.valueInt(), 0);
526 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(
527 packetRulesOp.getSourceBundle()),
528 packetRulesOp.sourceIndex(), slot, packetInit,
529 slotOp.maskInt(), msel, arbiter);
535 for (
auto muxOp : targetOp.getOps<ShimMuxOp>()) {
539 XAie_TileLoc(muxOp.getTileOp().getCol(), muxOp.getTileOp().getRow());
540 Block &b = muxOp.getConnections().front();
541 for (
auto connectOp : b.getOps<ConnectOp>()) {
543 if (connectOp.getSourceBundle() == WireBundle::North)
545 &
devInst, tileLoc, connectOp.sourceIndex());
547 if (connectOp.getDestBundle() == WireBundle::North)
549 &
devInst, tileLoc, connectOp.destIndex());
553 for (
auto switchboxOp : targetOp.getOps<ShimSwitchboxOp>()) {
554 Block &b = switchboxOp.getConnections().front();
555 auto tileLoc = XAie_TileLoc(switchboxOp.getCol(), 0);
556 for (
auto connectOp : b.getOps<ConnectOp>())
558 switchboxOp, XAie_StrmConnCctEnable, &
devInst, tileLoc,
559 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()),
560 connectOp.sourceIndex(),
561 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()),
562 connectOp.destIndex());
567 for (
auto configOp : targetOp.getOps<ConfigureCascadeOp>()) {
568 TileOp tile = cast<TileOp>(configOp.getTile().getDefiningOp());
569 auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow());
571 targetOp, XAie_CoreConfigAccumulatorControl, &
devInst, tileLoc,
572 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(
573 static_cast<WireBundle
>(configOp.getInputDir())),
574 WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(
575 static_cast<WireBundle
>(configOp.getOutputDir())));
592 auto memOps = llvm::to_vector_of<TileElement>(targetOp.getOps<MemOp>());
593 llvm::append_range(memOps, targetOp.getOps<MemTileDMAOp>());
594 llvm::append_range(memOps, targetOp.getOps<ShimDMAOp>());
595 for (TileElement memOp : memOps) {
596 int col = memOp.getTileID().col;
597 int row = memOp.getTileID().row;
598 XAie_LocType tileLoc = XAie_TileLoc(
col,
row);
602 llvm::SetVector<Block *> blockVector =
606 auto dmaOps = llvm::to_vector_of<DMAOp>(
607 memOp.getOperation()->getRegion(0).getOps<DMAOp>());
608 if (!dmaOps.empty()) {
609 for (
auto dmaOp : dmaOps)
610 for (
auto &bdRegion : dmaOp.getBds()) {
611 Block &block = bdRegion.getBlocks().front();
616 for (Block *block : blockVector) {
617 if (block->getOps<DMABDOp>().empty())
625 for (
auto dmaOp : dmaOps) {
626 auto &block = dmaOp.getBds().front().getBlocks().front();
627 DMABDOp bd = *block.getOps<DMABDOp>().begin();
629 *dmaOp.getOperation(), tileLoc, dmaOp.getChannelIndex(),
630 dmaOp.getChannelDir(), bd.getBdId().value(),
631 dmaOp.getRepeatCount())))
635 for (Block *block : blockVector) {
636 for (
auto op : block->getOps<DMAStartOp>()) {
637 DMABDOp bd = *op.getDest()->getOps<DMABDOp>().begin();
638 int chNum = op.getChannelIndex();
639 auto channelDir = op.getChannelDir();
641 channelDir, bd.getBdId().value(),
642 op.getRepeatCount())))