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(resynthesis, m)
20  {
21  m.doc() = "Provides functions to decompose or re-synthesize combinational parts of a gate-level netlist.";
22 #else
23  PYBIND11_PLUGIN(resynthesis)
24  {
25  py::module m("resynthesis", "Provides functions to decompose or re-synthesize combinational parts of a gate-level netlist.");
26 #endif // ifdef PYBIND11_MODULE
27 
28  py::class_<ResynthesisPlugin, RawPtrWrapper<ResynthesisPlugin>, BasePluginInterface> py_resynthesis_plugin(
29  m, "ResynthesisPlugin", R"(This class provides an interface to integrate the netlist resynthesis as a plugin within the HAL framework.)");
30 
31  py_resynthesis_plugin.def_property_readonly("name", &ResynthesisPlugin::get_name, R"(
32  The name of the plugin.
33 
34  :type: str
35  )");
36 
37  py_resynthesis_plugin.def("get_name", &ResynthesisPlugin::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_resynthesis_plugin.def_property_readonly("version", &ResynthesisPlugin::get_version, R"(
45  The version of the plugin.
46 
47  :type: str
48  )");
49 
50  py_resynthesis_plugin.def("get_version", &ResynthesisPlugin::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_resynthesis_plugin.def_property_readonly("description", &ResynthesisPlugin::get_description, R"(
58  The description of the plugin.
59 
60  :type: str
61  )");
62 
63  py_resynthesis_plugin.def("get_description", &ResynthesisPlugin::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_resynthesis_plugin.def_property_readonly("dependencies", &ResynthesisPlugin::get_dependencies, R"(
71  A set of plugin names that this plugin depends on.
72 
73  :type: set[str]
74  )");
75 
76  py_resynthesis_plugin.def("get_dependencies", &ResynthesisPlugin::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  "decompose_gate",
85  [](Netlist* nl, Gate* gate, const bool delete_gate = true) -> bool {
86  auto res = resynthesis::decompose_gate(nl, gate, delete_gate);
87  if (res.is_ok())
88  {
89  return true;
90  }
91  else
92  {
93  log_error("python_context", "{}", res.get_error().get());
94  return false;
95  }
96  },
97  py::arg("nl"),
98  py::arg("gate"),
99  py::arg("delete_gate") = true,
100  R"(
101  Decompose a combinational gate into a small circuit of AND, OR, XOR, and INVERT gates.
102  For each output pin, the resolved Boolean function (only dependent on input pins) is determined.
103  All these Boolean functions are then converted into a netlist using the previously mentioned primitive gates.
104  The target gate is then replaced in the original netlist with the circuit that was just generated.
105  The target gate is only deleted if ``delete_gate`` is set to ``True``.
106  Gate replacement will fail if the gate library of the netlist does not contain suitable AND, OR, XOR, and INVERT gate types.
107 
108  :param hal_py.Netlist nl: The netlist to operate on.
109  :param hal_py.Gate gate: The gate to decompose.
110  :param bool delete_gate: Set ``True`` to delete the original gate, ``False`` to keep it in the netlist. Defaults to ``True``.
111  :returns: ``True`` on success, ``False`` otherwise.
112  :rtype: bool
113  )");
114 
115  m.def(
116  "decompose_gates_of_type",
117  [](Netlist* nl, const std::vector<const GateType*>& gate_types) -> std::optional<u32> {
118  auto res = resynthesis::decompose_gates_of_type(nl, gate_types);
119  if (res.is_ok())
120  {
121  return res.get();
122  }
123  else
124  {
125  log_error("python_context", "{}", res.get_error().get());
126  return std::nullopt;
127  }
128  },
129  py::arg("nl"),
130  py::arg("gate_types"),
131  R"(
132  Decompose all combinational gates of the specified types into small circuits of AND, OR, XOR, and INVERT gates.
133  For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
134  All these Boolean functions are then converted into a circuit using the previously mentioned primitive gates.
135  The target gates are then replaced (and thereby deleted) in the original netlist with the circuit that was just generated.
136  Gate replacement will fail if the gate library of the netlist does not contain suitable AND, OR, XOR, and INVERT gate types.
137 
138  :param hal_py.Netlist nl: The netlist to operate on.
139  :param list[hal_py.GateType] gate_types: The gate types to be decomposed.
140  :returns: The number of decomposed gates on success, ``None`` otherwise.
141  :rtype: int or ``None``
142  )");
143 
144  m.def(
145  "resynthesize_gate",
146  [](Netlist* nl, Gate* gate, GateLibrary* target_gl, const bool delete_gate) -> bool {
147  auto res = resynthesis::resynthesize_gate(nl, gate, target_gl, delete_gate);
148  if (res.is_ok())
149  {
150  return true;
151  }
152  else
153  {
154  log_error("python_context", "{}", res.get_error().get());
155  return false;
156  }
157  },
158  py::arg("nl"),
159  py::arg("gate"),
160  py::arg("target_gl"),
161  py::arg("delete_gate") = true,
162  R"(
163  Re-synthesize a combinational gate by calling Yosys on a functional description of the gate using a reduced gate library.
164  For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
165  All these Boolean functions are then written to an HDL file that is functionally equivalent to the target gate.
166  This file is fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
167  The provided gate library should be a subset of the gate library that was used to parse the netlist.
168  The target gate is then replaced in the original netlist with the circuit that was just generated.
169  The target gate is only deleted if ``delete_gate`` is set to ``True``.
170 
171  :param hal_py.Netlist nl: The netlist to operate on.
172  :param hal_py.Gate gate: The gate to re-synthesize.
173  :param hal_py.GateLibrary target_gl: The gate library that is a subset of the gate library used to parse the netlist.
174  :param bool delete_gate: Set ``True`` to delete the original gate, ``False`` to keep it in the netlist. Defaults to ``True``.
175  :returns: ``True`` on success, ``False`` otherwise.
176  :rtype: bool
177  )");
178 
179  m.def(
180  "resynthesize_gates",
181  [](Netlist* nl, const std::vector<Gate*>& gates, GateLibrary* target_gl) -> std::optional<u32> {
182  auto res = resynthesis::resynthesize_gates(nl, gates, target_gl);
183  if (res.is_ok())
184  {
185  return res.get();
186  }
187  else
188  {
189  log_error("python_context", "{}", res.get_error().get());
190  return std::nullopt;
191  }
192  },
193  py::arg("nl"),
194  py::arg("gates"),
195  py::arg("target_gl"),
196  R"(
197  Re-synthesize all specified combinational gates by calling Yosys on a functional description of the gates using a reduced gate library.
198  For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
199  All Boolean functions of a gate are then written to an HDL file that is functionally equivalent to the gate.
200  These files are fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
201  The provided gate library should be a subset of the gate library that was used to parse the netlist.
202  The gates are then replaced in the original netlist with the circuits that were just generated.
203  This process is repeated for every gate, hence they are re-synthesized in isolation.
204 
205  :param hal_py.Netlist nl: The netlist to operate on.
206  :param hal_py.Gate g: The gates to re-synthesize.
207  :param hal_py.GateLibrary target_gl: The gate library that is a subset of the gate library used to parse the netlist.
208  :returns: The number of re-synthesized gates on success, ``None`` otherwise.
209  :rtype: int or ``None``
210  )");
211 
212  m.def(
213  "resynthesize_gates_of_type",
214  [](Netlist* nl, const std::vector<const GateType*>& gate_types, GateLibrary* target_gl) -> std::optional<u32> {
215  auto res = resynthesis::resynthesize_gates_of_type(nl, gate_types, target_gl);
216  if (res.is_ok())
217  {
218  return res.get();
219  }
220  else
221  {
222  log_error("python_context", "{}", res.get_error().get());
223  return std::nullopt;
224  }
225  },
226  py::arg("nl"),
227  py::arg("gate_types"),
228  py::arg("target_gl"),
229  R"(
230  Re-synthesize all combinational gates of the specified types by calling Yosys on a functional description of the gates using a reduced gate library.
231  For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
232  All Boolean functions of a gate are then written to an HDL file that is functionally equivalent to the gate.
233  These files are fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
234  The provided gate library should be a subset of the gate library that was used to parse the netlist.
235  The gates are then replaced in the original netlist with the circuits that were just generated.
236  This process is repeated for every gate, hence they are re-synthesized in isolation.
237 
238  :param hal_py.Netlist nl: The netlist to operate on.
239  :param list[hal_py.GateType] gate_types: The gate types to be re-synthesized.
240  :param hal_py.GateLibrary target_gl: The gate library that is a subset of the gate library used to parse the netlist.
241  :returns: The number of re-synthesized gates on success, ``None`` otherwise.
242  :rtype: int or ``None``
243  )");
244 
245  m.def(
246  "resynthesize_subgraph",
247  [](Netlist* nl, const std::vector<Gate*>& subgraph, GateLibrary* target_gl) -> std::optional<u32> {
248  auto res = resynthesis::resynthesize_subgraph(nl, subgraph, target_gl);
249  if (res.is_ok())
250  {
251  return res.get();
252  }
253  else
254  {
255  log_error("python_context", "{}", res.get_error().get());
256  return std::nullopt;
257  }
258  },
259  py::arg("nl"),
260  py::arg("subgraph"),
261  py::arg("target_gl"),
262  R"(
263  Re-synthesize the combinational gates of the subgraph by calling Yosys on a Verilog netlist representation of the subgraph using a reduced gate library.
264  All gates of the subgraph are written to a Verilog netlist file which is then fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
265  The provided gate library should be a subset of the gate library that was used to parse the netlist.
266  The gates are then replaced in the original netlist with the circuit that was just generated.
267 
268  :param hal_py.Netlist nl: The netlist to operate on.
269  :param list[hal_py.Gate] subgraph: The subgraph to re-synthesize.
270  :param hal_py.GateLibrary target_lib: The gate library that is a subset of the gate library used to parse the netlist.
271  :returns: The number of re-synthesized gates on success, ``None`` otherwise.
272  :rtype: int or ``None``
273  )");
274 
275  m.def(
276  "resynthesize_subgraph_of_type",
277  [](Netlist* nl, const std::vector<const GateType*>& gate_types, GateLibrary* target_gl) -> std::optional<u32> {
278  auto res = resynthesis::resynthesize_subgraph_of_type(nl, gate_types, target_gl);
279  if (res.is_ok())
280  {
281  return res.get();
282  }
283  else
284  {
285  log_error("python_context", "{}", res.get_error().get());
286  return std::nullopt;
287  }
288  },
289  py::arg("nl"),
290  py::arg("gate_types"),
291  py::arg("target_gl"),
292  R"(
293  Re-synthesize the combinational gates of the specified types as a subgraph by calling Yosys on a Verilog netlist representation of the subgraph induced by these gates using a reduced gate library.
294  All gates of the subgraph are written to a Verilog netlist file which is then fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
295  The provided gate library should be a subset of the gate library that was used to parse the netlist.
296  The gates are then replaced in the original netlist with the circuit that was just generated.
297 
298  :param hal_py.Netlist nl: The netlist to operate on.
299  :param list[hal_py.GateType] gate_types: The gate types to be re-synthesized.
300  :param hal_py.GateLibrary target_lib: The gate library that is a subset of the gate library used to parse the netlist.
301  :returns: The number of re-synthesized gates on success, ``None`` otherwise.
302  :rtype: int or ``None``
303  )");
304 
305 #ifndef PYBIND11_MODULE
306  return m.ptr();
307 #endif // PYBIND11_MODULE
308  }
309 } // namespace hal
Definition: gate.h:58
std::string get_description() const override
Get a short description of the plugin.
std::string get_name() const override
Get the name of the plugin.
std::set< std::string > get_dependencies() const override
Get the plugin dependencies.
std::string get_version() const override
Get the version of the plugin.
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Result< u32 > resynthesize_gates(Netlist *nl, const std::vector< Gate * > &gates, GateLibrary *target_gl)
Result< std::monostate > decompose_gate(Netlist *nl, Gate *gate, const bool delete_gate=true)
Result< std::monostate > resynthesize_gate(Netlist *nl, Gate *gate, GateLibrary *target_gl, const bool delete_gate=true)
Result< u32 > decompose_gates_of_type(Netlist *nl, const std::vector< const GateType * > &gate_types)
Result< u32 > resynthesize_subgraph_of_type(Netlist *nl, const std::vector< const GateType * > &gate_types, GateLibrary *target_gl)
Result< u32 > resynthesize_subgraph(Netlist *nl, const std::vector< Gate * > &subgraph, GateLibrary *target_gl)
Result< u32 > resynthesize_gates_of_type(Netlist *nl, const std::vector< const GateType * > &gate_types, GateLibrary *target_gl)
Definition: defines.h:45
PYBIND11_PLUGIN(hal_py)
This file contains all functions related to the HAL plugin API.
This file contains functions to decompose or re-synthesize combinational parts of a gate-level netlis...