3 #include "pybind11/operators.h"
4 #include "pybind11/pybind11.h"
5 #include "pybind11/stl.h"
6 #include "pybind11/stl_bind.h"
18 #ifdef PYBIND11_MODULE
19 PYBIND11_MODULE(xilinx_toolbox, m)
21 m.doc() =
"A collection of functions specifically designed to operate on Xilinx FPGA netlists.";
25 py::module m(
"xilinx_toolbox",
"A collection of functions specifically designed to operate on Xilinx FPGA netlists.");
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.)");
32 The name of the plugin.
38 Get the name of the plugin.
40 :returns: The name of the plugin.
45 The version of the plugin.
51 Get the version of the plugin.
53 :returns: The version of the plugin.
58 The description of the plugin.
64 Get the description of the plugin.
66 :returns: The description of the plugin.
71 A set of plugin names that this plugin depends on.
77 Get a set of plugin names that this plugin depends on.
79 :returns: A set of plugin names that this plugin depends on.
85 [](
Gate* g,
bool create_module) ->
bool {
91 log_error(
"python_context",
"{}", res.get_error().get());
95 py::arg(
"create_module") =
false,
97 Split a single ``LUT6_2`` gate into up to two separate LUT gates.
99 Creates replacement gates depending on which outputs are connected:
101 - ``O6`` → ``LUT6`` using all 64 bits of the INIT string and all 6 inputs.
102 - ``O5`` → ``LUT5`` using bits [0, 31] of the INIT string and inputs I0-I4 (I5 is excluded).
104 The original ``LUT6_2`` gate is always deleted. The original INIT string is stored on each replacement gate under ``xilinx_preprocessing_information/original_init``.
106 :param hal_py.Gate g: The ``LUT6_2`` gate to split.
107 :param bool create_module: If ``True``, a new module named after the original gate is created as a child of its parent module and all replacement gates are placed into it. If ``False`` (default), replacement gates inherit the parent module of the original gate.
108 :returns: ``True`` on success, ``False`` otherwise.
114 [](
const std::vector<Gate*>& gates,
bool create_module) ->
u32 {
118 py::arg(
"create_module") =
false,
120 Split a list of ``LUT6_2`` gates into separate LUT gates.
122 Calls :func:`split_lut` for each gate in ``gates``. Gates that cannot be split are skipped
123 with a warning; processing always continues with the remaining gates.
125 :param list[hal_py.Gate] gates: The ``LUT6_2`` gates to split.
126 :param bool create_module: If ``True``, each split gate's replacements are placed into a new module named after the original gate. If ``False`` (default), replacements inherit the parent module of the original gate.
127 :returns: The number of successfully split gates.
133 [](
Netlist* nl,
const std::vector<Gate*>& gates,
bool create_module) -> std::optional<u32> {
139 log_error(
"python_context",
"{}", res.get_error().get());
143 py::arg(
"gates") = std::vector<Gate*>(),
144 py::arg(
"create_module") =
false,
146 Split the ``LUT6_2`` gates of the netlist, or of the given gates, into separate LUT gates.
148 Finds all gates of type ``LUT6_2`` within ``gates`` (or within the netlist if ``gates`` is empty) and calls :func:`split_luts` on them.
150 :param hal_py.Netlist nl: The netlist to operate on.
151 :param list[hal_py.Gate] gates: The gates to consider. Defaults to an empty list, in which case all gates of the netlist are considered.
152 :param bool create_module: If ``True``, each split gate's replacements are placed into a new module named after the original gate. If ``False`` (default), replacements inherit the parent module of the original gate.
153 :returns: The number of successfully split ``LUT6_2`` gates on success, ``None`` otherwise.
158 "split_shift_register",
159 [](
Gate* g,
bool create_module) ->
bool {
163 log_error(
"python_context",
"{}", res.get_error().get());
167 py::arg(
"create_module") =
false,
169 Split a single shift register primitive into an equivalent chain of ``FDCE`` flip-flops.
171 Supported gate types: ``SRL16``, ``SRL16E``, ``SRLC16E``, ``SRLC32E``.
173 Every address pin must be connected and driven by a constant (GND/VCC) net; an error is
174 returned otherwise. The number of flip-flops created equals ``select_value + 1``, where
175 ``select_value`` is the binary value encoded by the address pins (A0 = bit 0). When the
176 cascade output (``Q15`` for ``SRLC16E``, ``Q31`` for ``SRLC32E``) has downstream consumers,
177 all stages up to the maximum depth (15 or 31) are materialised so that the last flip-flop
178 correctly drives the cascade net.
180 The original gate is always deleted on success.
182 :param hal_py.Gate g: The shift register gate to split.
183 :param bool create_module: If ``True``, a new module named after the original gate is created as a child of its parent module and all replacement flip-flops are placed into it. If ``False`` (default), replacement flip-flops inherit the parent module of the original gate.
184 :returns: ``True`` on success, ``False`` if ``g`` is not a supported type, if any address
185 pin is unconnected or not driven by a constant net, or if the gate cannot be deleted.
190 "split_shift_registers",
191 [](
const std::vector<Gate*>& gates,
bool create_module) -> std::optional<u32> {
195 log_error(
"python_context",
"{}", res.get_error().get());
199 py::arg(
"create_module") =
false,
201 Split a list of shift register primitives into equivalent ``FDCE`` flip-flop chains.
203 Supported gate types: ``SRL16``, ``SRL16E``, ``SRLC16E``, ``SRLC32E``.
205 Calls :func:`split_shift_register` for each gate in ``gates``. Gates that cannot be split
206 (e.g. because an address pin is not driven by a constant net) are skipped with a warning;
207 processing always continues with the remaining gates.
209 :param list[hal_py.Gate] gates: The shift register gates to split.
210 :param bool create_module: If ``True``, each split gate's replacements are placed into a new module named after the original gate. If ``False`` (default), replacements inherit the parent module of the original gate.
211 :returns: The number of successfully split gates.
216 "split_shift_registers",
217 [](
Netlist* nl,
const std::vector<Gate*>& gates,
bool create_module) -> std::optional<u32> {
221 log_error(
"python_context",
"{}", res.get_error().get());
225 py::arg(
"gates") = std::vector<Gate*>(),
226 py::arg(
"create_module") =
false,
228 Split the shift register primitives of the netlist, or of the given gates, into equivalent ``FDCE`` flip-flop chains.
230 Supported gate types: ``SRL16``, ``SRL16E``, ``SRLC16E``, ``SRLC32E``.
232 Finds all gates of one of the supported types within ``gates`` (or within the netlist if ``gates`` is empty)
233 and calls :func:`split_shift_registers` on them.
235 :param hal_py.Netlist nl: The netlist to operate on.
236 :param list[hal_py.Gate] gates: The gates to consider. Defaults to an empty list, in which case all gates of the netlist are considered.
237 :param bool create_module: If ``True``, each split gate's replacements are placed into a new module named after the original gate. If ``False`` (default), replacements inherit the parent module of the original gate.
238 :returns: The number of successfully split shift register gates.
243 "remove_no_load_wires",
244 [](
Netlist* nl,
const std::vector<Net*>& nets) -> std::optional<u32> {
252 log_error(
"python_context",
"{}", res.get_error().get());
257 py::arg(
"nets") = std::vector<Net*>(),
259 Remove the "no load wire" nets that Vivado writes for unused output pins.
260 Vivado names such nets ``NLW_<instance>_<pin>_UNCONNECTED`` and only connects them to the output pin they stand in for.
261 A net is removed if its name starts with ``NLW_`` (or has ``NLW_`` right after a ``/`` in a flattened path) and ends with ``_UNCONNECTED``, optionally followed by a bit index such as ``(2)`` or ``[2]``, it has no destinations, and it is not a global output.
262 The output pins that drove the removed nets are left unconnected.
264 :param hal_py.Netlist nl: The netlist to operate on.
265 :param list[hal_py.Net] nets: The nets to consider. Defaults to an empty list, in which case all nets of the netlist are considered.
266 :returns: The number of removed nets on success, ``None`` otherwise.
272 [](
Netlist* nl,
const std::filesystem::path& xdc_file) ->
bool {
280 log_error(
"python_context",
"{}", res.get_error().get());
287 Parse an ``.xdc`` file and extract the position LOC and BEL data of each gate.
288 Translates the coordinates extracted from the ``.xdc`` file into integer values.
290 :param hal_py.Netlist nl: The netlist to operate on.
291 :param path xdc_file: The path to the ``.xdc`` file.
292 :returns: ``True`` on success, ``False`` otherwise.
296 #ifndef PYBIND11_MODULE
#define log_error(channel,...)
const Module * module(const Gate *g, const NodeBoxes &boxes)
This file contains functions specifically designed to preprocess Xilinx FPGA netlists.