From 48a190c99f15e1b226a4f53cbd5d7a4795e9cb22 Mon Sep 17 00:00:00 2001 From: xuyipei Date: Wed, 22 Apr 2026 14:50:06 +0800 Subject: [PATCH] add rcx python interface --- src/interface/python/CMakeLists.txt | 2 + src/interface/python/py_ircx/CMakeLists.txt | 14 ++ src/interface/python/py_ircx/py_ircx.cpp | 137 ++++++++++++++++++ src/interface/python/py_ircx/py_ircx.h | 40 +++++ .../python/py_ircx/py_register_ircx.h | 44 ++++++ src/interface/python/python_moodule.cc | 2 + 6 files changed, 239 insertions(+) create mode 100644 src/interface/python/py_ircx/CMakeLists.txt create mode 100644 src/interface/python/py_ircx/py_ircx.cpp create mode 100644 src/interface/python/py_ircx/py_ircx.h create mode 100644 src/interface/python/py_ircx/py_register_ircx.h diff --git a/src/interface/python/CMakeLists.txt b/src/interface/python/CMakeLists.txt index 4aa2b4c3f..081e9544b 100644 --- a/src/interface/python/CMakeLists.txt +++ b/src/interface/python/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(py_instance) add_subdirectory(py_ipdn) add_subdirectory(py_ipl) add_subdirectory(py_irt) +add_subdirectory(py_ircx) add_subdirectory(py_ista) add_subdirectory(py_ipw) add_subdirectory(py_ito) @@ -46,6 +47,7 @@ target_link_libraries(ecc_py py_ipdn py_ipl py_irt + py_ircx py_ista py_ipw py_ito diff --git a/src/interface/python/py_ircx/CMakeLists.txt b/src/interface/python/py_ircx/CMakeLists.txt new file mode 100644 index 000000000..d2b51924d --- /dev/null +++ b/src/interface/python/py_ircx/CMakeLists.txt @@ -0,0 +1,14 @@ +aux_source_directory(. PY_IRCX_SRC) + +add_library(py_ircx ${PY_IRCX_SRC}) + +target_link_libraries(py_ircx + PUBLIC + ircx + OpenMP::OpenMP_CXX + pybind11::pybind11 +) +target_include_directories(py_ircx + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/src/interface/python/py_ircx/py_ircx.cpp b/src/interface/python/py_ircx/py_ircx.cpp new file mode 100644 index 000000000..1c0e82237 --- /dev/null +++ b/src/interface/python/py_ircx/py_ircx.cpp @@ -0,0 +1,137 @@ +// *************************************************************************************** +// Copyright (c) 2023-2025 Peng Cheng Laboratory +// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences +// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip +// +// iEDA is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// +// See the Mulan PSL v2 for more details. +// *************************************************************************************** +#include "py_ircx.h" + +#include +#include + +#include + +#include "RCX.hpp" + +namespace python_interface { + +namespace { + +namespace fs = std::filesystem; + +ircx::RCX& rcx() +{ + return ircx::RCX::getOrCreateInst(); +} + +void require_non_empty(const std::string& value, const char* field_name) +{ + if (value.empty()) { + throw std::invalid_argument(std::string(field_name) + " is empty."); + } +} + +void require_file_exists(const std::string& path, const char* file_kind) +{ + require_non_empty(path, file_kind); + if (!fs::exists(path)) { + throw std::runtime_error(std::string(file_kind) + " not found: " + path); + } +} + +} // namespace + +bool init_rcx(unsigned thread_number) +{ + rcx().set_num_threads(thread_number == 0 ? 1U : thread_number); + return true; +} + +bool read_rcx_corner(const std::string& corner_name, + const std::string& itf_file, + const std::string& captab_file) +{ + require_non_empty(corner_name, "corner_name"); + require_file_exists(itf_file, "itf_file"); + require_file_exists(captab_file, "captab_file"); + + return rcx().readCorner(corner_name, itf_file.c_str(), captab_file.c_str()); +} + +bool read_rcx_itf(const std::vector& itf_files) +{ + if (itf_files.empty()) { + throw std::invalid_argument("itf_files is empty."); + } + + for (const auto& itf_file : itf_files) { + require_file_exists(itf_file, "itf_file"); + } + + return rcx().readItf(itf_files); +} + +bool read_rcx_mapping(const std::string& mapping_file) +{ + require_file_exists(mapping_file, "mapping_file"); + return rcx().readMapping(mapping_file.c_str()); +} + +bool adapt_rcx_db() +{ + return rcx().adaptDB(); +} + +bool build_rcx_topology() +{ + return rcx().buildTopology(); +} + +bool build_rcx_environment() +{ + return rcx().buildEnvironment(); +} + +bool build_rcx_process_variation() +{ + return rcx().buildProcessVariation(); +} + +bool extract_rcx_parasitics() +{ + return rcx().extractParasitics(); +} + +bool run_rcx() +{ + auto& rcx_inst = rcx(); + omp_set_num_threads(rcx_inst.num_threads()); + + unsigned result = 1; + result &= rcx_inst.adaptDB(); + result &= rcx_inst.buildTopology(); + result &= rcx_inst.buildEnvironment(); + result &= rcx_inst.buildProcessVariation(); + result &= rcx_inst.extractParasitics(); + + return result; +} + +bool report_rcx(const std::string& output_dir) +{ + const std::string resolved_output_dir = output_dir.empty() ? "." : output_dir; + fs::create_directories(resolved_output_dir); + return rcx().reportSpef(resolved_output_dir); +} + +} // namespace python_interface diff --git a/src/interface/python/py_ircx/py_ircx.h b/src/interface/python/py_ircx/py_ircx.h new file mode 100644 index 000000000..2619c1294 --- /dev/null +++ b/src/interface/python/py_ircx/py_ircx.h @@ -0,0 +1,40 @@ +// *************************************************************************************** +// Copyright (c) 2023-2025 Peng Cheng Laboratory +// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences +// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip +// +// iEDA is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// +// See the Mulan PSL v2 for more details. +// *************************************************************************************** +#pragma once + +#include +#include + +namespace python_interface { + +bool init_rcx(unsigned thread_number); +bool read_rcx_corner(const std::string& corner_name, + const std::string& itf_file, + const std::string& captab_file); +bool read_rcx_itf(const std::vector& itf_files); +bool read_rcx_mapping(const std::string& mapping_file); + +bool adapt_rcx_db(); +bool build_rcx_topology(); +bool build_rcx_environment(); +bool build_rcx_process_variation(); +bool extract_rcx_parasitics(); + +bool run_rcx(); +bool report_rcx(const std::string& output_dir); + +} // namespace python_interface diff --git a/src/interface/python/py_ircx/py_register_ircx.h b/src/interface/python/py_ircx/py_register_ircx.h new file mode 100644 index 000000000..898a0e588 --- /dev/null +++ b/src/interface/python/py_ircx/py_register_ircx.h @@ -0,0 +1,44 @@ +// *************************************************************************************** +// Copyright (c) 2023-2025 Peng Cheng Laboratory +// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences +// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip +// +// iEDA is licensed under Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +// +// See the Mulan PSL v2 for more details. +// *************************************************************************************** +#pragma once +#include +#include + +#include "py_ircx.h" + +namespace python_interface { +namespace py = pybind11; + +void register_ircx(py::module& m) +{ + m.def("init_rcx", init_rcx, py::arg("thread_number") = 64); + m.def("read_rcx_corner", read_rcx_corner, py::arg("corner_name"), + py::arg("itf_file"), py::arg("captab_file")); + m.def("read_rcx_itf", read_rcx_itf, py::arg("itf_files")); + m.def("read_rcx_mapping", read_rcx_mapping, py::arg("mapping_file")); + + m.def("adapt_rcx_db", adapt_rcx_db); + m.def("build_rcx_topology", build_rcx_topology); + m.def("build_rcx_environment", build_rcx_environment); + m.def("build_rcx_process_variation", build_rcx_process_variation); + m.def("extract_rcx_parasitics", extract_rcx_parasitics); + + m.def("run_rcx", run_rcx); + m.def("report_rcx", report_rcx, py::arg("output_dir") = "."); +} + +} // namespace python_interface diff --git a/src/interface/python/python_moodule.cc b/src/interface/python/python_moodule.cc index b9530898f..da18043dd 100644 --- a/src/interface/python/python_moodule.cc +++ b/src/interface/python/python_moodule.cc @@ -31,6 +31,7 @@ #include "py_register_ipl.h" #include "py_register_ipw.h" #include "py_register_irt.h" +#include "py_register_ircx.h" #include "py_register_ista.h" #include "py_register_ito.h" #include "py_register_report.h" @@ -54,6 +55,7 @@ PYBIND11_MODULE(ecc_py, m) register_ipnp(m); register_ipl(m); register_irt(m); + register_ircx(m); register_ista(m); register_ipw(m); register_ito(m);