HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
plugin_module_identification.cpp
Go to the documentation of this file.
2 
3 #include "hal_core/defines.h"
9 
10 #include <algorithm>
11 #include <fstream>
12 #include <iostream>
13 
14 namespace hal
15 {
17  {
19  }
20 
21  extern std::unique_ptr<BasePluginInterface> create_plugin_instance()
22  {
23  return std::make_unique<ModuleIdentificationPlugin>();
24  }
25 
27  {
28  return std::string("module_identification");
29  }
30 
32  {
33  return std::string("0.1");
34  }
35 
37  {
38  return std::string("Plugin for module classification against a library of predefined types.");
39  }
40 
41  std::set<std::string> ModuleIdentificationPlugin::get_dependencies() const
42  {
43  std::set<std::string> retval;
44  retval.insert("boolean_influence");
45  retval.insert("z3_utils");
46  return retval;
47  }
48 
52  void GuiExtensionModuleIdentification::set_parameter(const std::vector<PluginParameter>& params)
53  {
54  for (const PluginParameter& par : params)
55  {
56  if (par.get_tagname() == "general_config/max_thread_count")
57  {
58  m_max_thread_count = atoi(par.get_value().c_str());
59  }
60  else if (par.get_tagname() == "general_config/max_control_signals")
61  {
62  m_max_control_signals = atoi(par.get_value().c_str());
63  }
64  else if (par.get_tagname() == "general_config/check_selector")
65  {
66  if (par.get_value() == "whole netlist")
67  {
68  m_check_selector = 0;
69  }
70  else if (par.get_value() == "selected gates")
71  {
72  m_check_selector = 1;
73  }
74  else if (par.get_value() == "selected modules")
75  {
76  m_check_selector = 2;
77  }
78  else
79  {
80  log_error("module_identification", "check selector returned not valid result");
81  }
82  }
83  else if (par.get_tagname() == "general_config/multi_selector")
84  {
85  if (par.get_value() == "time_priority")
86  {
88  }
89  else if (par.get_value() == "memory_priority")
90  {
92  }
93  else
94  {
95  log_error("module_identification", "check selector returned not valid result");
96  }
97  }
98  else if (par.get_tagname() == "exec")
99  {
100  m_button_clicked = (par.get_value() == "clicked");
101  }
102  else
103  {
105  {
106  if (par.get_tagname() == ("to_check_types/" + enum_to_string(cur_type)))
107  {
108  if (par.get_value() == "true")
109  {
110  if (std::find(m_types_to_check.begin(), m_types_to_check.end(), cur_type) == m_types_to_check.end())
111  {
112  m_types_to_check.push_back(cur_type);
113  }
114  }
115  else
116  {
117  auto type_it = std::find(m_types_to_check.begin(), m_types_to_check.end(), cur_type);
118  if (type_it != m_types_to_check.end())
119  {
120  m_types_to_check.erase(type_it);
121  }
122  }
123  }
124  }
125  }
126  }
127  }
128 
129  std::vector<PluginParameter> GuiExtensionModuleIdentification::get_parameter() const
130  {
131  std::vector<PluginParameter> retval;
132 
133  retval.push_back(PluginParameter(PluginParameter::TabName, "general_config", "Select your options for the module identification run", "1"));
134  retval.push_back(PluginParameter(PluginParameter::Integer, "general_config/max_thread_count", "Maximum Number of threads utilized (default: 1)", "1"));
135  retval.push_back(PluginParameter(PluginParameter::Boolean, "general_config/m_do_multithreading", "Determines whether multithreading should be done at all (default: off)", "false"));
136  retval.push_back(PluginParameter(PluginParameter::Integer, "general_config/max_control_signals", "Maximum number of control signals that will be checked for (default: 3)", "3"));
137 
138  retval.push_back(PluginParameter(PluginParameter::ComboBox, "general_config/check_selector", "Select what the run should be executed on", "whole netlist;selected gates;selected modules"));
139 
140  retval.push_back(PluginParameter(PluginParameter::ComboBox, "general_config/multi_selector", "Select how multithreading should be handled", "none;time_priority;memory_priority"));
141 
142  //second page
143  retval.push_back(PluginParameter(PluginParameter::TabName, "to_check_types", "Select Module Types that shall be checked for", "1"));
145  {
146  std::string type_name = enum_to_string(cur_type);
147  std::transform(type_name.begin(), type_name.end(), type_name.begin(), [](unsigned char c) { return std::tolower(c); });
148  retval.push_back(
149  PluginParameter(PluginParameter::Boolean, "to_check_types/" + enum_to_string(cur_type), "Check wether the selected gates belong to the " + type_name + " type (default: on)", "true"));
150  }
151  retval.push_back(PluginParameter(PluginParameter::PushButton, "exec", "Execute module identification analysis"));
152  return retval;
153  }
154 
155  void GuiExtensionModuleIdentification::execute_function(std::string tag, Netlist* nl, const std::vector<u32>& module_ids, const std::vector<u32>& gate_ids, const std::vector<u32>&)
156  {
157  std::vector<module_identification::CandidateType> types_to_check = module_identification::all_checkable_candidate_types;
158  if (tag == "Module Identification")
159  {
160  m_max_thread_count = 1;
161  m_max_control_signals = 4;
162  m_check_selector = 1;
163  m_do_multithreading = false;
164  }
165  else if (tag == "exec_nl")
166  {
167  m_max_thread_count = 1;
168  m_max_control_signals = 4;
169  m_check_selector = 0;
170  m_do_multithreading = false;
171  }
172  else if (tag == "exec_module")
173  {
174  m_max_thread_count = 1;
175  m_max_control_signals = 4;
176  m_check_selector = 2;
177  m_do_multithreading = false;
178  }
179  else
180  {
181  if (!m_button_clicked)
182  {
183  return;
184  }
185 
186  types_to_check = m_types_to_check;
187  }
188 
189  if (!nl)
190  {
191  log_warning("module_identification", "Error setting paramater: no netlist loaded.");
192  return;
193  }
194 
196  {
197  GuiExtensionModuleIdentification::s_progress_indicator_function(0, "module identification running ...");
198  }
199 
201 
202  auto config = module_identification::Configuration(nl)
203  .with_max_thread_count(m_max_thread_count)
204  .with_max_control_signals(m_max_control_signals)
206  .with_types_to_check(types_to_check);
207  // .with_progress_printer(GuiExtensionModuleIdentification::s_progress_indicator_function);
208 
209  if (m_check_selector == 0)
210  {
211  auto execution_res = module_identification::execute(config);
212  if (execution_res.is_error())
213  {
214  log_error("module_identification", "{}", execution_res.get_error().get());
215  return;
216  }
217 
218  const auto& creation_res = execution_res.get().create_modules_in_netlist();
219  if (creation_res.is_error())
220  {
221  log_error("module_identification", "{}", creation_res.get_error().get());
222  }
223  }
224  else if (m_check_selector == 1)
225  {
226  std::vector<Gate*> gates;
227  for (u32 gate_id : gate_ids)
228  {
229  gates.push_back(nl->get_gate_by_id(gate_id));
230  }
231  auto execution_res = module_identification::execute_on_gates(gates, config);
232  if (execution_res.is_error())
233  {
234  log_error("module_identification", "{}", execution_res.get_error().get());
235  return;
236  }
237 
238  const auto& creation_res = execution_res.get().create_modules_in_netlist();
239  if (creation_res.is_error())
240  {
241  log_error("module_identification", "{}", creation_res.get_error().get());
242  }
243  }
244  else
245  {
246  for (u32 module_id : module_ids)
247  {
248  auto cur_module = nl->get_module_by_id(module_id);
249  const std::vector<Gate*> gates = cur_module->get_gates();
250  auto execution_res = module_identification::execute_on_gates(gates, config);
251  if (execution_res.is_error())
252  {
253  log_error("module_identification", "{}", execution_res.get_error().get());
254  return;
255  }
256 
257  const auto& creation_res = execution_res.get().create_modules_in_netlist();
258  if (creation_res.is_error())
259  {
260  log_error("module_identification", "{}", creation_res.get_error().get());
261  }
262  }
263  }
264 
265  // if (GuiExtensionModuleIdentification::s_progress_indicator_function)
266  // {
267  // GuiExtensionModuleIdentification::s_progress_indicator_function(100, "module identification finished");
268  // }
269  }
270 
271  std::function<void(int, const std::string&)> GuiExtensionModuleIdentification::s_progress_indicator_function = nullptr;
272 
273  void GuiExtensionModuleIdentification::register_progress_indicator(std::function<void(int, const std::string&)> pif)
274  {
276  }
277 
278  std::vector<ContextMenuContribution> GuiExtensionModuleIdentification::get_context_contribution(const Netlist*, const std::vector<u32>&, const std::vector<u32>&, const std::vector<u32>&)
279  {
280  std::vector<ContextMenuContribution> retval;
281  auto context = ContextMenuContribution();
282  context.mContributer = this;
283  context.mTagname = "Module Identification";
284  context.mEntry = "Run module identification on selected gates";
285  retval.push_back(context);
286  auto context2 = ContextMenuContribution();
287  context2.mContributer = this;
288  context2.mTagname = "exec_module";
289  context2.mEntry = "Run module identification on selected modules";
290  retval.push_back(context2);
291  auto context3 = ContextMenuContribution();
292  context3.mContributer = this;
293  context3.mTagname = "exec_nl";
294  context3.mEntry = "Run module identification on netlist";
295  retval.push_back(context3);
296  return retval;
297  }
298 
299 } // namespace hal
std::vector< AbstractExtensionInterface * > m_extensions
GUI extension interface for the module identification plugin.
virtual void register_progress_indicator(std::function< void(int, const std::string &)> pif) override
Register function to indicate work progress when busy.
std::vector< ContextMenuContribution > get_context_contribution(const Netlist *nl, const std::vector< u32 > &mods, const std::vector< u32 > &gats, const std::vector< u32 > &nets)
Get context menu contributions based on the current netlist and selection.
void set_parameter(const std::vector< PluginParameter > &params) override
Set configurable parameters to values.
static std::function< void(int, const std::string &)> s_progress_indicator_function
Static progress indicator function.
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 a function with a specific tag on a netlist.
std::vector< PluginParameter > get_parameter() const override
Get list of configurable parameters.
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:393
std::set< std::string > get_dependencies() const override
Get the plugin dependencies.
ModuleIdentificationPlugin()
Constructor for ModuleIdentificationPlugin.
std::string get_description() const override
Get a short description of the plugin.
std::string get_name() const override
Get the name of the plugin.
std::string get_version() const override
Get the version of the plugin.
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:613
uint32_t u32
Definition: defines.h:41
#define log_error(channel,...)
Definition: log.h:78
#define log_warning(channel,...)
Definition: log.h:76
This file contains the struct Configuration for module identification analysis.
This file contains the function declarations for the Module Identification plugin in hal.
const std::vector< CandidateType > all_checkable_candidate_types
A list of all candidate types that are selectable to be checked.
hal::Result< Result > execute(const Configuration &config)
Perform a full run of the module identification process on the given netlist with the provided config...
hal::Result< Result > execute_on_gates(const std::vector< Gate * > &gates, const Configuration &config)
Perform a module identification run on the specified gates with the provided configuration.
CandidateType
Enumeration of the different candidate types for module identification.
@ time_priority
Prioritize time efficiency in multithreading.
@ memory_priority
Prioritize memory efficiency in multithreading.
Definition: defines.h:45
std::unique_ptr< BasePluginInterface > create_plugin_instance()
std::string enum_to_string(T e)
Definition: enums.h:53
This file contains the structures and functions related to module identification results.
Configuration for the module identification analysis.
Definition: configuration.h:55
Configuration & with_multithreading_priority(const MultithreadingPriority &priority)
Set the multithreading priority type.
Configuration & with_types_to_check(const std::vector< module_identification::CandidateType > &types_to_check)
Set the candidate types to be checked.
Configuration & with_max_control_signals(const u32 &max_control_signals)
Set the maximum number of control signals to be tested.
Configuration & with_max_thread_count(const u32 &max_thread_count)
Set the maximum number of threads.