7 auto py_netlist_utils = m.def_submodule(
"NetlistUtils", R
"(
8 HAL Netlist Utility functions.
12 "get_subgraph_function",
21 log_error(
"python_context",
"error encountered while getting subgraph function:\n{}", res.get_error().get());
26 py::arg(
"subgraph_gates"),
28 Get the combined Boolean function of a subgraph of combinational gates starting at the source of the given net.
29 The variables of the resulting Boolean function are made up of the IDs of the nets that influence the output ('net_[ID]').
31 :param hal_py.Net net: The output net for which to generate the Boolean function.
32 :param list[hal_py.Gate] subgraph_gates: The gates making up the subgraph.
33 :returns: The combined Boolean function of the subgraph on success, an empty Boolean function otherwise.
34 :rtype: hal_py.BooleanFunction
39 Get a deep copy of an entire netlist including all of its gates, nets, modules, and groupings.
41 :param hal_py.Netlist nl: The netlist to copy.
42 :returns: The deep copy of the netlist.
43 :rtype: hal_py.Netlist
47 Get the FF dependency matrix of a netlist.
49 :param hal_py.Netlist nl: The netlist to extract the dependency matrix from.
50 :returns: A pair consisting of a dict from the original gate IDs to the ones in the matrix, and the FF dependency matrix itself.
51 :rtype: tuple(dict[int,hal_py.Gate], list[list[int]])
54 py_netlist_utils.def("get_next_gates",
57 py::arg(
"get_successors"),
59 py::arg(
"filter") =
nullptr,
61 Find predecessors or successors of a gate. If depth is set to 1 only direct predecessors/successors will be returned.
62 Higher number of depth causes as many steps of recursive calls.
63 If depth is set to 0 there is no limitation and the loop continues until no more predecessors/succesors are found.
64 If a filter function is given, the recursion stops whenever the filter function evaluates to ``False``.
65 Only gates matching the filter will be added to the result vector.
66 The result will not include the provided gate itself.
68 :param hal_py.Gate gate: The initial gate.
69 :param bool get_successors: ``True`` to return successors, ``False`` for Predecessors.
70 :param int depth: Depth of recursion.
71 :param lambda filter: User-defined filter function.
72 :returns: List of predecessor/successor gates.
73 :rtype: list[hal_py.Gate]
76 py_netlist_utils.def("get_next_gates",
79 py::arg(
"get_successors"),
81 py::arg(
"filter") =
nullptr,
83 Find predecessors or successors of a net. If depth is set to 1 only direct predecessors/successors will be returned.
84 Higher number of depth causes as many steps of recursive calls.
85 If depth is set to 0 there is no limitation and the loop continues until no more predecessors/succesors are found.
86 If a filter function is given, the recursion stops whenever the filter function evaluates to ``False``.
87 Only gates matching the filter will be added to the result vector.
89 :param hal_py.Net net: The initial net.
90 :param bool get_successors: ``True`` to return successors, ``False`` for Predecessors.
91 :param int depth: Depth of recursion.
92 :param lambda filter: User-defined filter function.
93 :returns: List of predecessor/successor gates.
94 :rtype: list[hal_py.Gate]
97 py_netlist_utils.def("get_next_sequential_gates",
100 py::arg(
"get_successors"),
103 Find all sequential predecessors or successors of a gate.
104 Traverses combinational logic of all input or output nets until sequential gates are found.
105 The result may include the provided gate itself.
106 The use of the this cached version is recommended in case of extensive usage to improve performance.
107 The cache will be filled by this function and should initially be provided empty.
108 Different caches for different values of get_successors shall be used.
110 :param hal_py.Gate gate: The initial gate.
111 :param bool get_successors: If ``True``, sequential successors are returned, otherwise sequential predecessors are returned.
112 :param dict[int, list[hal_py.Gate]] cache: The cache.
113 :returns: All sequential successors or predecessors of the gate.
114 :rtype: list[hal_py.Gate]
118 Find all sequential predecessors or successors of a gate.
119 Traverses combinational logic of all input or output nets until sequential gates are found.
120 The result may include the provided gate itself.
122 :param hal_py.Gate gate: The initial gate.
123 :param bool get_successors: If ``True``, sequential successors are returned, otherwise sequential predecessors are returned.
124 :returns: All sequential successors or predecessors of the gate.
125 :rtype: list[hal_py.Gate]
128 py_netlist_utils.def("get_next_sequential_gates",
131 py::arg(
"get_successors"),
134 Find all sequential predecessors or successors of a net.
135 Traverses combinational logic of all input or output nets until sequential gates are found.
136 The use of the cache is recommended in case of extensive usage of this function.
137 The cache will be filled by this function and should initially be provided empty.
138 Different caches for different values of get_successors shall be used.
140 :param hal_py.Net net: The initial net.
141 :param bool get_successors: If ``True``, sequential successors are returned, otherwise sequential predecessors are returned.
142 :param dict[int, list[hal_py.Gate]] cache: The cache.
143 :returns: All sequential successors or predecessors of the net.
144 :rtype: list[hal_py.Net]
148 Find all sequential predecessors or successors of a net.
149 Traverses combinational logic of all input or output nets until sequential gates are found.
151 :param hal_py.Net net: The initial net.
152 :param bool get_successors: If ``True``, sequential successors are returned, otherwise sequential predecessors are returned.
153 :returns: All sequential successors or predecessors of the net.
154 :rtype: list[hal_py.Net]
157 py_netlist_utils.def("get_path",
160 py::arg(
"get_successors"),
161 py::arg(
"stop_properties"),
164 Find all gates on the predecessor or successor path of a gate.
165 Traverses all input or output nets until gates of the specified base types are found.
166 The result may include the provided gate itself.
167 The use of the this cached version is recommended in case of extensive usage to improve performance.
168 The cache will be filled by this function and should initially be provided empty.
169 Different caches for different values of get_successors shall be used.
171 :param hal_py.Gate gate: The initial gate.
172 :param bool get_successors: If ``True``, the successor path is returned, otherwise the predecessor path is returned.
173 :param set[hal_py.GateTypeProperty] stop_properties: Stop recursion when reaching a gate of a type with one of the specified properties.
174 :param dict[int, list[hal_py.Gate]] cache: The cache.
175 :returns: All gates on the predecessor or successor path of the gate.
176 :rtype: list[hal_py.Gate]
179 py_netlist_utils.def(
180 "get_path", py::overload_cast<
const Gate*,
bool, std::set<GateTypeProperty>>(&
netlist_utils::get_path), py::arg(
"gate"), py::arg(
"get_successors"), py::arg(
"stop_properties"), R
"(
181 Find all gates on the predeccessor or successor path of a gate.
182 Traverses all input or output nets until gates of the specified base types are found.
183 The result may include the provided gate itself.
185 :param hal_py.Gate gate: The initial gate.
186 :param bool get_successors: If ``True``, the successor path is returned, otherwise the predecessor path is returned.
187 :param set[hal_py.GateTypeProperty] stop_properties: Stop recursion when reaching a gate of a type with one of the specified properties.
188 :returns: All gates on the predecessor or successor path of the gate.
189 :rtype: list[hal_py.Gate]
192 py_netlist_utils.def("get_path",
195 py::arg(
"get_successors"),
196 py::arg(
"stop_properties"),
199 Find all gates on the predecessor or successor path of a net.
200 Traverses all input or output nets until gates of the specified base types are found.
201 The use of the this cached version is recommended in case of extensive usage to improve performance.
202 The cache will be filled by this function and should initially be provided empty.
203 Different caches for different values of get_successors shall be used.
205 :param hal_py.Net net: The initial net.
206 :param bool get_successors: If ``True``, the successor path is returned, otherwise the predecessor path is returned.
207 :param set[hal_py.GateTypeProperty] stop_properties: Stop recursion when reaching a gate of a type with one of the specified properties.
208 :param dict[int, list[hal_py.Gate]] cache: The cache.
209 :returns: All gates on the predecessor or successor path of the net.
210 :rtype: list[hal_py.Net]
212 py_netlist_utils.def(
213 "get_path", py::overload_cast<
const Net*,
bool, std::set<GateTypeProperty>>(&
netlist_utils::get_path), py::arg(
"net"), py::arg(
"get_successors"), py::arg(
"stop_properties"), R
"(
214 Find all gates on the predecessor or successor path of a net.
215 Traverses all input or output nets until gates of the specified base types are found.
217 :param hal_py.Net net: The initial net.
218 :param bool get_successors: If ``True``, the successor path is returned, otherwise the predecessor path is returned.
219 :param set[hal_py.GateTypeProperty] stop_properties: Stop recursion when reaching a gate of a type with one of the specified properties.
220 :returns: All gates on the predecessor or successor path of the net.
221 :rtype: list[hal_py.Net]
225 Get the nets that are connected to a subset of pins of the specified gate.
227 :param hal_py.Gate gate: The gate.
228 :param list[hal_py.GatePin] pins: The targeted pins.
229 :returns: A list of nets connected to the pins.
230 :rtype: list[hal_py.Net]
233 py_netlist_utils.def(
235 [](
Netlist* netlist,
bool analyze_inputs =
false) ->
i32 {
239 return (
i32)res.get();
243 log_error(
"python_context",
"error encountered while removing buffer gates from netlist:\n{}", res.get_error().get());
248 py::arg(
"analyze_inputs") =
false,
250 Remove all buffer gates from the netlist and connect their fan-in to their fan-out nets.
251 If enabled, analyzes every gate's inputs and removes fixed '0' or '1' inputs from the Boolean function.
253 :param hal_py.Netlist netlist: The target netlist.
254 :param bool analyze_inputs: Set ``True`` to dynamically analyze the inputs, ``False`` otherwise.
255 :returns: The number of removed buffers on success, -1 otherwise.
259 py_netlist_utils.def(
260 "remove_unused_lut_endpoints",
265 return (
i32)res.get();
269 log_error(
"python_context",
"error encountered while removing unused LUT endpoints from netlist:\n{}", res.get_error().get());
275 Remove all LUT fan-in endpoints that are not present within the Boolean function of the output of a gate.
277 :param hal_py.Netlist netlist: The target netlist.
278 :returns: The number of removed endpionts on success, -1 otherwise.
283 Returns all nets that are considered to be common inputs to the provided gates.
284 A threshold value can be provided to specify the number of gates a net must be connected to in order to be classified as a common input.
285 If the theshold value is set to 0, a net must be input to all gates to be considered a common input.
287 :param list[hal_py.Gate] gates: The gates.
288 :param int threshold: The threshold value, defaults to 0.
289 :returns: The common input nets.
290 :rtype: list[hal_py.Net]
293 py_netlist_utils.def(
295 [](
Gate* gate,
GateType* target_type, std::map<GatePin*, GatePin*> pin_map) ->
i32 {
303 log_error(
"python_context",
"error encountered while replacing gate:\n{}", res.get_error().get());
308 py::arg(
"target_type"),
311 Replace the given gate with a gate of the specified gate type.
312 A dict from old to new pins must be provided in order to correctly connect the gates inputs and outputs.
313 A pin can be omitted if no connection at that pin is desired.
315 :param hal_py.Gate gate: The gate to be replaced.
316 :param hal_py.GateType target_type: The gate type of the replacement gate.
317 :param dict[hal_py.GatePin,hal_py.GatePin] pin_map: A dict from old to new pins.
318 :returns: ``True`` on success, ``False`` otherwise.
322 py_netlist_utils.def(
324 [](
Gate* start_gate,
const std::vector<const GatePin*>& input_pins = {},
const std::vector<const GatePin*>& output_pins = {},
const std::function<bool(
const Gate*)>& filter =
nullptr)
325 -> std::vector<Gate*> {
333 log_error(
"python_context",
"error encountered while detecting gate chain:\n{}", res.get_error().get());
337 py::arg(
"start_gate"),
338 py::arg(
"input_pins") = std::vector<GatePin*>(),
339 py::arg(
"output_pins") = std::vector<GatePin*>(),
340 py::arg(
"filter") =
nullptr,
342 Find a sequence of identical gates that are connected via the specified input and output pins.
343 The start gate may be any gate within a such a sequence, it is not required to be the first or the last gate.
344 If input and/or output pins are specified, the gates must be connected through one of the input pins and/or one of the output pins.
345 The optional filter is evaluated on every gate such that the result only contains gates matching the specified condition.
347 :param hal_py.Gate start_gate: The gate at which to start the chain detection.
348 :param list[hal_py.GatePin] input_pins: The input pins through which the gates must be connected. Defaults to an empty list.
349 :param set[hal_py.GatePin] output_pins: The output pins through which the gates must be connected. Defaults to an empty list.
350 :param lambda filter: An optional filter function to be evaluated on each gate.
351 :returns: A list of gates that form a chain on success, an empty list on error.
352 :rtype: list[hal_py.Gate]
355 py_netlist_utils.def(
356 "get_complex_gate_chain",
358 const std::vector<GateType*>& chain_types,
359 const std::map<
GateType*, std::vector<const GatePin*>>& input_pins,
360 const std::map<
GateType*, std::vector<const GatePin*>>& output_pins,
361 const std::function<
bool(
const Gate*)>& filter =
nullptr) -> std::vector<Gate*> {
369 log_error(
"python_context",
"error encountered while detecting complex gate chain:\n{}", res.get_error().get());
373 py::arg(
"start_gate"),
374 py::arg(
"chain_types"),
375 py::arg(
"input_pins"),
376 py::arg(
"output_pins"),
377 py::arg(
"filter") =
nullptr,
379 Find a sequence of gates (of the specified sequence of gate types) that are connected via the specified input and output pins.
380 The start gate may be any gate within a such a sequence, it is not required to be the first or the last gate.
381 However, the start gate must be of the first gate type within the repeating sequence.
382 If input and/or output pins are specified for a gate type, the gates must be connected through one of the input pins and/or one of the output pins.
383 The optional filter is evaluated on every gate such that the result only contains gates matching the specified condition.
385 :param hal_py.Gate start_gate: The gate at which to start the chain detection.
386 :param list[hal_py.GateType] chain_types: The sequence of gate types that is expected to make up the gate chain.
387 :param dict[hal_py.GateType,set[str]] input_pins: The input pins (of every gate type of the sequence) through which the gates must be connected.
388 :param dict[hal_py.GateType,set[str]] output_pins: The output pins (of every gate type of the sequence) through which the gates must be connected.
389 :param lambda filter: An optional filter function to be evaluated on each gate.
390 :returns: A list of gates that form a chain on success, an empty list on error.
391 :rtype: list[hal_py.Gate]
394 py_netlist_utils.def("get_shortest_path", py::overload_cast<Gate*,Gate*,bool>(&
netlist_utils::get_shortest_path), py::arg(
"start_gate"), py::arg(
"end_gate"), py::arg(
"search_both_directions") =
false, R
"(
395 Find the shortest path (i.e., the result set with the lowest number of gates) that connects the start gate with the end gate.
396 The gate where the search started from will be the first in the result vector, the end gate will be the last.
397 If there is no such path an empty vector is returned. If there is more than one path with the same length only the first one is returned.
399 :param hal_py.Gate start_gate: The gate to start from.
400 :param hal_py.Gate end_gate: The gate to connect to.
401 :param bool search_both_directions: ``True`` to additionally check whether a shorter path from end to start exists, ``False`` otherwise.
402 :returns: A list of gates that connect the start with end gate (possibly in reverse order).
403 :rtype: list[hal_py.Gate]
406 py_netlist_utils.def("get_shortest_path", py::overload_cast<Gate*,Module*,bool>(&
netlist_utils::get_shortest_path), py::arg(
"start_gate"), py::arg(
"end_module"), py::arg(
"forward_direction"), R
"(
407 Find the shortest path (i.e., the result set with the lowest number of gates) that connects the start gate with any gate from the given module.
408 The gate where the search started from will be the first in the result vector, the end gate will be the last.
409 If there is no such path an empty vector is returned. If there is more than one path with the same length only the first one is returned.
411 :param hal_py.Gate start_gate: The gate to start from.
412 :param hal_py.Module end_module: The module to connect to.
413 :param bool forward_direction: ``True`` to search along the fan-out nets of the start gate, ``False`` to search along its fan-in nets.
414 :returns: A list of gates that connect the start with end gate (possibly in reverse order).
415 :rtype: list[hal_py.Gate]
418 py_netlist_utils.def("get_shortest_path", py::overload_cast<Module*,Module*>(&
netlist_utils::get_shortest_path), py::arg(
"start_module"), py::arg(
"end_module"), R
"(
419 Find the shortest path (i.e., the result set with the lowest number of gates) that connects the start module with the target module.
420 There might be more than one connection thus a list of connecting gate lists is returned.
422 :param hal_py.Module start_module: The module to start from.
423 :param hal_py.Module end_module: The module to connect to.
424 :returns: A list of connecting lists with gates that connect the start with end gate.
425 :rtype: list[list[hal_py.Gate]]
void netlist_utils_init(py::module &m)
#define log_error(channel,...)
const Module * module(const Gate *g, const NodeBoxes &boxes)
Result< u32 > remove_unused_lut_endpoints(Netlist *netlist)
std::vector< Gate * > get_path(const Gate *gate, bool get_successors, std::set< GateTypeProperty > stop_properties, std::unordered_map< u32, std::vector< Gate * >> &cache)
Result< std::vector< Gate * > > get_gate_chain(Gate *start_gate, const std::vector< const GatePin * > &input_pins={}, const std::vector< const GatePin * > &output_pins={}, const std::function< bool(const Gate *)> &filter=nullptr)
std::vector< Gate * > get_next_gates(const Gate *gate, bool get_successors, int depth=0, const std::function< bool(const Gate *)> &filter=nullptr)
Result< BooleanFunction > get_subgraph_function(const Net *net, const std::vector< const Gate * > &subgraph_gates, std::map< std::pair< u32, const GatePin * >, BooleanFunction > &cache)
Result< u32 > remove_buffers(Netlist *netlist, bool analyze_inputs=false)
Result< std::vector< Gate * > > get_complex_gate_chain(Gate *start_gate, const std::vector< GateType * > &chain_types, const std::map< GateType *, std::vector< const GatePin * >> &input_pins, const std::map< GateType *, std::vector< const GatePin * >> &output_pins, const std::function< bool(const Gate *)> &filter=nullptr)
std::unique_ptr< Netlist > copy_netlist(const Netlist *nl)
std::vector< Gate * > get_next_sequential_gates(const Gate *gate, bool get_successors, std::unordered_map< u32, std::vector< Gate * >> &cache)
std::vector< Gate * > get_shortest_path(Gate *start_gate, Gate *end_gate, bool search_both_directions=false)
Result< std::monostate > replace_gate(Gate *gate, GateType *target_type, std::map< GatePin *, GatePin * > pin_map)
std::vector< Net * > get_nets_at_pins(Gate *gate, std::vector< GatePin * > pins)
std::vector< Net * > get_common_inputs(const std::vector< Gate * > &gates, u32 threshold=0)
std::pair< std::map< u32, Gate * >, std::vector< std::vector< int > > > get_ff_dependency_matrix(const Netlist *nl)