HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
net.cpp
Go to the documentation of this file.
1 #include "hal_core/netlist/net.h"
2 
10 
11 #include <assert.h>
12 #include <memory>
13 
14 namespace hal
15 {
16  Net::Net(NetlistInternalManager* internal_manager, EventHandler* event_handler, const u32 id, const std::string& name)
17  {
18  assert(internal_manager != nullptr);
19  m_internal_manager = internal_manager;
20  m_id = id;
21  m_name = name;
22 
23  m_event_handler = event_handler;
24  }
25 
26  bool Net::operator==(const Net& other) const
27  {
28  if (m_id != other.get_id() || m_name != other.get_name())
29  {
30  log_debug("net", "the nets with IDs {} and {} are not equal due to an unequal ID or name.", m_id, other.get_id());
31  return false;
32  }
33 
35  {
36  log_debug("net", "the nets with IDs {} and {} are not equal as one is a global input or output net and the other is not.", m_id, other.get_id());
37  return false;
38  }
39 
40  if (m_sources.size() != other.get_num_of_sources() || m_destinations.size() != other.get_num_of_destinations())
41  {
42  log_debug("net", "the nets with IDs {} and {} are not equal due to an unequal number of sources or destinations.", m_id, other.get_id());
43  return false;
44  }
45 
46  const std::vector<Endpoint*>& sources_n2 = other.get_sources();
47  for (const Endpoint* ep_n1 : m_sources_raw)
48  {
49  if (std::find_if(sources_n2.begin(), sources_n2.end(), [ep_n1](const Endpoint* ep_n2) { return *ep_n1->get_pin() == *ep_n2->get_pin() && *ep_n1->get_gate() == *ep_n2->get_gate(); })
50  == sources_n2.end())
51  {
52  log_debug("net", "the nets with IDs {} and {} are not equal due to an unequal source endpoint.", m_id, other.get_id());
53  return false;
54  }
55  }
56 
57  const std::vector<Endpoint*>& destinations_n2 = other.get_destinations();
58  for (const Endpoint* ep_n1 : m_destinations_raw)
59  {
60  if (std::find_if(
61  destinations_n2.begin(), destinations_n2.end(), [ep_n1](const Endpoint* ep_n2) { return *ep_n1->get_pin() == *ep_n2->get_pin() && *ep_n1->get_gate() == *ep_n2->get_gate(); })
62  == destinations_n2.end())
63  {
64  log_debug("net", "the nets with IDs {} and {} are not equal due to an unequal destination endpoint.", m_id, other.get_id());
65  return false;
66  }
67  }
68 
69  if (!DataContainer::operator==(other))
70  {
71  log_debug("net", "the nets with IDs {} and {} are not equal due to unequal data.", m_id, other.get_id());
72  return false;
73  }
74 
75  return true;
76  }
77 
78  bool Net::operator!=(const Net& other) const
79  {
80  return !operator==(other);
81  }
82 
83  ssize_t Net::get_hash() const
84  {
85  return (uintptr_t)this;
86  }
87 
88  u32 Net::get_id() const
89  {
90  return m_id;
91  }
92 
94  {
95  return m_internal_manager->m_netlist;
96  }
97 
98  const std::string& Net::get_name() const
99  {
100  return m_name;
101  }
102 
103  void Net::set_name(const std::string& name)
104  {
105  if (utils::trim(name).empty())
106  {
107  log_error("net", "net name cannot be empty.");
108  return;
109  }
110  if (name != m_name)
111  {
112  m_name = name;
113  m_event_handler->notify(NetEvent::event::name_changed, this);
114  }
115  }
116 
118  {
119  return m_grouping;
120  }
121 
123  {
124  return m_internal_manager->net_add_source(this, gate, pin);
125  }
126 
127  Endpoint* Net::add_source(Gate* gate, const std::string& pin_name)
128  {
129  if (gate == nullptr)
130  {
131  log_warning("net", "could not add source to gate: nullptr given for gate");
132  return nullptr;
133  }
134  if (pin_name.empty())
135  {
136  log_warning("net", "could not add source to gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
137  return nullptr;
138  }
139  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
140  if (pin == nullptr)
141  {
142  log_warning("net", "could not add source to gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
143  return nullptr;
144  }
145  return add_source(gate, pin);
146  }
147 
148  bool Net::remove_source(Gate* gate, const GatePin* pin)
149  {
150  if (gate == nullptr)
151  {
152  log_warning("net", "could not remove source from gate: nullptr given for gate");
153  return false;
154  }
155 
156  if (pin == nullptr)
157  {
158  log_warning("net", "could not remove source from gate '{}' with ID {}: nullptr given for pin", gate->get_name(), gate->get_id());
159  return false;
160  }
161 
162  if (auto it = std::find_if(m_sources_raw.begin(), m_sources_raw.end(), [gate, pin](const auto* ep) { return ep->get_gate() == gate && ep->get_pin() == pin; }); it != m_sources_raw.end())
163  {
164  return m_internal_manager->net_remove_source(this, *it);
165  }
166  return false;
167  }
168 
169  bool Net::remove_source(Gate* gate, const std::string& pin_name)
170  {
171  if (gate == nullptr)
172  {
173  log_warning("net", "could not remove source from gate: nullptr given for gate");
174  return false;
175  }
176  if (pin_name.empty())
177  {
178  log_warning("net", "could not remove source from gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
179  return false;
180  }
181  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
182  if (pin == nullptr)
183  {
184  log_warning("net", "could not remove source from gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
185  return false;
186  }
187  return remove_source(gate, pin);
188  }
189 
191  {
192  if (ep == nullptr)
193  {
194  return false;
195  }
196  return m_internal_manager->net_remove_source(this, ep);
197  }
198 
199  bool Net::is_a_source(const Gate* gate) const
200  {
201  if (gate == nullptr)
202  {
203  log_warning("net", "could not check if gate is a source: nullptr given for gate");
204  return false;
205  }
206 
207  return std::find_if(m_sources_raw.begin(), m_sources_raw.end(), [gate](const auto* ep) { return ep->get_gate() == gate; }) != m_sources_raw.end();
208  }
209 
210  bool Net::is_a_source(const Gate* gate, const GatePin* pin) const
211  {
212  if (gate == nullptr)
213  {
214  log_warning("net", "could not check if gate is a source: nullptr given for gate");
215  return false;
216  }
217 
218  if (pin == nullptr)
219  {
220  log_warning("net", "could not check if gate is a source: nullptr given for pin");
221  return false;
222  }
223 
224  return std::find_if(m_sources_raw.begin(), m_sources_raw.end(), [gate, pin](const auto* ep) { return ep->get_gate() == gate && ep->get_pin() == pin; }) != m_sources_raw.end();
225  }
226 
227  bool Net::is_a_source(const Gate* gate, const std::string& pin_name) const
228  {
229  if (gate == nullptr)
230  {
231  log_warning("net", "could not check if gate is a source: nullptr given for gate");
232  return false;
233  }
234 
235  if (pin_name.empty())
236  {
237  log_warning("net", "could not check if gate '{}' with ID {} is a source: empty string provided as pin name", gate->get_name(), gate->get_id());
238  return false;
239  }
240 
241  return is_a_source(gate, gate->get_type()->get_pin_by_name(pin_name));
242  }
243 
244  bool Net::is_a_source(const Endpoint* ep) const
245  {
246  if (ep == nullptr)
247  {
248  return false;
249  }
250  if (!ep->is_source_pin())
251  {
252  return false;
253  }
254 
255  return std::find(m_sources_raw.begin(), m_sources_raw.end(), ep) != m_sources_raw.end();
256  }
257 
258  u32 Net::get_num_of_sources(const std::function<bool(Endpoint* ep)>& filter) const
259  {
260  if (!filter)
261  {
262  return (u32)m_sources_raw.size();
263  }
264 
265  u32 num = 0;
266  for (auto dst : m_sources_raw)
267  {
268  if (filter(dst))
269  {
270  num++;
271  }
272  }
273  return num;
274  }
275 
276  std::vector<Endpoint*> Net::get_sources(const std::function<bool(Endpoint* ep)>& filter) const
277  {
278  if (!filter)
279  {
280  return m_sources_raw;
281  }
282 
283  std::vector<Endpoint*> srcs;
284  for (auto src : m_sources_raw)
285  {
286  if (!filter(src))
287  {
288  continue;
289  }
290  srcs.push_back(src);
291  }
292  return srcs;
293  }
294 
296  {
297  return m_internal_manager->net_add_destination(this, gate, pin);
298  }
299 
300  Endpoint* Net::add_destination(Gate* gate, const std::string& pin_name)
301  {
302  if (gate == nullptr)
303  {
304  log_warning("net", "could not add destination to gate: nullptr given for gate");
305  return nullptr;
306  }
307  if (pin_name.empty())
308  {
309  log_warning("net", "could not add destination to gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
310  return nullptr;
311  }
312  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
313  if (pin == nullptr)
314  {
315  log_warning("net", "could not add destination to gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
316  return nullptr;
317  }
318  return add_destination(gate, pin);
319  }
320 
321  bool Net::remove_destination(Gate* gate, const GatePin* pin)
322  {
323  if (gate == nullptr)
324  {
325  log_warning("net", "could not remove destination from gate: nullptr given for gate");
326  return false;
327  }
328 
329  if (pin == nullptr)
330  {
331  log_warning("net", "could not remove destination from gate '{}' with ID {}: nullptr given for pin", gate->get_name(), gate->get_id());
332  return false;
333  }
334 
335  if (auto it = std::find_if(m_destinations_raw.begin(), m_destinations_raw.end(), [gate, pin](const auto* ep) { return ep->get_gate() == gate && ep->get_pin() == pin; });
336  it != m_destinations_raw.end())
337  {
338  return m_internal_manager->net_remove_destination(this, *it);
339  }
340  return false;
341  }
342 
343  bool Net::remove_destination(Gate* gate, const std::string& pin_name)
344  {
345  if (gate == nullptr)
346  {
347  log_warning("net", "could not remove destination from gate: nullptr given for gate");
348  return false;
349  }
350  if (pin_name.empty())
351  {
352  log_warning("net", "could not remove destination from gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
353  return false;
354  }
355  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
356  if (pin == nullptr)
357  {
358  log_warning("net", "could not remove destination from gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
359  return false;
360  }
361  return remove_destination(gate, pin);
362  }
363 
365  {
366  if (ep == nullptr)
367  {
368  return false;
369  }
370  return m_internal_manager->net_remove_destination(this, ep);
371  }
372 
373  bool Net::is_a_destination(const Gate* gate) const
374  {
375  if (gate == nullptr)
376  {
377  log_warning("net", "could not check if gate is a destination: nullptr given for gate");
378  return false;
379  }
380 
381  return std::find_if(m_destinations_raw.begin(), m_destinations_raw.end(), [gate](const auto* ep) { return ep->get_gate() == gate; }) != m_destinations_raw.end();
382  }
383 
384  bool Net::is_a_destination(const Gate* gate, const GatePin* pin) const
385  {
386  if (gate == nullptr)
387  {
388  log_warning("net", "could not check if gate is a destination: nullptr given for gate");
389  return false;
390  }
391 
392  if (pin == nullptr)
393  {
394  log_warning("net", "could not check if gate is a destination: nullptr given for pin");
395  return false;
396  }
397 
398  return std::find_if(m_destinations_raw.begin(), m_destinations_raw.end(), [gate, pin](const auto* ep) { return ep->get_gate() == gate && ep->get_pin() == pin; }) != m_destinations_raw.end();
399  }
400 
401  bool Net::is_a_destination(const Gate* gate, const std::string& pin_name) const
402  {
403  if (gate == nullptr)
404  {
405  log_warning("net", "could not check if gate is a destination: nullptr given for gate");
406  return false;
407  }
408 
409  if (pin_name.empty())
410  {
411  log_warning("net", "could not check if gate '{}' with ID {} is a destination: empty string provided as pin name", gate->get_name(), gate->get_id());
412  return false;
413  }
414 
415  return is_a_destination(gate, gate->get_type()->get_pin_by_name(pin_name));
416  }
417 
418  bool Net::is_a_destination(const Endpoint* ep) const
419  {
420  if (ep == nullptr)
421  {
422  return false;
423  }
424  if (!ep->is_destination_pin())
425  {
426  return false;
427  }
428 
429  return std::find(m_destinations_raw.begin(), m_destinations_raw.end(), ep) != m_destinations_raw.end();
430  }
431 
432  u32 Net::get_num_of_destinations(const std::function<bool(Endpoint* ep)>& filter) const
433  {
434  if (!filter)
435  {
436  return (u32)m_destinations_raw.size();
437  }
438 
439  u32 num = 0;
440  for (auto dst : m_destinations_raw)
441  {
442  if (filter(dst))
443  {
444  num++;
445  }
446  }
447  return num;
448  }
449 
450  std::vector<Endpoint*> Net::get_destinations(const std::function<bool(Endpoint* ep)>& filter) const
451  {
452  if (!filter)
453  {
454  return m_destinations_raw;
455  }
456 
457  std::vector<Endpoint*> dsts;
458  for (auto dst : m_destinations_raw)
459  {
460  if (!filter(dst))
461  {
462  continue;
463  }
464  dsts.push_back(dst);
465  }
466  return dsts;
467  }
468 
469  bool Net::is_unrouted() const
470  {
471  return ((m_sources.size() == 0) || (m_destinations.size() == 0));
472  }
473 
474  bool Net::is_gnd_net() const
475  {
476  return m_sources.size() == 1 && m_sources.front()->get_gate()->is_gnd_gate();
477  }
478 
479  bool Net::is_vcc_net() const
480  {
481  return m_sources.size() == 1 && m_sources.front()->get_gate()->is_vcc_gate();
482  }
483 
485  {
486  return m_internal_manager->m_netlist->mark_global_input_net(this);
487  }
488 
490  {
491  return m_internal_manager->m_netlist->mark_global_output_net(this);
492  }
493 
495  {
496  return m_internal_manager->m_netlist->unmark_global_input_net(this);
497  }
498 
500  {
501  return m_internal_manager->m_netlist->unmark_global_output_net(this);
502  }
503 
505  {
506  return m_internal_manager->m_netlist->is_global_input_net(this);
507  }
508 
510  {
511  return m_internal_manager->m_netlist->is_global_output_net(this);
512  }
513 } // namespace hal
bool is_source_pin() const
Definition: endpoint.cpp:43
bool is_destination_pin() const
Definition: endpoint.cpp:38
void notify(NetlistEvent::event ev, Netlist *netlist, u32 associated_data=0xFFFFFFFF)
Definition: gate.h:58
GateType * get_type() const
Definition: gate.cpp:125
const std::string & get_name() const
Definition: gate.cpp:105
u32 get_id() const
Definition: gate.cpp:95
GatePin * get_pin_by_name(const std::string &name) const
Definition: gate_type.cpp:318
@ name_changed
no associated_data
Definition: net.h:58
u32 get_num_of_sources(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:258
u32 get_id() const
Definition: net.cpp:88
Netlist * get_netlist() const
Definition: net.cpp:93
Endpoint * add_destination(Gate *gate, const std::string &pin_name)
Definition: net.cpp:300
bool remove_source(Gate *gate, const std::string &pin_name)
Definition: net.cpp:169
void set_name(const std::string &name)
Definition: net.cpp:103
bool mark_global_input_net()
Definition: net.cpp:484
Endpoint * add_source(Gate *gate, const std::string &pin_name)
Definition: net.cpp:127
const std::string & get_name() const
Definition: net.cpp:98
bool unmark_global_output_net()
Definition: net.cpp:499
bool operator==(const Net &other) const
Definition: net.cpp:26
bool is_unrouted() const
Definition: net.cpp:469
bool unmark_global_input_net()
Definition: net.cpp:494
bool mark_global_output_net()
Definition: net.cpp:489
bool is_a_source(const Gate *gate) const
Definition: net.cpp:199
Grouping * get_grouping() const
Definition: net.cpp:117
bool is_global_output_net() const
Definition: net.cpp:509
ssize_t get_hash() const
Definition: net.cpp:83
u32 get_num_of_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:432
std::vector< Endpoint * > get_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:450
bool operator!=(const Net &other) const
Definition: net.cpp:78
bool is_a_destination(const Gate *gate) const
Definition: net.cpp:373
bool is_global_input_net() const
Definition: net.cpp:504
bool remove_destination(Gate *gate, const std::string &pin_name)
Definition: net.cpp:343
bool is_vcc_net() const
Definition: net.cpp:479
std::vector< Endpoint * > get_sources(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:276
bool is_gnd_net() const
Definition: net.cpp:474
bool mark_global_input_net(Net *net)
Definition: netlist.cpp:387
bool mark_global_output_net(Net *net)
Definition: netlist.cpp:417
bool unmark_global_output_net(Net *net)
Definition: netlist.cpp:478
bool is_global_input_net(const Net *net) const
Definition: netlist.cpp:509
bool unmark_global_input_net(Net *net)
Definition: netlist.cpp:447
bool is_global_output_net(const Net *net) const
Definition: netlist.cpp:514
uint32_t u32
Definition: defines.h:41
#define log_error(channel,...)
Definition: log.h:78
#define log_debug(channel,...)
Definition: log.h:74
#define log_warning(channel,...)
Definition: log.h:76
T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:360
Definition: defines.h:45
std::string name
i32 id