HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
python_bindings.cpp
Go to the documentation of this file.
2 
3 #include "pybind11/operators.h"
4 #include "pybind11/pybind11.h"
5 #include "pybind11/stl.h"
6 #include "pybind11/stl_bind.h"
9 
10 namespace py = pybind11;
11 
12 namespace hal
13 {
14 
15  // the name in PYBIND11_MODULE/PYBIND11_PLUGIN *MUST* match the filename of the output library (without extension),
16  // otherwise you will get "ImportError: dynamic module does not define module export function" when importing the module
17 
18 #ifdef PYBIND11_MODULE
19  PYBIND11_MODULE(xilinx_toolbox, m)
20  {
21  m.doc() = "A collection of functions specifically designed to operate on Xilinx FPGA netlists.";
22 #else
23  PYBIND11_PLUGIN(xilinx_toolbox)
24  {
25  py::module m("xilinx_toolbox", "A collection of functions specifically designed to operate on Xilinx FPGA netlists.");
26 #endif // ifdef PYBIND11_MODULE
27 
28  py::class_<XilinxToolboxPlugin, RawPtrWrapper<XilinxToolboxPlugin>, BasePluginInterface> py_xilinx_toolbox_plugin(
29  m, "XilinxToolboxPlugin", R"(This class provides an interface to integrate the Xilinx toolbox as a plugin within the HAL framework.)");
30 
31  py_xilinx_toolbox_plugin.def_property_readonly("name", &XilinxToolboxPlugin::get_name, R"(
32  The name of the plugin.
33 
34  :type: str
35  )");
36 
37  py_xilinx_toolbox_plugin.def("get_name", &XilinxToolboxPlugin::get_name, R"(
38  Get the name of the plugin.
39 
40  :returns: The name of the plugin.
41  :rtype: str
42  )");
43 
44  py_xilinx_toolbox_plugin.def_property_readonly("version", &XilinxToolboxPlugin::get_version, R"(
45  The version of the plugin.
46 
47  :type: str
48  )");
49 
50  py_xilinx_toolbox_plugin.def("get_version", &XilinxToolboxPlugin::get_version, R"(
51  Get the version of the plugin.
52 
53  :returns: The version of the plugin.
54  :rtype: str
55  )");
56 
57  py_xilinx_toolbox_plugin.def_property_readonly("description", &XilinxToolboxPlugin::get_description, R"(
58  The description of the plugin.
59 
60  :type: str
61  )");
62 
63  py_xilinx_toolbox_plugin.def("get_description", &XilinxToolboxPlugin::get_description, R"(
64  Get the description of the plugin.
65 
66  :returns: The description of the plugin.
67  :rtype: str
68  )");
69 
70  py_xilinx_toolbox_plugin.def_property_readonly("dependencies", &XilinxToolboxPlugin::get_dependencies, R"(
71  A set of plugin names that this plugin depends on.
72 
73  :type: set[str]
74  )");
75 
76  py_xilinx_toolbox_plugin.def("get_dependencies", &XilinxToolboxPlugin::get_dependencies, R"(
77  Get a set of plugin names that this plugin depends on.
78 
79  :returns: A set of plugin names that this plugin depends on.
80  :rtype: set[str]
81  )");
82 
83  m.def(
84  "split_luts",
85  [](Netlist* nl) -> std::optional<u32> {
86  auto res = xilinx_toolbox::split_luts(nl);
87  if (res.is_ok())
88  {
89  return res.get();
90  }
91  else
92  {
93  log_error("python_context", "{}", res.get_error().get());
94  return std::nullopt;
95  }
96  },
97  py::arg("nl"),
98  R"(
99  Split LUTs with two outputs into two separate LUT gates.
100  Replaces ``LUT6_2`` with a ``LUT6`` and a ``LUT5`` gate if the respective outputs of the ``LUT6_2`` are actually used, i.e., connected to other gates.
101 
102  :param hal_py.Netlist nl: The netlist to operate on.
103  :returns: The number of split ``LUT6_2`` gates on success, ``None`` otherwise.
104  :rtype: int or None
105  )");
106 
107  m.def(
108  "split_shift_registers",
109  [](Netlist* nl) -> std::optional<u32> {
111  if (res.is_ok())
112  {
113  return res.get();
114  }
115  else
116  {
117  log_error("python_context", "{}", res.get_error().get());
118  return std::nullopt;
119  }
120  },
121  py::arg("nl"),
122  R"(
123  Split shift register primitives and replaces them with equivalent flip-flops chains.
124  Currently only implemented for gate type ``SRL16E``.
125 
126  :param hal_py.Netlist nl: The netlist to operate on.
127  :returns: The number of split shift registers on success, ``None`` otherwise.
128  :rtype: int or None
129  )");
130 
131  m.def(
132  "parse_xdc_file",
133  [](Netlist* nl, const std::filesystem::path& xdc_file) -> bool {
134  auto res = xilinx_toolbox::parse_xdc_file(nl, xdc_file);
135  if (res.is_ok())
136  {
137  return true;
138  }
139  else
140  {
141  log_error("python_context", "{}", res.get_error().get());
142  return false;
143  }
144  },
145  py::arg("nl"),
146  py::arg("xdc_file"),
147  R"(
148  Parse an ``.xdc`` file and extract the position LOC and BEL data of each gate.
149  Translates the coordinates extracted from the ``.xdc`` file into integer values.
150 
151  :param hal_py.Netlist nl: The netlist to operate on.
152  :param path xdc_file: The path to the ``.xdc`` file.
153  :returns: ``True`` on success, ``False`` otherwise.
154  :rtype: bool
155  )");
156 
157 #ifndef PYBIND11_MODULE
158  return m.ptr();
159 #endif // PYBIND11_MODULE
160  }
161 } // namespace hal
std::string get_name() const override
Get the name of the plugin.
std::string get_version() const override
Get the version of the plugin.
std::set< std::string > get_dependencies() const override
Get the plugin dependencies.
std::string get_description() const override
Get a short description of the plugin.
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Result< u32 > split_luts(Netlist *nl)
Split LUTs with two outputs into two separate LUT gates.
Result< std::monostate > parse_xdc_file(Netlist *nl, const std::filesystem::path &xdc_file)
Parse an .xdc file and extract the position LOC and BEL data of each gate.
Definition: xdc_parser.cpp:220
Result< u32 > split_shift_registers(Netlist *nl)
Split shift register primitives and replaces them with equivalent flip-flops chains.
Definition: defines.h:45
PYBIND11_PLUGIN(hal_py)
This file contains all functions related to the HAL plugin API.
This file contains functions specifically designed to preprocess Xilinx FPGA netlists.