HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
verified_candidate.cpp
Go to the documentation of this file.
2 
6 #include "hal_core/netlist/net.h"
10 
11 #include <string>
12 namespace hal
13 {
14  namespace module_identification
15  {
16  VerifiedCandidate::VerifiedCandidate(const std::vector<std::vector<Net*>>& operands,
17  const std::vector<Net*>& output_nets,
18  const std::vector<Net*>& control_signals,
19  const std::vector<std::map<Net*, BooleanFunction::Value>>& control_signal_mappings,
20  const std::map<std::map<Net*, BooleanFunction::Value>, BooleanFunction>& word_level_operations,
21  const std::vector<Gate*>& gates,
22  const std::vector<Gate*>& base_gates,
23  const std::map<std::string, std::string>& additional_data,
24  const std::set<CandidateType>& types)
25  : m_operands{operands}, m_output_nets{output_nets}, m_control_signals{control_signals}, m_control_signal_mappings{control_signal_mappings}, m_word_level_operations{word_level_operations},
26  m_gates{gates}, m_base_gates{base_gates}, m_total_input_nets{get_input_nets(gates)}, m_total_output_nets{get_output_nets(gates)}, m_types{types}, m_verified{!types.empty()},
27  m_additional_data{additional_data} {};
28 
30  {
31  m_operands = {};
32  m_control_signals = {};
35  m_output_nets = {};
36  m_gates = {};
37  m_base_gates = {};
38  m_types = {};
39  m_verified = false;
40  m_additional_data = {};
41  };
42 
44  {
45  return m_verified;
46  }
47 
49  {
50  std::string result = "";
51  result += "Verified: " + std::to_string(m_verified) + "\n";
52  result += "Candidate Types: \n";
53  for (const auto& t : m_types)
54  {
55  result += "\t" + enum_to_string(t) + "\n";
56  }
57 
58  result += "GATES [" + std::to_string(m_gates.size()) + "]" + ": \n";
59  for (const auto& g : m_gates)
60  {
61  result += "\t" + g->get_name() + " / " + std::to_string(g->get_id()) + "\n";
62  }
63 
64  for (u32 op_idx = 0; op_idx < m_operands.size(); op_idx++)
65  {
66  const auto& nets = m_operands.at(op_idx);
67  result += "OPERAND " + std::to_string(op_idx) + " [" + std::to_string(nets.size()) + "]" + ": \n";
68  for (const auto& n : nets)
69  {
70  result += "\t" + n->get_name() + " / " + std::to_string(n->get_id()) + "\n";
71  }
72  }
73  result += "OUTPUT: [" + std::to_string(m_output_nets.size()) + "]\n";
74  for (auto n : m_output_nets)
75  {
76  result += "\t" + n->get_name() + " / " + std::to_string(n->get_id()) + "\n";
77  }
78  result += "CONTROL SIGNALS: [" + std::to_string(m_control_signals.size()) + "]\n";
79  result += "\t" + utils::join(", ", m_control_signals, [](const auto& n) { return n->get_name(); }) + "\n";
80  result += "CONTROL MAPPINGS: [" + std::to_string(m_control_signal_mappings.size()) + "]\n";
81  for (const auto& cm : m_control_signal_mappings)
82  {
83  for (const auto& [n, v] : cm)
84  {
85  result += "\t" + n->get_name() + " / " + std::to_string(n->get_id()) + " : " + std::to_string(v) + "\n";
86  }
87  result += "--------------------------------------------------\n";
88  }
89  result += "ADDITIONAL DATA: \n";
90  for (const auto& [key, data] : m_additional_data)
91  {
92  result += "\t" + key + ": " + data + "\n";
93  }
94 
95  return result;
96  }
97 
98  Result<VerifiedCandidate> VerifiedCandidate::merge(const std::vector<VerifiedCandidate>& candidates)
99  {
100  std::set<CandidateType> merged_types;
101 
102  std::vector<Net*> merged_control_signals = candidates.front().m_control_signals;
103  std::vector<std::map<Net*, BooleanFunction::Value>> merged_control_signal_mappings;
104  std::map<std::map<Net*, BooleanFunction::Value>, BooleanFunction> merged_word_level_operations;
105 
106  std::vector<std::vector<Net*>> merged_operands;
107 
108  std::vector<Gate*> merged_gates = candidates.front().m_gates;
109  std::vector<Gate*> merged_base_gates = candidates.front().m_base_gates;
110 
111  // TODO maybe add sanity check that all output nets match
112  std::vector<Net*> merged_output_nets = candidates.front().m_output_nets;
113  // std::vector<Net*> merged_total_input_nets = candidates.front().m_total_input_nets;
114  // std::vector<Net*> merged_total_output_nets = candidates.front().m_total_output_nets;
115 
116  std::map<std::string, std::string> merged_additional_data;
117 
118  // helper variable
119  std::set<Net*> assigned_to_operand;
120 
121  for (const auto& c : candidates)
122  {
123  merged_types.insert(c.m_types.begin(), c.m_types.end());
124 
125  for (const auto& cm : c.m_control_signal_mappings)
126  {
127  if (std::find(merged_control_signal_mappings.begin(), merged_control_signal_mappings.end(), cm) != merged_control_signal_mappings.end())
128  {
129  return ERR("cannot merge verified candidates with overlapping control signal mapping");
130  }
131 
132  merged_control_signal_mappings.push_back(cm);
133  merged_word_level_operations.insert({cm, c.m_word_level_operations.at(cm)});
134  }
135 
136  for (const auto& nets : c.m_operands)
137  {
138  // check whether identical operand
139  if (const auto it = std::find(merged_operands.begin(), merged_operands.end(), nets); it != merged_operands.end())
140  {
141  continue;
142  }
143 
144  bool is_not_intersecting = true;
145  for (const auto& n : nets)
146  {
147  if (n->is_gnd_net() || n->is_vcc_net())
148  {
149  continue;
150  }
151 
152  if (assigned_to_operand.find(n) != assigned_to_operand.end())
153  {
154  log_warning("module_identification", "found intersecting operand at net {} with ID {}", n->get_name(), n->get_id());
155  is_not_intersecting = false;
156  break;
157  }
158  }
159 
160  if (is_not_intersecting)
161  {
162  merged_operands.push_back(nets);
163  for (const auto& n : nets)
164  {
165  if (n->is_gnd_net() || n->is_vcc_net())
166  {
167  continue;
168  }
169  assigned_to_operand.insert(n);
170  }
171  }
172  }
173  }
174 
175  return OK(VerifiedCandidate(merged_operands,
176  merged_output_nets,
177  merged_control_signals,
178  merged_control_signal_mappings,
179  merged_word_level_operations,
180  merged_gates,
181  merged_base_gates,
182  merged_additional_data,
183  merged_types));
184  }
185 
186  std::string VerifiedCandidate::get_name() const
187  {
188  if (m_types.empty())
189  {
190  return "NONE_CARRY_CHAIN";
191  }
192 
193  return utils::join("_", m_types);
194  }
195 
197  {
198  // TODO add the ommission of the UNKNOWN OPERATION, if there is an exhaustive amount of control mappings
199  BooleanFunction res = BooleanFunction::Var("UNKNOWN_OPERATION", m_output_nets.size());
200 
201  for (const auto& [ctrl_mapping, bf] : m_word_level_operations)
202  {
203  if (ctrl_mapping.empty())
204  {
205  if (m_word_level_operations.size() != 1)
206  {
207  log_error("module_identification", "Found a module with {} word level operations but at least one being unconditional!", m_word_level_operations.size());
208  }
209  else
210  {
211  res = bf;
212  }
213  break;
214  }
215 
216  BooleanFunction cond;
217  for (const auto& [net, val] : ctrl_mapping)
218  {
219  auto net_var = BooleanFunctionNetDecorator(*net).get_boolean_variable();
220  auto new_cond = BooleanFunction::Eq(std::move(net_var), BooleanFunction::Const({val}), 1).get();
221 
222  if (cond.is_empty())
223  {
224  cond = new_cond;
225  }
226  else
227  {
228  cond = BooleanFunction::And(std::move(cond), std::move(new_cond), 1).get();
229  }
230  }
231 
232  res = BooleanFunction::Ite(std::move(cond), bf.clone(), res.clone(), res.size()).get();
233  }
234 
235  return res;
236  }
237  } // namespace module_identification
238 } // namespace hal
This file contains the enumeration and constants for the candidate types used in the module identific...
static Result< BooleanFunction > Ite(BooleanFunction &&p0, BooleanFunction &&p1, BooleanFunction &&p2, u16 size)
static Result< BooleanFunction > Eq(BooleanFunction &&p0, BooleanFunction &&p1, u16 size)
static BooleanFunction Var(const std::string &name, u16 size=1)
BooleanFunction clone() const
static BooleanFunction Const(const BooleanFunction::Value &value)
static Result< BooleanFunction > And(BooleanFunction &&p0, BooleanFunction &&p1, u16 size)
bool is_verified() const
Check if the candidate is verified.
std::string get_name() const
Get the name of the candidate that represents the functionality of the candidate.
BooleanFunction get_merged_word_level_operation() const
Get the merged word-level operation for the candidate.
VerifiedCandidate()
Default constructor for an empty/unverified VerifiedCandidate.
std::vector< std::map< Net *, BooleanFunction::Value > > m_control_signal_mappings
std::string get_candidate_info() const
Get the candidate information as a string.
std::map< std::map< Net *, BooleanFunction::Value >, BooleanFunction > m_word_level_operations
static hal::Result< VerifiedCandidate > merge(const std::vector< VerifiedCandidate > &candidates)
Merge multiple verified candidates into a single candidate.
std::vector< std::vector< Net * > > m_operands
uint32_t u32
Definition: defines.h:41
#define log_error(channel,...)
Definition: log.h:78
#define log_warning(channel,...)
Definition: log.h:76
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
std::vector< Net * > get_input_nets(const std::vector< Gate * > &gates)
Get input nets from a list of gates.
Definition: utils.cpp:25
std::vector< Net * > get_output_nets(const std::vector< Gate * > &gates, bool only_external_destinations=true)
Get output nets from a list of gates.
Definition: utils.cpp:61
std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
Definition: utils.h:414
Definition: defines.h:45
std::string enum_to_string(T e)
Definition: enums.h:53
Net * net
This file contains helper functions for module identification in the HAL framework.
The result of a module identification run containing the candidates.
Definition: result.h:55