HAL
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 (auto it = std::find_if(m_sources_raw.begin(), m_sources_raw.end(), [gate, pin](auto ep) { return ep->get_gate() == gate && *ep->get_pin() == *pin; }); it != m_sources_raw.end())
151  {
152  return m_internal_manager->net_remove_source(this, *it);
153  }
154  return false;
155  }
156 
157  bool Net::remove_source(Gate* gate, const std::string& pin_name)
158  {
159  if (gate == nullptr)
160  {
161  log_warning("net", "could not remove source from gate: nullptr given for gate");
162  return false;
163  }
164  if (pin_name.empty())
165  {
166  log_warning("net", "could not remove source from gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
167  return false;
168  }
169  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
170  if (pin == nullptr)
171  {
172  log_warning("net", "could not remove source from gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
173  return false;
174  }
175  return remove_source(gate, pin);
176  }
177 
179  {
180  if (ep == nullptr)
181  {
182  return false;
183  }
184  return m_internal_manager->net_remove_source(this, ep);
185  }
186 
187  bool Net::is_a_source(const Gate* gate) const
188  {
189  if (gate == nullptr)
190  {
191  log_warning("net", "could not check if gate is a source: nullptr given for gate");
192  return false;
193  }
194 
195  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();
196  }
197 
198  bool Net::is_a_source(const Gate* gate, const GatePin* pin) const
199  {
200  if (gate == nullptr)
201  {
202  log_warning("net", "could not check if gate is a source: nullptr given for gate");
203  return false;
204  }
205 
206  if (pin == nullptr)
207  {
208  log_warning("net", "could not check if gate is a source: nullptr given for pin");
209  return false;
210  }
211 
212  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();
213  }
214 
215  bool Net::is_a_source(const Gate* gate, const std::string& pin_name) const
216  {
217  if (gate == nullptr)
218  {
219  log_warning("net", "could not check if gate is a source: nullptr given for gate");
220  return false;
221  }
222 
223  if (pin_name.empty())
224  {
225  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());
226  return false;
227  }
228 
229  return is_a_source(gate, gate->get_type()->get_pin_by_name(pin_name));
230  }
231 
232  bool Net::is_a_source(const Endpoint* ep) const
233  {
234  if (ep == nullptr)
235  {
236  return false;
237  }
238  if (!ep->is_source_pin())
239  {
240  return false;
241  }
242 
243  return std::find(m_sources_raw.begin(), m_sources_raw.end(), ep) != m_sources_raw.end();
244  }
245 
246  u32 Net::get_num_of_sources(const std::function<bool(Endpoint* ep)>& filter) const
247  {
248  if (!filter)
249  {
250  return (u32)m_sources_raw.size();
251  }
252 
253  u32 num = 0;
254  for (auto dst : m_sources_raw)
255  {
256  if (filter(dst))
257  {
258  num++;
259  }
260  }
261  return num;
262  }
263 
264  std::vector<Endpoint*> Net::get_sources(const std::function<bool(Endpoint* ep)>& filter) const
265  {
266  if (!filter)
267  {
268  return m_sources_raw;
269  }
270 
271  std::vector<Endpoint*> srcs;
272  for (auto src : m_sources_raw)
273  {
274  if (!filter(src))
275  {
276  continue;
277  }
278  srcs.push_back(src);
279  }
280  return srcs;
281  }
282 
284  {
285  return m_internal_manager->net_add_destination(this, gate, pin);
286  }
287 
288  Endpoint* Net::add_destination(Gate* gate, const std::string& pin_name)
289  {
290  if (gate == nullptr)
291  {
292  log_warning("net", "could not add destination to gate: nullptr given for gate");
293  return nullptr;
294  }
295  if (pin_name.empty())
296  {
297  log_warning("net", "could not add destination to gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
298  return nullptr;
299  }
300  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
301  if (pin == nullptr)
302  {
303  log_warning("net", "could not add destination to gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
304  return nullptr;
305  }
306  return add_destination(gate, pin);
307  }
308 
309  bool Net::remove_destination(Gate* gate, const GatePin* pin)
310  {
311  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; });
312  it != m_destinations_raw.end())
313  {
314  return m_internal_manager->net_remove_destination(this, *it);
315  }
316  return false;
317  }
318 
319  bool Net::remove_destination(Gate* gate, const std::string& pin_name)
320  {
321  if (gate == nullptr)
322  {
323  log_warning("net", "could not remove destination from gate: nullptr given for gate");
324  return false;
325  }
326  if (pin_name.empty())
327  {
328  log_warning("net", "could not remove destination from gate '{}' with ID {}: empty string provided as pin name", gate->get_name(), gate->get_id());
329  return false;
330  }
331  GatePin* pin = gate->get_type()->get_pin_by_name(pin_name);
332  if (pin == nullptr)
333  {
334  log_warning("net", "could not remove destination from gate '{}' with ID {}: no pin with name '{}' exists", gate->get_name(), gate->get_id(), pin_name);
335  return false;
336  }
337  return remove_destination(gate, pin);
338  }
339 
341  {
342  if (ep == nullptr)
343  {
344  return false;
345  }
346  return m_internal_manager->net_remove_destination(this, ep);
347  }
348 
349  bool Net::is_a_destination(const Gate* gate) const
350  {
351  if (gate == nullptr)
352  {
353  log_warning("net", "could not check if gate is a destination: nullptr given for gate");
354  return false;
355  }
356 
357  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();
358  }
359 
360  bool Net::is_a_destination(const Gate* gate, const GatePin* pin) const
361  {
362  if (gate == nullptr)
363  {
364  log_warning("net", "could not check if gate is a destination: nullptr given for gate");
365  return false;
366  }
367 
368  if (pin == nullptr)
369  {
370  log_warning("net", "could not check if gate is a destination: nullptr given for pin");
371  return false;
372  }
373 
374  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();
375  }
376 
377  bool Net::is_a_destination(const Gate* gate, const std::string& pin_name) const
378  {
379  if (gate == nullptr)
380  {
381  log_warning("net", "could not check if gate is a destination: nullptr given for gate");
382  return false;
383  }
384 
385  if (pin_name.empty())
386  {
387  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());
388  return false;
389  }
390 
391  return is_a_destination(gate, gate->get_type()->get_pin_by_name(pin_name));
392  }
393 
394  bool Net::is_a_destination(const Endpoint* ep) const
395  {
396  if (ep == nullptr)
397  {
398  return false;
399  }
400  if (!ep->is_destination_pin())
401  {
402  return false;
403  }
404 
405  return std::find(m_destinations_raw.begin(), m_destinations_raw.end(), ep) != m_destinations_raw.end();
406  }
407 
408  u32 Net::get_num_of_destinations(const std::function<bool(Endpoint* ep)>& filter) const
409  {
410  if (!filter)
411  {
412  return (u32)m_destinations_raw.size();
413  }
414 
415  u32 num = 0;
416  for (auto dst : m_destinations_raw)
417  {
418  if (filter(dst))
419  {
420  num++;
421  }
422  }
423  return num;
424  }
425 
426  std::vector<Endpoint*> Net::get_destinations(const std::function<bool(Endpoint* ep)>& filter) const
427  {
428  if (!filter)
429  {
430  return m_destinations_raw;
431  }
432 
433  std::vector<Endpoint*> dsts;
434  for (auto dst : m_destinations_raw)
435  {
436  if (!filter(dst))
437  {
438  continue;
439  }
440  dsts.push_back(dst);
441  }
442  return dsts;
443  }
444 
445  bool Net::is_unrouted() const
446  {
447  return ((m_sources.size() == 0) || (m_destinations.size() == 0));
448  }
449 
450  bool Net::is_gnd_net() const
451  {
452  return m_sources.size() == 1 && m_sources.front()->get_gate()->is_gnd_gate();
453  }
454 
455  bool Net::is_vcc_net() const
456  {
457  return m_sources.size() == 1 && m_sources.front()->get_gate()->is_vcc_gate();
458  }
459 
461  {
462  return m_internal_manager->m_netlist->mark_global_input_net(this);
463  }
464 
466  {
467  return m_internal_manager->m_netlist->mark_global_output_net(this);
468  }
469 
471  {
472  return m_internal_manager->m_netlist->unmark_global_input_net(this);
473  }
474 
476  {
477  return m_internal_manager->m_netlist->unmark_global_output_net(this);
478  }
479 
481  {
482  return m_internal_manager->m_netlist->is_global_input_net(this);
483  }
484 
486  {
487  return m_internal_manager->m_netlist->is_global_output_net(this);
488  }
489 } // namespace hal
bool is_source_pin() const
Definition: endpoint.cpp:43
bool is_destination_pin() const
Definition: endpoint.cpp:38
NETLIST_API 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:246
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:288
bool remove_source(Gate *gate, const std::string &pin_name)
Definition: net.cpp:157
void set_name(const std::string &name)
Definition: net.cpp:103
bool mark_global_input_net()
Definition: net.cpp:460
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:475
bool operator==(const Net &other) const
Definition: net.cpp:26
bool is_unrouted() const
Definition: net.cpp:445
bool unmark_global_input_net()
Definition: net.cpp:470
bool mark_global_output_net()
Definition: net.cpp:465
bool is_a_source(const Gate *gate) const
Definition: net.cpp:187
Grouping * get_grouping() const
Definition: net.cpp:117
bool is_global_output_net() const
Definition: net.cpp:485
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:408
std::vector< Endpoint * > get_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:426
bool operator!=(const Net &other) const
Definition: net.cpp:78
bool is_a_destination(const Gate *gate) const
Definition: net.cpp:349
bool is_global_input_net() const
Definition: net.cpp:480
bool remove_destination(Gate *gate, const std::string &pin_name)
Definition: net.cpp:319
bool is_vcc_net() const
Definition: net.cpp:455
std::vector< Endpoint * > get_sources(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:264
bool is_gnd_net() const
Definition: net.cpp:450
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
#define log_error(channel,...)
Definition: log.h:78
#define log_debug(channel,...)
Definition: log.h:74
#define log_warning(channel,...)
Definition: log.h:76
CORE_API T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:358
quint32 u32
std::string name
i32 id