HAL  v4.5.0-133-g64838ea8d
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
plugin_netlist_preprocessing.cpp
Go to the documentation of this file.
2 
8 
9 #include <unordered_set>
10 
11 namespace hal
12 {
14  {
16  }
17 
18  extern std::unique_ptr<BasePluginInterface> create_plugin_instance()
19  {
20  return std::make_unique<NetlistPreprocessingPlugin>();
21  }
22 
24  {
25  return std::string("netlist_preprocessing");
26  }
27 
29  {
30  return std::string("0.2");
31  }
32 
34  {
35  return "A collection of tools to preprocess a netlist and prepare it for further analysis.";
36  }
37 
38  std::set<std::string> NetlistPreprocessingPlugin::get_dependencies() const
39  {
40  std::set<std::string> retval;
41  retval.insert("resynthesis");
42  retval.insert("z3_utils");
43  return retval;
44  }
45 
46  namespace
47  {
52  std::vector<Gate*> gates_from_selection(Netlist* nl, const std::vector<u32>& mods, const std::vector<u32>& gats)
53  {
54  std::vector<Gate*> res;
55  std::unordered_set<Gate*> seen;
56 
57  const auto collect = [&res, &seen](Gate* g) {
58  if (g != nullptr && seen.insert(g).second)
59  {
60  res.push_back(g);
61  }
62  };
63 
64  for (u32 id : gats)
65  {
66  collect(nl->get_gate_by_id(id));
67  }
68 
69  for (u32 id : mods)
70  {
71  if (const Module* m = nl->get_module_by_id(id); m != nullptr)
72  {
73  for (Gate* g : m->get_gates(nullptr, true))
74  {
75  collect(g);
76  }
77  }
78  }
79 
80  return res;
81  }
82  } // namespace
83 
84  std::vector<ContextMenuContribution> GuiExtensionNetlistPreprocessing::get_context_contribution(const Netlist*, const std::vector<u32>& mods, const std::vector<u32>& gats, const std::vector<u32>&)
85  {
86  std::vector<ContextMenuContribution> retval;
87 
88  const auto add = [this, &retval](const std::string& tag, const std::string& entry) {
90  cmc.mContributer = this;
91  cmc.mTagname = tag;
92  cmc.mEntry = entry;
93  retval.push_back(cmc);
94  };
95 
96  // a selection is what the user is pointing at, so do not offer to run on the entire netlist next to it
97  if (!mods.empty() || !gats.empty())
98  {
99  add("remove_buffers_selection", "Remove buffers from selection");
100  add("unify_ff_outputs_selection", "Unify flip-flop outputs of selection");
101  }
102  else
103  {
104  add("remove_buffers_netlist", "Remove buffers from netlist");
105  add("unify_ff_outputs_netlist", "Unify flip-flop outputs of netlist");
106  }
107 
108  return retval;
109  }
110 
111  void GuiExtensionNetlistPreprocessing::execute_function(std::string tag, Netlist* nl, const std::vector<u32>& mods, const std::vector<u32>& gats, const std::vector<u32>&)
112  {
113  if (nl == nullptr)
114  {
115  log_warning("netlist_preprocessing", "cannot run preprocessing: no netlist loaded.");
116  return;
117  }
118 
119  // deleting or replacing a gate makes the GUI re-layout its graph views, which would otherwise happen once
120  // per gate and dominate the runtime of the preprocessing itself
121  const netlist_preprocessing::GuiLayoutLocker layout_locker;
122 
123  // an empty scope makes the preprocessing functions consider the entire netlist
124  std::vector<Gate*> scope;
125  if (tag == "remove_buffers_selection" || tag == "unify_ff_outputs_selection")
126  {
127  scope = gates_from_selection(nl, mods, gats);
128  if (scope.empty())
129  {
130  log_warning("netlist_preprocessing", "cannot run preprocessing on the selection: no gates selected.");
131  return;
132  }
133  }
134 
135  if (tag == "remove_buffers_selection" || tag == "remove_buffers_netlist")
136  {
137  if (const auto res = netlist_preprocessing::remove_buffers(nl, scope); res.is_error())
138  {
139  log_error("netlist_preprocessing", "failed to remove buffers: {}", res.get_error().get());
140  }
141  }
142  else if (tag == "unify_ff_outputs_selection" || tag == "unify_ff_outputs_netlist")
143  {
144  if (const auto res = netlist_preprocessing::unify_ff_outputs(nl, scope); res.is_error())
145  {
146  log_error("netlist_preprocessing", "failed to unify flip-flop outputs: {}", res.get_error().get());
147  }
148  else
149  {
150  log_info("netlist_preprocessing", "rerouted {} 'neg_state' outputs.", res.get());
151  }
152  }
153  else
154  {
155  log_warning("netlist_preprocessing", "unknown context menu tag '{}'.", tag);
156  }
157  }
158 } // namespace hal
std::vector< AbstractExtensionInterface * > m_extensions
Definition: gate.h:58
GUI extension interface for the netlist preprocessing plugin.
std::vector< ContextMenuContribution > get_context_contribution(const Netlist *nl, const std::vector< u32 > &mods, const std::vector< u32 > &gats, const std::vector< u32 > &nets) override
Get the context menu entries contributed for the given selection.
void execute_function(std::string tag, Netlist *nl, const std::vector< u32 > &mods, const std::vector< u32 > &gats, const std::vector< u32 > &nets) override
Execute the context menu entry identified by the given tag.
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:195
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:615
std::string get_name() const override
Get the name of the plugin.
std::string get_description() const override
Get a short description of the plugin.
std::string get_version() const override
Get the version of the plugin.
std::set< std::string > get_dependencies() const override
Get the plugin dependencies.
NetlistPreprocessingPlugin()
Constructor for NetlistPreprocessingPlugin that registers the GUI extension.
Suppresses layout updates of the GUI for as long as the object exists.
uint32_t u32
Definition: defines.h:41
#define log_error(channel,...)
Definition: log.h:78
#define log_info(channel,...)
Definition: log.h:70
#define log_warning(channel,...)
Definition: log.h:76
Result< u32 > remove_buffers(Netlist *nl, const std::vector< Gate * > &gates={})
Result< u32 > unify_ff_outputs(Netlist *nl, const std::vector< Gate * > &ffs={}, GateType *inverter_type=nullptr)
Definition: defines.h:45
std::unique_ptr< BasePluginInterface > create_plugin_instance()
This file contains a helper that suppresses layout updates of the GUI.
This file contains all functions related to the HAL plugin API.
GuiExtensionInterface * mContributer