Program Listing for File EmitHLSToLaksaHeader.cpp
↰ Return to documentation for file (lib/Target/EmitHLSToLaksaHeader/EmitHLSToLaksaHeader.cpp)
// Implementation of translation EmitHLSToLaksaHeader
//
// @file
// @author Jiahong Bi (jiahong.bi@tu-dresden.de)
#include "laksa-mlir/Target/EmitHLSToLaksaHeader/LaksaHeaderEmitter.h"
#include "laksa-mlir/Target/LaksaCommon/BufferInfo.h"
#include "llvm/ADT/STLExtras.h"
using namespace mlir;
using namespace mlir::emithls;
//===----------------------------------------------------------------------===//
// Translation entry point
//===----------------------------------------------------------------------===//
LogicalResult
emithls::translateEmitHLSToLaksaHeader(ModuleOp op, raw_ostream &os)
{
FailureOr<FuncOp> topFunc = findLaksaTopFunc(op);
if (failed(topFunc)) return failure();
SmallVector<LaksaBufferInfo> buffers;
if (failed(collectLaksaBufferInfos(*topFunc, buffers))) return failure();
StringRef designName = topFunc->getSymName();
std::string prefix = getLaksaMacroPrefix(designName);
std::string guard = prefix + "_LAKSA_CONFIG_H";
os << "// Generated by ladle -t emithls-to-laksa-header.\n"
<< "// Buffer sizes and AXI-Lite register offsets for '" << designName
<< "', matching the\n"
<< "// argument layout expected by laksa.h's IOCTL_START_KERNEL.\n"
<< "#ifndef " << guard << "\n"
<< "#define " << guard << "\n\n"
<< "#define " << prefix << "_NUM_ARGS " << buffers.size() << "\n\n"
<< "#define " << prefix << "_CTRL_OFFSET 0x00 /* ap_ctrl */\n\n";
// Register offsets follow Vitis HLS's fixed AXI-Lite control layout for
// m_axi arguments: ap_ctrl/gie/ier/isr occupy 0x00-0x0c, then each
// 64-bit pointer argument gets a 0xc-byte slot starting at 0x10 (low
// word, high word, one reserved word).
for (auto [idx, info] : llvm::enumerate(buffers)) {
unsigned lowOffset = 0x10 + idx * 0xc;
unsigned highOffset = lowOffset + 0x4;
StringRef direction = info.isReadByKernel && info.isWrittenByKernel
? "input/output"
: info.isReadByKernel ? "input"
: "output";
os << "/* arg" << idx << ": " << direction << " buffer, "
<< info.numElements << " x " << info.elementBits
<< "-bit elements */\n"
<< "#define " << prefix << "_ARG" << idx << "_LOW_OFFSET 0x";
os.write_hex(lowOffset);
os << "\n#define " << prefix << "_ARG" << idx << "_HIGH_OFFSET 0x";
os.write_hex(highOffset);
os << "\n#define " << prefix << "_ARG" << idx << "_SIZE "
<< info.getSizeInBytes() << " /* bytes */\n\n";
}
os << "#endif /* " << guard << " */\n";
return success();
}