.. _program_listing_file_lib_Target_EmitHLSToKriaDtsi_EmitHLSToKriaDtsi.cpp: Program Listing for File EmitHLSToKriaDtsi.cpp ============================================== |exhale_lsh| :ref:`Return to documentation for file ` (``lib/Target/EmitHLSToKriaDtsi/EmitHLSToKriaDtsi.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Implementation of translation EmitHLSToKriaDtsi // // @file // @author Jiahong Bi (jiahong.bi@tu-dresden.de) #include "laksa-mlir/Dialect/EmitHLS/IR/EmitHLS.h" #include "laksa-mlir/Target/EmitHLSToKriaDtsi/KriaDtsiEmitter.h" #include "llvm/Support/CommandLine.h" using namespace mlir; using namespace mlir::emithls; namespace { // 0xa0000000 is the base address Vivado's address editor assigns by default // to the first custom IP's AXI-Lite control interface (s_axi_control) when // it is auto-connected to the Zynq MPSoC's M_AXI_HPM0_FPD master port, as // done by the EmitHLSToVivadoTcl translation. llvm::cl::opt clKriaAxiLiteBaseAddress( "kria-axi-lite-base-address", llvm::cl::desc( "Physical base address of the HLS IP's AXI-Lite control interface, " "as assigned by Vivado's address editor"), llvm::cl::init("0xa0000000")); llvm::cl::opt clKriaAxiLiteSize( "kria-axi-lite-size", llvm::cl::desc( "Size of the AXI-Lite control register window, as assigned by " "Vivado's address editor"), llvm::cl::init("0x10000")); } // namespace // Finds the function marked as the design's top function, i.e. the one whose // body contains a PragmaTopInterfaceOp. Its symbol name doubles as the // device tree node's label and unit name. static FailureOr findTopFunc(ModuleOp moduleOp) { FuncOp topFunc = nullptr; auto result = moduleOp.walk([&](PragmaTopInterfaceOp topInterfaceOp) { FuncOp funcOp = topInterfaceOp->getParentOfType(); if (!funcOp || topFunc) return WalkResult::interrupt(); topFunc = funcOp; return WalkResult::advance(); }); if (result.wasInterrupted() || !topFunc) return moduleOp->emitError( "expected exactly one function containing a top_interface " "pragma"); return topFunc; } // Strips a leading "0x"/"0X", if present, so the address can be reused as a // device tree unit-address suffix (`node@
`). static StringRef stripHexPrefix(StringRef hex) { if (hex.starts_with_insensitive("0x")) return hex.drop_front(2); return hex; } //===----------------------------------------------------------------------===// // Translation entry point //===----------------------------------------------------------------------===// LogicalResult emithls::translateEmitHLSToKriaDtsi(ModuleOp op, raw_ostream &os) { FailureOr topFunc = findTopFunc(op); if (failed(topFunc)) return failure(); StringRef nodeName = topFunc->getSymName(); StringRef unitAddress = stripHexPrefix(clKriaAxiLiteBaseAddress); os << "/dts-v1/;\n" << "/plugin/;\n" "\n" "/ {\n" " fragment@0 {\n" " target-path = \"/\";\n" " __overlay__ {\n" " #address-cells = <2>;\n" " #size-cells = <2>;\n" "\n" << " " << nodeName << ": " << nodeName << "@" << unitAddress << " {\n" " compatible = \"tud,laksa\";\n" " reg = <0x0 " << clKriaAxiLiteBaseAddress << " 0x0 " << clKriaAxiLiteSize << ">;\n" " };\n" " };\n" " };\n" "};\n"; return success(); }