9 #include <unordered_set>
20 return std::make_unique<XilinxToolboxPlugin>();
25 return std::string(
"xilinx_toolbox");
30 return std::string(
"0.1");
35 return "A collection of functions specifically designed to operate on Xilinx FPGA netlists.";
47 {
PluginParameter::Boolean,
"split_shift_registers",
"Split all shift register gates", mSplitShiftRegisters ?
"true" :
"false"},
54 for (
const auto& p : params)
56 if (p.get_tagname() ==
"split_luts")
58 mSplitLuts = (p.get_value() ==
"true");
60 else if (p.get_tagname() ==
"split_shift_registers")
62 mSplitShiftRegisters = (p.get_value() ==
"true");
73 std::vector<Gate*> gates_from_selection(
Netlist* nl,
const std::vector<u32>& mods,
const std::vector<u32>& gats)
75 std::vector<Gate*> res;
76 std::unordered_set<Gate*> seen;
78 const auto collect = [&res, &seen](
Gate* g) {
79 if (g !=
nullptr && seen.insert(g).second)
94 for (Gate* g : m->get_gates(
nullptr,
true))
107 std::vector<ContextMenuContribution> retval;
109 const auto add = [
this, &retval](
const std::string& tag,
const std::string& entry) {
114 retval.push_back(cmc);
118 if (!mods.empty() || !gats.empty())
120 add(
"split_luts_selection",
"Split LUTs of selection");
121 add(
"split_shift_registers_selection",
"Split shift registers of selection");
123 else if (!nets.empty())
125 add(
"remove_no_load_wires_selection",
"Remove no load wires of selection");
129 add(
"split_luts_netlist",
"Split LUTs of netlist");
130 add(
"split_shift_registers_netlist",
"Split shift registers of netlist");
131 add(
"remove_no_load_wires_netlist",
"Remove no load wires of netlist");
141 log_warning(
"xilinx_toolbox",
"cannot run preprocessing: no netlist loaded.");
150 std::vector<Gate*> scope;
151 if (tag ==
"split_luts_selection" || tag ==
"split_shift_registers_selection")
153 scope = gates_from_selection(nl, mods, gats);
156 log_warning(
"xilinx_toolbox",
"cannot run preprocessing on the selection: no gates selected.");
161 if (tag ==
"execute")
168 log_error(
"xilinx_toolbox",
"failed to split LUTs: {}", res.get_error().get());
171 if (mSplitShiftRegisters)
175 log_error(
"xilinx_toolbox",
"failed to split shift registers: {}", res.get_error().get());
179 else if (tag ==
"split_luts_selection" || tag ==
"split_luts_netlist")
183 log_error(
"xilinx_toolbox",
"failed to split LUTs: {}", res.get_error().get());
187 log_info(
"xilinx_toolbox",
"split {} LUTs.", res.get());
190 else if (tag ==
"split_shift_registers_selection" || tag ==
"split_shift_registers_netlist")
194 log_error(
"xilinx_toolbox",
"failed to split shift registers: {}", res.get_error().get());
198 log_info(
"xilinx_toolbox",
"split {} shift registers.", res.get());
201 else if (tag ==
"remove_no_load_wires_selection" || tag ==
"remove_no_load_wires_netlist")
203 std::vector<Net*> net_scope;
204 if (tag ==
"remove_no_load_wires_selection")
210 net_scope.push_back(n);
213 if (net_scope.empty())
215 log_warning(
"xilinx_toolbox",
"cannot remove no load wires of the selection: no nets selected.");
222 log_error(
"xilinx_toolbox",
"failed to remove no load wires: {}", res.get_error().get());
226 log_info(
"xilinx_toolbox",
"removed {} no load wires.", res.get());
231 log_warning(
"xilinx_toolbox",
"unknown context menu tag '{}'.", tag);
std::vector< AbstractExtensionInterface * > m_extensions
Gate * get_gate_by_id(const u32 gate_id) const
Module * get_module_by_id(u32 module_id) const
Net * get_net_by_id(u32 net_id) const
#define log_error(channel,...)
#define log_info(channel,...)
#define log_warning(channel,...)
std::unique_ptr< BasePluginInterface > create_plugin_instance()
This file contains functions specifically designed to preprocess Xilinx FPGA netlists.