HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
module.cpp
Go to the documentation of this file.
2 
3 namespace hal
4 {
6  {
7  py::class_<Module, DataContainer, RawPtrWrapper<Module>> py_module(m, "Module", R"(
8  A module is a container for gates and their associated nets that enables hierarchization within the netlist.
9  Each gate can only be in one module at a time. Nets are only loosely associated with modules.
10  )");
11 
12  py_module.def(py::self == py::self, R"(
13  Check whether two modules are equal.
14  Does not check for parent module.
15 
16  :returns: ``True`` if both modules are equal, ``False`` otherwise.
17  :rtype: bool
18  )");
19 
20  py_module.def(py::self != py::self, R"(
21  Check whether two modules are unequal.
22  Does not check for parent module.
23 
24  :returns: ``True`` if both modules are unequal, ``False`` otherwise.
25  :rtype: bool
26  )");
27 
28  py_module.def("__hash__", &Module::get_hash, R"(
29  Python requires hash for set and dict container.
30 
31  :returns: The hash.
32  :rtype: Py_hash_t
33  )");
34 
35  py_module.def_property_readonly("id", &Module::get_id, R"(
36  The unique ID of the module.
37 
38  :type: int
39  )");
40 
41  py_module.def("get_id", &Module::get_id, R"(
42  Get the unique ID of the module.
43 
44  :returns: The unique id.
45  :rtype: int
46  )");
47 
48  py_module.def_property("name", &Module::get_name, &Module::set_name, R"(
49  The name of the module.
50 
51  :type: str
52  )");
53 
54  py_module.def("get_name", &Module::get_name, R"(
55  Get the name of the module.
56 
57  :returns: The name.
58  :rtype: str
59  )");
60 
61  py_module.def("set_name", &Module::set_name, py::arg("name"), R"(
62  Set the name of the module.
63 
64  :param str name: The new name.
65  )");
66 
67  py_module.def_property("type", &Module::get_type, &Module::set_type, R"(
68  The type of the module.
69 
70  :type: str
71  )");
72 
73  py_module.def("get_type", &Module::get_type, R"(
74  Get the type of the module.
75 
76  :returns: The type.
77  :rtype: str
78  )");
79 
80  py_module.def("set_type", &Module::set_type, py::arg("type"), R"(
81  Set the type of the module.
82 
83  :param str type: The new type.
84  )");
85 
86  py_module.def("get_grouping", &Module::get_grouping, R"(
87  Get the grouping in which this module is contained.
88 
89  :returns: The grouping.
90  :rtype: hal_py.Grouping
91  )");
92 
93  py_module.def_property_readonly("submodule_depth", &Module::get_submodule_depth, R"(
94  The depth of the module within the module hierarchie (0 = top module, 1 = direct child of top module, ...).
95 
96  :type: int
97  )");
98 
99  py_module.def("get_submodule_depth", &Module::get_submodule_depth, R"(
100  Get the depth of the module within the module hierarchie (0 = top module, 1 = direct child of top module, ...).
101 
102  :returns: The depth within the module hierarchie.
103  :rtype: int
104  )");
105 
106  py_module.def_property("parent_module", &Module::get_parent_module, &Module::set_parent_module, R"(
107  The parent module of this module.
108  Is set to ``None`` for the top module, but cannot be set to ``None`` by the user.
109 
110  :type: hal_py.Module or None
111  )");
112 
113  py_module.def("get_parent_module", &Module::get_parent_module, R"(
114  Get the parent module of this module.
115  For the top module, ``None`` is returned.
116 
117  :returns: The parent module.
118  :rtype: hal_py.Module or None
119  )");
120 
121  py_module.def_property_readonly("parent_modules", [](Module* mod) { return mod->get_parent_modules(); }, R"(
122  The parent modules of this module.
123 
124  :type: list[hal_py.Module]
125  )");
126 
127  py_module.def("get_parent_modules", &Module::get_parent_modules, py::arg("filter") = nullptr, py::arg("recursive") = true, R"(
128  Get all parents of this module.
129  If ``recursive`` is set to ``True``, all indirect parents are also included.
130  The optional filter is evaluated on every candidate such that the result only contains those matching the specified condition.
131 
132  :param lambda filter: An optional filter.
133  :param bool recursive: Set ``True`` to include indirect parents as well, ``False`` otherwise.
134  :returns: A list of parent modules.
135  :rtype: list[hal_py.Module]
136  )");
137 
138  py_module.def("set_parent_module", &Module::set_parent_module, py::arg("new_parent"), R"(
139  Set a new parent for this module.
140  If the new parent is a submodule of this module, the new parent is added as a direct submodule to the old parent first.
141 
142  :param hal_py.Module new_parent: The new parent module.
143  :returns: ``True`` if the parent was changed, ``False`` otherwise.
144  :rtype: bool
145  )");
146 
147  py_module.def("is_parent_module_of", &Module::is_parent_module_of, py::arg("module"), py::arg("recursive") = false, R"(
148  Check if the module is a parent of the specified module.
149 
150  :param hal_py.Module module: The module.
151  :param bool recursive: Set ``True`` to check recursively, ``False`` otherwise.
152  :returns: ``True`` if the module is a parent of the specified module, ``False`` otherwise.
153  :rtype: bool
154  )");
155 
156  py_module.def_property_readonly("submodules", [](Module* mod) { return mod->get_submodules(); }, R"(
157  A list of all direct submodules of this module.
158 
159  :type: list[hal_py.Module]
160  )");
161 
162  py_module.def("get_submodules", &Module::get_submodules, py::arg("filter") = nullptr, py::arg("recursive") = false, R"(
163  Get all direct submodules of this module.
164  If ``recursive`` is set to ``True``, all indirect submodules are also included.
165  The optional filter is evaluated on every candidate such that the result only contains those matching the specified condition.
166 
167  :param lambda filter: An optional filter.
168  :param bool recursive: Set ``True`` to include indirect submodules as well, ``False`` otherwise.
169  :returns: A list of submodules.
170  :rtype: list[hal_py.Module]
171  )");
172 
173  py_module.def("is_submodule_of", &Module::is_submodule_of, py::arg("module"), py::arg("recursive") = false, R"(
174  Check if the module is a submodule of the specified module.
175 
176  :param hal_py.Module module: The module.
177  :param bool recursive: Set ``True`` to check recursively, ``False`` otherwise.
178  :returns: ``True`` if the module is a submodule of the specified module, ``False`` otherwise.
179  :rtype: bool
180  )");
181 
182  py_module.def("contains_module", &Module::contains_module, py::arg("other"), py::arg("recursive") = false, R"(
183  Checks whether another module is a submodule of this module.
184  If recursive is set to ``True``, all indirect submodules are also included.
185 
186  :param hal_py.Module other: Other module to check for.
187  :param bool recursive: Set ``True`` to include indirect submodules as well, ``False`` otherwise.
188  :returns: ``True`` if the other module is a submodule, ``False`` otherwise.
189  :rtype: bool
190  )");
191 
192  py_module.def_property_readonly("top_module", &Module::is_top_module, R"(
193  ``True`` only if the module is the top module of the netlist.
194 
195  :type: bool
196  )");
197 
198  py_module.def("is_top_module", &Module::is_top_module, R"(
199  Returns ``True`` only if the module is the top module of the netlist.
200 
201  :returns: ``True`` if the module is the top module, ``False`` otherwise.
202  :rtype: bool
203  )");
204 
205  py_module.def_property_readonly("netlist", [](Module* module) { return RawPtrWrapper<Netlist>(module->get_netlist()); }, R"(
206  The netlist this module is associated with.
207 
208  :type: hal_py.Netlist
209  )");
210 
211  py_module.def("get_netlist", [](Module* module) { return RawPtrWrapper<Netlist>(module->get_netlist()); }, R"(
212  Get the netlist this module is associated with.
213 
214  :returns: The netlist.
215  :rtype: hal_py.Netlist
216  )");
217 
218  py_module.def("update_nets", &Module::update_nets, R"(
219  Iterates over all nets connected to at least one gate of the module to update the nets, internal nets, input nets, and output nets of the module.
220  Has no effect on module pins.
221 
222  WARNING: can only be used when automatic net checks have been disabled using hal_py.Netlist.enable_automatic_net_checks.
223  )");
224 
225  py_module.def("contains_net", &Module::contains_net, py::arg("net"), py::arg("recursive") = false, R"(
226  Check whether a net is contained in the module.
227  If ``recursive`` is set to ``True``, nets in submodules are considered as well.
228 
229  :param hal_py.Net net: The net to check for.
230  :param bool recursive: ``True`` to also consider nets in submodules, ``False`` otherwise.
231  :returns: ``True`` if the net is contained in the module, ``False`` otherwise.
232  :rtype: bool
233  )");
234 
235  py_module.def_property_readonly("nets", py::overload_cast<>(&Module::get_nets, py::const_), R"(
236  An unordered set of all nets that have at least one source or one destination within the module.
237 
238  :type: set[hal_py.Net]
239  )");
240 
241  py_module.def("get_nets", py::overload_cast<>(&Module::get_nets, py::const_), R"(
242  Get all nets that have at least one source or one destination within the module.
243 
244  :returns: An unordered set of nets.
245  :rtype: set[hal_py.Net]
246  )");
247 
248  py_module.def("get_nets", py::overload_cast<const std::function<bool(Net*)>&, bool>(&Module::get_nets, py::const_), py::arg("filter"), py::arg("recursive") = false, R"(
249  Get all nets that have at least one source or one destination within the module.
250  The filter is evaluated on every candidate such that the result only contains those matching the specified condition.
251  If ``recursive`` is ``True``, nets in submodules are considered as well.
252 
253  :param lambda filter: Filter function to be evaluated on each net.
254  :param bool recursive: ``True`` to also consider nets in submodules, ``False`` otherwise.
255  :returns: An unordered set of nets.
256  :rtype: set[hal_py.Net]
257  )");
258 
259  py_module.def_property_readonly("input_nets", &Module::get_input_nets, R"(
260  A set of all nets that are either a global input to the netlist or have at least one source outside of the module.
261 
262  :type: set[hal_py.Net]
263  )");
264 
265  py_module.def("get_input_nets", &Module::get_input_nets, R"(
266  Get all nets that are either a global input to the netlist or have at least one source outside of the module.
267 
268  :returns: A set of input nets.
269  :rtype: set[hal_py.Net]
270  )");
271 
272  py_module.def_property_readonly("output_nets", &Module::get_output_nets, R"(
273  A set of all nets that are either a global output to the netlist or have at least one destination outside of the module.
274 
275  :type: set[hal_py.Net]
276  )");
277 
278  py_module.def("get_output_nets", &Module::get_output_nets, R"(
279  Get all nets that are either a global output to the netlist or have at least one destination outside of the module.
280 
281  :returns: A set of output nets.
282  :rtype: set[hal_py.Net]
283  )");
284 
285  py_module.def_property_readonly("internal_nets", &Module::get_internal_nets, R"(
286  A set of all nets that have at least one source and one destination within the module, including its submodules. The result may contain nets that are also regarded as input or output nets.
287 
288  :type: set[hal_py.Net]
289  )");
290 
291  py_module.def("get_internal_nets", &Module::get_internal_nets, R"(
292  Get all nets that have at least one source and one destination within the module, including its submodules. The result may contain nets that are also regarded as input or output nets.
293 
294  :returns: A set of internal nets.
295  :rtype: set[hal_py.Net]
296  )");
297 
298  py_module.def("is_input_net", &Module::is_input_net, py::arg("net"), R"(
299  Check whether the given net is an input of the module, i.e., whether the net is a global input to the netlist or has at least one source outside of the module.
300 
301  :param hal_py.Net net: The net.
302  :returns: ``True`` if the net is an input net, ``False`` otherwise.
303  :rtype: bool
304  )");
305 
306  py_module.def("is_output_net", &Module::is_output_net, py::arg("net"), R"(
307  Check whether the given net is an output of the module, i.e., whether the net is a global output to the netlist or has at least one destination outside of the module.
308 
309  :param hal_py.Net net: The net.
310  :returns: ``True`` if the net is an output net, ``False`` otherwise.
311  :rtype: bool
312  )");
313 
314  py_module.def("is_internal_net", &Module::is_internal_net, py::arg("net"), R"(
315  Check whether the given net is an internal net of the module, i.e. whether the net has at least one source and one destination within the module.
316 
317  :param hal_py.Net net: The net.
318  :returns: ``True`` if the net is an internal net, ``False`` otherwise.
319  :rtype: bool
320  )");
321 
322  py_module.def("assign_gate", &Module::assign_gate, py::arg("gate"), R"(
323  Assign a gate to the module.
324  The gate is removed from its previous module in the process.
325 
326  :param hal_py.Gate gate: The gate to assign.
327  :returns: ``True`` on success, ``False`` otherwise.
328  :rtype: bool
329  )");
330 
331  py_module.def("assign_gates", &Module::assign_gates, py::arg("gates"), R"(
332  Assign a list of gates to the module.
333  The gates are removed from their previous module in the process.
334 
335  :param list[hal_py.Gate] gates: The gates to assign.
336  :returns: ``True`` on success, ``False`` otherwise.
337  :rtype: bool
338  )");
339 
340  py_module.def("remove_gate", &Module::remove_gate, py::arg("gate"), R"(
341  Remove a gate from the module.
342  Automatically moves the gate to the top module of the netlist.
343 
344  :param hal_py.Gate gate: The gate to remove.
345  :returns: ``True`` on success, ``False`` otherwise.
346  :rtype: bool
347  )");
348 
349  py_module.def("remove_gates", &Module::remove_gates, py::arg("gates"), R"(
350  Remove a list of gates from the module.
351  Automatically moves the gates to the top module of the netlist.
352 
353  :param list[hal_py.Gate] gates: The gates to remove.
354  :returns: ``True`` on success, ``False`` otherwise.
355  :rtype: bool
356  )");
357 
358  py_module.def("contains_gate", &Module::contains_gate, py::arg("gate"), py::arg("recursive") = false, R"(
359  Check whether a gate is contained in the module.
360  If ``recursive`` is ``True``, gates in submodules are considered as well.
361 
362  :param hal_py.Gate gate: The gate to check for.
363  :param bool recursive: ``True`` to also consider gates in submodules, ``False`` otherwise.
364  :returns: ``True`` if the gate is contained in the module, ``False`` otherwise.
365  :rtype: bool
366  )");
367 
368  py_module.def("get_gate_by_id", &Module::get_gate_by_id, py::arg("id"), py::arg("recursive") = false, R"(
369  Get a gate specified by the given ID.
370  If ``recursive`` is ``True``, gates in submodules are considered as well.
371 
372  :param int id: The unique ID of the gate.
373  :param bool recursive: ``True`` to also consider gates in submodules, ``False`` otherwise.
374  :returns: The gate if found, ``None`` otherwise.
375  :rtype: hal_py.Gate or None
376  )");
377 
378  py_module.def_property_readonly("gates", py::overload_cast<>(&Module::get_gates, py::const_), R"(
379  The list of all gates contained within the module.
380 
381  :type: list[hal_py.Gate]
382  )");
383 
384  py_module.def("get_gates", py::overload_cast<>(&Module::get_gates, py::const_), R"(
385  Get all gates contained within the module.
386 
387  :returns: A list of gates.
388  :rtype: list[hal_py.Gate]
389  )");
390 
391  py_module.def("get_gates", py::overload_cast<const std::function<bool(Gate*)>&, bool>(&Module::get_gates, py::const_), py::arg("filter") = nullptr, py::arg("recursive") = false, R"(
392  Get all gates contained within the module.
393  The filter is evaluated on every candidate such that the result only contains those matching the specified condition.
394  If ``recursive`` is ``True``, gates in submodules are considered as well.
395 
396  :param lambda filter: Filter function to be evaluated on each gate.
397  :param bool recursive: ``True`` to also consider gates in submodules, ``False`` otherwise. Defaults to ``False``.
398  :returns: A list of gates.
399  :rtype: list[hal_py.Gate]
400  )");
401 
402  py_module.def("get_unique_pin_id", &Module::get_unique_pin_id, R"(
403  Get a spare pin ID.
404  The value of 0 is reserved and represents an invalid ID.
405 
406  :returns: The pin ID.
407  :rtype: int
408  )");
409 
410  py_module.def("get_unique_pin_group_id", &Module::get_unique_pin_group_id, R"(
411  Get a spare pin group ID.
412  The value of 0 is reserved and represents an invalid ID.
413 
414  :returns: The pin group ID.
415  :rtype: int
416  )");
417 
418  py_module.def(
419  "create_pin",
420  [](Module& self, const u32 id, const std::string& name, Net* net, PinType type = PinType::none, bool create_group = true, bool force_name = false) -> ModulePin* {
421  auto res = self.create_pin(id, name, net, type, create_group, force_name);
422  if (res.is_ok())
423  {
424  return res.get();
425  }
426  else
427  {
428  log_error("python_context", "error encountered while creating pin:\n{}", res.get_error().get());
429  return nullptr;
430  }
431  },
432  py::arg("id"),
433  py::arg("name"),
434  py::arg("net"),
435  py::arg("type") = PinType::none,
436  py::arg("create_group") = true,
437  py::arg("force_name") = false,
438  R"(
439  Manually create a module pin and assign it to a net.
440  Checks whether the given direction matches the actual properties of the net, i.e., checks whether the net actually is an input and/or output to the module.
441  Hence, make sure to update the module nets beforehand using ``hal_py.Module.update_nets``.
442  If ``create_group`` is set to ``False``, the pin will not be added to a pin group.
443 
444  WARNING: can only be used when automatic net checks have been disabled using ``hal_py.Netlist.enable_automatic_net_checks``.
445 
446  :param int id: The ID of the pin.
447  :param str name: The name of the pin.
448  :param hal_py.Net net: The net that the pin is being assigned to.
449  :param hal_py.PinType type: The type of the pin. Defaults to ``hal_py.PinType.none``.
450  :param bool create_group: Set ``True`` to automatically create a pin group and assign the pin, ``False`` otherwise. Defaults to ``True``.
451  :param bool force_name: Set ``True`` to enforce the name, ``False`` otherwise. If a pin with the same name already exists, that existing pin will be renamed. Defaults to ``False``.
452  :returns: The module pin on success, ``None`` otherwise.
453  :rtype: hal_py.ModulePin or None
454  )");
455 
456  py_module.def(
457  "create_pin",
458  [](Module& self, const std::string& name, Net* net, PinType type = PinType::none, bool create_group = true, bool force_name = false) -> ModulePin* {
459  auto res = self.create_pin(name, net, type, create_group, force_name);
460  if (res.is_ok())
461  {
462  return res.get();
463  }
464  else
465  {
466  log_error("python_context", "error encountered while creating pin:\n{}", res.get_error().get());
467  return nullptr;
468  }
469  },
470  py::arg("name"),
471  py::arg("net"),
472  py::arg("type") = PinType::none,
473  py::arg("create_group") = true,
474  py::arg("force_name") = false,
475  R"(
476  Manually create a module pin and assign it to a net.
477  The ID of the pin is set automatically.
478  Checks whether the given direction matches the actual properties of the net, i.e., checks whether the net actually is an input and/or output to the module.
479  Hence, make sure to update the module nets beforehand using ``hal_py.Module.update_nets``.
480  If ``create_group`` is set to ``False``, the pin will not be added to a pin group.
481 
482  WARNING: can only be used when automatic net checks have been disabled using ``hal_py.Netlist.enable_automatic_net_checks``.
483 
484  :param str name: The name of the pin.
485  :param hal_py.Net net: The net that the pin is being assigned to.
486  :param hal_py.PinType type: The type of the pin. Defaults to ``hal_py.PinType.none``.
487  :param bool create_group: Set ``True`` to automatically create a pin group and assign the pin, ``False`` otherwise. Defaults to ``True``.
488  :param bool force_name: Set ``True`` to enforce the name, ``False`` otherwise. If a pin with the same name already exists, that existing pin will be renamed. Defaults to ``False``.
489  :returns: The module pin on success, ``None`` otherwise.
490  :rtype: hal_py.ModulePin or None
491  )");
492 
493  py_module.def_property_readonly("pins", &Module::get_pins, R"(
494  The (ordered) pins of the module.
495 
496  :type: list[hal_py.ModulePin]
497  )");
498 
499  py_module.def("get_pins", &Module::get_pins, py::arg("filter") = nullptr, R"(
500  Get an ordered list of all pins of the module.
501  The optional filter is evaluated on every candidate such that the result only contains those matching the specified condition.
502 
503  :param lambda filter: An optional filter.
504  :returns: An ordered list of pins.
505  :rtype: list[hal_py.ModulePin]
506  )");
507 
508  py_module.def_property_readonly(
509  "pin_names",
510  [](const Module& self) -> std::vector<std::string> { return self.get_pin_names(); },
511  R"(
512  An ordered list of the names of all pins of the module.
513 
514  :type: list[str]
515  )");
516 
517  py_module.def("get_pin_names", &Module::get_pin_names, py::arg("filter") = nullptr, R"(
518  Get an ordered list of the names of all pins of the module.
519  The optional filter is evaluated on every candidate such that the result only contains those matching the specified condition.
520 
521  :returns: A list of input pin names of the module.
522  :param lambda filter: An optional filter.
523  :returns: An ordered list of pin names.
524  :rtype: list[str]
525  )");
526 
527  py_module.def_property_readonly("input_pins", &Module::get_input_pins, R"(
528  An ordered list of all input pins of the module (including inout pins).
529 
530  :type: list[hal_py.ModulePin]
531  )");
532 
533  py_module.def("get_input_pins", &Module::get_input_pins, R"(
534  Get an ordered list of all input pins of the module (including inout pins).
535 
536  :returns: An ordered list of input pins.
537  :rtype: list[hal_py.ModulePin]
538  )");
539 
540  py_module.def_property_readonly("input_pin_names", &Module::get_input_pin_names, R"(
541  An ordered list of the names of all input pins of the module (including inout pins).
542 
543  :type: list[str]
544  )");
545 
546  py_module.def("get_input_pin_names", &Module::get_input_pin_names, R"(
547  Get an ordered list of the names of all input pins of the module (including inout pins).
548 
549  :returns: An ordered list of input pin names.
550  :rtype: list[str]
551  )");
552 
553  py_module.def_property_readonly("output_pins", &Module::get_output_pins, R"(
554  An ordered list of all output pins of the module (including inout pins).
555 
556  :type: list[hal_py.ModulePin]
557  )");
558 
559  py_module.def("get_output_pins", &Module::get_output_pins, R"(
560  Get an ordered list of all output pins of the module (including inout pins).
561 
562  :returns: An ordered list of output pins.
563  :rtype: list[hal_py.ModulePin]
564  )");
565 
566  py_module.def_property_readonly("output_pin_names", &Module::get_output_pin_names, R"(
567  An ordered list of the names of all output pins of the module (including inout pins).
568 
569  :type: list[str]
570  )");
571 
572  py_module.def("get_output_pin_names", &Module::get_output_pin_names, R"(
573  Get an ordered list of the names of all output pins of the module (including inout pins).
574 
575  :returns: An ordered list of output pin names.
576  :rtype: list[str]
577  )");
578 
579  py_module.def_property_readonly("pin_groups", &Module::get_pin_groups, R"(
580  All pin_groups of the module.
581 
582  :type: list[hal_py.ModulePinGroup]
583  )");
584 
585  py_module.def("get_pin_groups", &Module::get_pin_groups, py::arg("filter") = nullptr, R"(
586  Get all pin groups of the module.
587  The optional filter is evaluated on every candidate such that the result only contains those matching the specified condition.
588 
589  :param lambda filter: An optional filter.
590  :returns: A list of pin groups.
591  :rtype: list[hal_py.ModulePinGroup]
592  )");
593 
594  py_module.def("get_pin_by_id", &Module::get_pin_by_id, py::arg("id"), R"(
595  Get the pin corresponding to the given ID.
596 
597  :param int id: The ID of the pin.
598  :returns: The pin on success, ``None`` otherwise.
599  :rtype: hal_py.ModulePin or None
600  )");
601 
602  py_module.def("get_pin_by_name", &Module::get_pin_by_name, py::arg("name"), R"(
603  Get the pin corresponding to the given name.
604 
605  :param str name: The name of the pin.
606  :returns: The pin on success, ``None`` otherwise.
607  :rtype: hal_py.ModulePin or None
608  )");
609 
610  py_module.def("get_pin_by_net", &Module::get_pin_by_net, py::arg("net"), R"(
611  Get the pin that passes through the specified net.
612 
613  :param hal_py.Net net: The net.
614  :returns: The pin on success, ``None`` otherwise.
615  :rtype: hal_py.ModulePin or None
616  )");
617 
618  py_module.def("get_pin_group_by_id", &Module::get_pin_group_by_id, py::arg("id"), R"(
619  Get the pin group corresponding to the given ID.
620 
621  :param int id: The ID of the pin group.
622  :returns: The pin group on success, ``None`` otherwise.
623  :rtype: hal_py.ModulePinGroup or None
624  )");
625 
626  py_module.def("get_pin_group_by_name", &Module::get_pin_group_by_name, py::arg("name"), R"(
627  Get the pin group corresponding to the given name.
628 
629  :param str name: The name of the pin group.
630  :returns: The pin group on success, ``None`` otherwise.
631  :rtype: hal_py.ModulePinGroup or None
632  )");
633 
634  py_module.def("set_pin_name", &Module::set_pin_name, py::arg("pin"), py::arg("new_name"), py::arg("force_name") = false, R"(
635  Set the name of the given pin.
636 
637  :param hal_py.ModulePin pin: The pin.
638  :param str new_name: The name to be assigned to the pin.
639  :param bool force_name: Set ``True`` to enforce the name, ``False`` otherwise. If a pin with the same name already exists, that existing pin will be renamed. Defaults to ``False``.
640  :returns: ``True`` on success, ``False`` otherwise.
641  :rtype: bool
642  )");
643 
644  py_module.def("set_pin_group_name", &Module::set_pin_group_name, py::arg("pin_group"), py::arg("new_name"), py::arg("force_name") = false, R"(
645  Set the name of the given pin group.
646 
647  :param hal_py.ModulePinGroup pin_group: The pin group.
648  :param str new_name: The name to be assigned to the pin group.
649  :param bool force_name: Set ``True`` to enforce the name, ``False`` otherwise. If a pin group with the same name already exists, the existing pin group will be renamed. Defaults to ``False``.
650  :returns: ``True`` on success, ``False`` otherwise.
651  :rtype: bool
652  )");
653 
654  py_module.def("set_pin_type", &Module::set_pin_type, py::arg("pin"), py::arg("new_type"), R"(
655  Set the type of the given pin.
656 
657  :param hal_py.ModulePin pin: The pin.
658  :param hal_py.PinType new_type: The type to be assigned to the pin.
659  :returns: ``True`` on success, ``False`` otherwise.
660  :rtype: bool
661  )");
662 
663  py_module.def("set_pin_group_type", &Module::set_pin_group_type, py::arg("pin_group"), py::arg("new_type"), R"(
664  Set the type of the given pin group.
665 
666  :param hal_py.ModulePinGroup pin_group: The pin group.
667  :param hal_py.PinType new_type: The type to be assigned to the pin group.
668  :returns: ``True`` on success, ``False`` otherwise.
669  :rtype: bool
670  )");
671 
672  py_module.def("set_pin_group_direction", &Module::set_pin_group_direction, py::arg("pin_group"), py::arg("new_direction"), R"(
673  Set the direction of the given pin group.
674 
675  :param hal_py.ModulePinGroup pin_group: The pin group.
676  :param hal_py.PinDirection new_direction: The direction to be assigned to the pin group.
677  :returns: ``True`` on success, ``False`` otherwise.
678  :rtype: bool
679  )");
680 
681  py_module.def(
682  "create_pin_group",
683  [](Module& self,
684  const u32 id,
685  const std::string& name,
686  const std::vector<ModulePin*> pins = {},
689  bool ascending = false,
690  u32 start_index = UINT_MAX, // placeholder for default depending on ascending <-> descending
691  bool delete_empty_groups = true,
692  bool force_name = false) -> PinGroup<ModulePin>* {
693  if (start_index == UINT_MAX)
694  {
695  if (ascending || pins.empty())
696  start_index = 0;
697  else
698  start_index = pins.size() - 1;
699  }
700  auto res = self.create_pin_group(id, name, pins, direction, type, ascending, start_index, delete_empty_groups, force_name);
701  if (res.is_ok())
702  {
703  return res.get();
704  }
705  else
706  {
707  log_error("python_context", "error encountered while creating pin group:\n{}", res.get_error().get());
708  return nullptr;
709  }
710  },
711  py::arg("id"),
712  py::arg("name"),
713  py::arg("pins") = std::vector<ModulePin*>(),
714  py::arg("direction") = PinDirection::none,
715  py::arg("type") = PinType::none,
716  py::arg("ascending") = false,
717  py::arg("start_index") = UINT_MAX,
718  py::arg("delete_empty_groups") = true,
719  py::arg("force_name") = false,
720  R"(
721  Create a new pin group with the given name.
722  All pins to be added to the pin group must have the same direction and type.
723 
724  :param int id: The ID of the pin group.
725  :param str name: The name of the pin group.
726  :param list[hal_py.ModulePin] pins: The pins to be assigned to the pin group. Defaults to an empty list.
727  :param hal_py.PinDirection direction: The direction of the pin group, if any. Defaults to ``hal_py.PinDirection.none``.
728  :param hal_py.PinType type: The type of the pin group, if any. Defaults to ``hal_py.PinType.none``.
729  :param bool ascending: Set ``True`` for ascending pin order (from 0 to n-1), ``False`` otherwise (from n-1 to 0). Defaults to ``True``.
730  :param int start_index: The start index of the pin group. Defaults to ``0``.
731  :param bool delete_empty_groups: Set ``True`` to delete groups that are empty after the pins have been assigned to the new group, ``False`` to keep empty groups. Defaults to ``True``.
732  :param bool force_name: Set ``True`` to enforce the name, ``False`` otherwise. If a pin group with the same name already exists, the existing pin group will be renamed. Defaults to ``False``.
733  :returns: The pin group on success, ``None`` otherwise.
734  :rtype: hal_py.ModulePinGroup or None
735  )");
736 
737  py_module.def(
738  "create_pin_group",
739  [](Module& self,
740  const std::string& name,
741  const std::vector<ModulePin*> pins = {},
744  bool ascending = false,
745  u32 start_index = UINT_MAX, // placeholder for default depending on ascending <-> descending
746  bool delete_empty_groups = true,
747  bool force_name = false) -> PinGroup<ModulePin>* {
748  if (start_index == UINT_MAX)
749  {
750  if (ascending || pins.empty())
751  start_index = 0;
752  else
753  start_index = pins.size() - 1;
754  }
755  auto res = self.create_pin_group(name, pins, direction, type, ascending, start_index, delete_empty_groups, force_name);
756  if (res.is_ok())
757  {
758  return res.get();
759  }
760  else
761  {
762  log_error("python_context", "error encountered while creating pin group:\n{}", res.get_error().get());
763  return nullptr;
764  }
765  },
766  py::arg("name"),
767  py::arg("pins") = std::vector<ModulePin*>(),
768  py::arg("direction") = PinDirection::none,
769  py::arg("type") = PinType::none,
770  py::arg("ascending") = false,
771  py::arg("start_index") = UINT_MAX,
772  py::arg("delete_empty_groups") = true,
773  py::arg("force_name") = false,
774  R"(
775  Create a new pin group with the given name.
776  All pins to be added to the pin group must have the same direction and type.
777 
778  :param str name: The name of the pin group.
779  :param list[hal_py.ModulePin] pins: The pins to be assigned to the pin group. Defaults to an empty list.
780  :param hal_py.PinDirection direction: The direction of the pin group, if any. Defaults to ``hal_py.PinDirection.none``.
781  :param hal_py.PinType type: The type of the pin group, if any. Defaults to ``hal_py.PinType.none``.
782  :param bool ascending: Set ``True`` for ascending pin order (from 0 to n-1), ``False`` otherwise (from n-1 to 0). Defaults to ``True``.
783  :param int start_index: The start index of the pin group. Defaults to ``0``.
784  :param bool delete_empty_groups: Set ``True``` to delete groups that are empty after the pins have been assigned to the new group, ```False``` to keep empty groups. Defaults to ```True```.
785  :param bool force_name: Set ``True`` to enforce the name, ``False`` otherwise. If a pin group with the same name already exists, the existing pin group will be renamed. Defaults to ``False``.
786  :returns: The pin group on success, ``None`` otherwise.
787  :rtype: hal_py.ModulePinGroup or None
788  )");
789 
790  py_module.def(
791  "delete_pin_group",
792  [](Module& self, PinGroup<ModulePin>* pin_group) {
793  if (self.delete_pin_group(pin_group))
794  {
795  return true;
796  }
797  else
798  {
799  log_error("python_context", "error encountered while deleting pin group.");
800  return false;
801  }
802  },
803  py::arg("pin_group"),
804  R"(
805  Delete the given pin group.
806 
807  :param hal_py.ModulePinGroup pin_group: The pin group to be deleted.
808  :returns: ``True`` on success, ``False`` otherwise.
809  :rtype: bool
810  )");
811 
812  py_module.def(
813  "move_pin_group",
814  [](Module& self, PinGroup<ModulePin>* pin_group, u32 new_index) {
815  if (self.move_pin_group(pin_group, new_index))
816  {
817  return true;
818  }
819  else
820  {
821  log_error("python_context", "error encountered while moving pin group.");
822  return false;
823  }
824  },
825  py::arg("pin_group"),
826  py::arg("new_index"),
827  R"(
828  Move a pin group to another index within the module.
829  The indices of some other pin groups will be incremented or decremented to make room for the moved pin group to be inserted at the desired position.
830 
831  :param hal_py.ModulePinGroup pin_group: The pin group to be moved.
832  :param int new_index: The index to which the pin group is moved.
833  :returns: ``True`` on success, ``False`` otherwise.
834  :rtype: bool
835  )");
836 
837  py_module.def(
838  "assign_pin_to_group",
839  [](Module& self, PinGroup<ModulePin>* pin_group, ModulePin* pin, bool delete_empty_groups = true) {
840  if (self.assign_pin_to_group(pin_group, pin, delete_empty_groups))
841  {
842  return true;
843  }
844  else
845  {
846  log_error("python_context", "error encountered while assigning pin to pin group.");
847  return false;
848  }
849  },
850  py::arg("pin_group"),
851  py::arg("pin"),
852  py::arg("delete_empty_groups") = true,
853  R"(
854  Assign a pin to a pin group.
855 
856  :param hal_py.ModulePinGroup pin_group: The new pin group.
857  :param hal_py.ModulePin pin: The pin to be added.
858  :param bool delete_empty_groups: Set ``True`` to delete groups that are empty after the pin has been assigned to the new group, ``False`` to keep empty groups. Defaults to ``True``.
859  :returns: ``True`` on success, ``False`` otherwise.
860  :rtype: bool
861  )");
862 
863  py_module.def(
864  "move_pin_within_group",
865  [](Module& self, PinGroup<ModulePin>* pin_group, ModulePin* pin, u32 new_index) {
866  if (self.move_pin_within_group(pin_group, pin, new_index))
867  {
868  return true;
869  }
870  else
871  {
872  log_error("python_context", "error encountered while moving pin within pin group.");
873  return false;
874  }
875  },
876  py::arg("pin_group"),
877  py::arg("pin"),
878  py::arg("new_index"),
879  R"(
880  Move a pin to another index within the given pin group.
881  The indices of some other pins within the group will be incremented or decremented to make room for the moved pin to be inserted at the desired position.
882 
883  :param hal_py.ModulePinGroup pin_group: The pin group.
884  :param hal_py.ModulePin pin: The pin to be moved.
885  :param int new_index: The index to which the pin is moved.
886  :returns: ``True`` on success, ``False`` otherwise.
887  :rtype: bool
888  )");
889 
890  py_module.def(
891  "remove_pin_from_group",
892  [](Module& self, PinGroup<ModulePin>* pin_group, ModulePin* pin, bool delete_empty_groups = true) {
893  if (self.remove_pin_from_group(pin_group, pin, delete_empty_groups))
894  {
895  return true;
896  }
897  else
898  {
899  log_error("python_context", "error encountered while removing pin from pin group.");
900  return false;
901  }
902  },
903  py::arg("pin_group"),
904  py::arg("pin"),
905  py::arg("delete_empty_groups") = true,
906  R"(
907  Remove a pin from a pin group.
908  The pin will be moved to a new group that goes by the pin's name.
909 
910  :param hal_py.ModulePinGroup pin_group: The old pin group.
911  :param hal_py.ModulePin pin: The pin to be removed.
912  :param bool delete_empty_groups: Set ``True`` to delete the group of it is empty after the pin has been removed, ``False`` to keep the empty group. Defaults to ``True``.
913  :returns: ``True`` on success, ``False`` otherwise.
914  :rtype: bool
915  )");
916  }
917 } // namespace hal
Definition: gate.h:58
bool is_input_net(Net *net) const
Definition: module.cpp:557
void set_name(const std::string &name)
Definition: module.cpp:92
const std::unordered_set< Net * > & get_nets() const
Definition: module.cpp:505
void update_nets()
Definition: module.cpp:436
std::vector< std::string > get_pin_names(const std::function< bool(ModulePin *)> &filter=nullptr) const
Definition: module.cpp:901
PinGroup< ModulePin > * get_pin_group_by_name(const std::string &name) const
Definition: module.cpp:1053
Module * get_parent_module() const
Definition: module.cpp:125
bool is_parent_module_of(const Module *module, bool recursive=false) const
Definition: module.cpp:240
std::vector< ModulePin * > get_output_pins() const
Definition: module.cpp:948
bool set_parent_module(Module *new_parent)
Definition: module.cpp:170
bool remove_gate(Gate *gate)
Definition: module.cpp:334
std::vector< ModulePin * > get_pins(const std::function< bool(ModulePin *)> &filter=nullptr) const
Definition: module.cpp:873
std::vector< ModulePin * > get_input_pins() const
Definition: module.cpp:932
bool assign_gates(const std::vector< Gate * > &gates)
Definition: module.cpp:329
bool contains_net(Net *net, bool recursive=false) const
Definition: module.cpp:485
Gate * get_gate_by_id(const u32 id, bool recursive=false) const
Definition: module.cpp:372
const std::unordered_set< Net * > & get_internal_nets() const
Definition: module.cpp:552
ModulePin * get_pin_by_name(const std::string &name) const
Definition: module.cpp:1002
int get_submodule_depth() const
Definition: module.cpp:159
bool is_top_module() const
Definition: module.cpp:314
bool remove_gates(const std::vector< Gate * > &gates)
Definition: module.cpp:339
ModulePin * get_pin_by_id(const u32 id) const
Definition: module.cpp:985
bool set_pin_group_type(PinGroup< ModulePin > *pin_group, PinType new_type)
Definition: module.cpp:1203
bool set_pin_type(ModulePin *pin, PinType new_type)
Definition: module.cpp:1124
bool assign_gate(Gate *gate)
Definition: module.cpp:324
bool is_output_net(Net *net) const
Definition: module.cpp:567
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:393
bool set_pin_name(ModulePin *pin, const std::string &new_name, bool force_name=false)
Definition: module.cpp:1070
std::string get_name() const
Definition: module.cpp:87
Grouping * get_grouping() const
Definition: module.cpp:120
const std::unordered_set< Net * > & get_input_nets() const
Definition: module.cpp:542
std::vector< std::string > get_input_pin_names() const
Definition: module.cpp:940
bool set_pin_group_direction(PinGroup< ModulePin > *pin_group, PinDirection new_direction)
Definition: module.cpp:1226
void set_type(const std::string &type)
Definition: module.cpp:111
u32 get_unique_pin_id()
Definition: module.cpp:763
bool contains_module(const Module *other, bool recursive=false) const
Definition: module.cpp:309
std::vector< Module * > get_parent_modules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=true) const
Definition: module.cpp:130
Netlist * get_netlist() const
Definition: module.cpp:319
ModulePin * get_pin_by_net(Net *net) const
Definition: module.cpp:1019
bool set_pin_group_name(PinGroup< ModulePin > *pin_group, const std::string &new_name, bool force_name=false)
Definition: module.cpp:1147
std::vector< PinGroup< ModulePin > * > get_pin_groups(const std::function< bool(PinGroup< ModulePin > *)> &filter=nullptr) const
Definition: module.cpp:964
PinGroup< ModulePin > * get_pin_group_by_id(const u32 id) const
Definition: module.cpp:1036
ssize_t get_hash() const
Definition: module.cpp:77
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
Definition: module.cpp:261
std::vector< std::string > get_output_pin_names() const
Definition: module.cpp:956
bool contains_gate(Gate *gate, bool recursive=false) const
Definition: module.cpp:352
std::string get_type() const
Definition: module.cpp:106
bool is_internal_net(Net *net) const
Definition: module.cpp:577
bool is_submodule_of(const Module *module, bool recursive=false) const
Definition: module.cpp:291
const std::unordered_set< Net * > & get_output_nets() const
Definition: module.cpp:547
u32 get_id() const
Definition: module.cpp:82
u32 get_unique_pin_group_id()
Definition: module.cpp:776
Definition: net.h:58
uint32_t u32
Definition: defines.h:41
std::unique_ptr< T, py::nodelete > RawPtrWrapper
void module_init(py::module &m)
Definition: module.cpp:5
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Definition: defines.h:45
PinDirection
Definition: pin_direction.h:36
PinType
Definition: pin_type.h:36
PinType type
std::vector< PinInformation > pins
Net * net
u32 start_index
bool ascending
PinDirection direction
std::string name