HAL  v4.5.0-133-g64838ea8d
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
module.cpp
Go to the documentation of this file.
3 
7 #include "hal_core/netlist/net.h"
10 #include "hal_core/utilities/log.h"
11 
12 namespace hal
13 {
14  Module::Module(NetlistInternalManager* internal_manager, EventHandler* event_handler, u32 id, Module* parent, const std::string& name)
15  {
16  m_internal_manager = internal_manager;
17  m_id = id;
18  m_parent = parent;
19  m_name = name;
20 
21  m_next_pin_id = 1;
22  m_next_pin_group_id = 1;
23 
24  m_event_handler = event_handler;
25  }
26 
27  bool Module::operator==(const Module& other) const
28  {
29  if (m_id != other.get_id() || m_name != other.get_name() || m_type != other.get_type())
30  {
31  log_debug("module", "the modules with IDs {} and {} are not equal due to an unequal ID, name, or type.", m_id, other.get_id());
32  return false;
33  }
34 
35  // does not check parent module to avoid infinite loop
36 
37  for (Module* other_module : other.get_submodules())
38  {
39  if (const auto it = m_submodules_map.find(other_module->get_id()); it == m_submodules_map.end() || *it->second != *other_module)
40  {
41  log_debug("module", "the modules with IDs {} and {} are not equal due to an unequal submodules.", m_id, other.get_id());
42  return false;
43  }
44  }
45 
46  for (Gate* other_gate : other.get_gates())
47  {
48  if (const auto it = m_gates_map.find(other_gate->get_id()); it == m_gates_map.end() || *it->second != *other_gate)
49  {
50  log_debug("module", "the modules with IDs {} and {} are not equal due to an unequal gates.", m_id, other.get_id());
51  return false;
52  }
53  }
54 
55  for (const PinGroup<ModulePin>* pin_group : get_pin_groups())
56  {
57  if (const auto other_pin_group_res = other.get_pin_group_by_id(pin_group->get_id()); other_pin_group_res == nullptr || *other_pin_group_res != *pin_group)
58  {
59  log_debug("module", "the modules with IDs {} and {} are not equal due to an unequal pin group.", m_id, other.get_id());
60  return false;
61  }
62  }
63 
64  if (!DataContainer::operator==(other))
65  {
66  log_debug("module", "the modules with IDs {} and {} are not equal due to unequal data.", m_id, other.get_id());
67  return false;
68  }
69 
70  return true;
71  }
72 
73  bool Module::operator!=(const Module& other) const
74  {
75  return !operator==(other);
76  }
77 
78  ssize_t Module::get_hash() const
79  {
80  return (uintptr_t)this;
81  }
82 
84  {
85  return m_id;
86  }
87 
88  std::string Module::get_name() const
89  {
90  return m_name;
91  }
92 
93  void Module::set_name(const std::string& name)
94  {
95  if (utils::trim(name).empty())
96  {
97  log_warning("module", "module name cannot be empty.");
98  return;
99  }
100  if (name != m_name)
101  {
102  m_name = name;
103  m_event_handler->notify(ModuleEvent::event::name_changed, this);
104  }
105  }
106 
107  std::string Module::get_type() const
108  {
109  return m_type;
110  }
111 
112  void Module::set_type(const std::string& type)
113  {
114  if (type != m_type)
115  {
116  m_type = type;
117  m_event_handler->notify(ModuleEvent::event::type_changed, this);
118  }
119  }
120 
122  {
123  return m_grouping;
124  }
125 
127  {
128  return m_parent;
129  }
130 
131  std::vector<Module*> Module::get_parent_modules(const std::function<bool(Module*)>& filter, bool recursive) const
132  {
133  std::vector<Module*> res;
134  if (m_parent == nullptr)
135  {
136  return {};
137  }
138 
139  if (!filter)
140  {
141  res.push_back(m_parent);
142  }
143  else
144  {
145  if (filter(m_parent))
146  {
147  res.push_back(m_parent);
148  }
149  }
150 
151  if (recursive)
152  {
153  std::vector<Module*> more = m_parent->get_parent_modules(filter, true);
154  res.reserve(res.size() + more.size());
155  res.insert(res.end(), more.begin(), more.end());
156  }
157  return res;
158  }
159 
161  {
162  int retval = 0;
163  const Module* p = this;
164  while ((p = p->get_parent_module()))
165  {
166  ++retval;
167  }
168  return retval;
169  }
170 
172  {
173  if (new_parent == this)
174  {
175  log_error("module", "module '{}' with ID {} in netlist with ID {} cannot be its own parent module.", m_name, m_id, m_internal_manager->m_netlist->get_id());
176  return false;
177  }
178 
179  if (m_parent == nullptr)
180  {
181  log_error("module", "no parent module can be assigned to top module '{}' with ID {} in netlist with ID {}.", m_name, m_id, m_internal_manager->m_netlist->get_id());
182  return false;
183  }
184 
185  if (new_parent == nullptr)
186  {
187  log_error("module", "module '{}' with ID {} in netlist with ID {} cannot be assigned to be the top module.", m_name, m_id, m_internal_manager->m_netlist->get_id());
188  return false;
189  }
190 
191  if (!get_netlist()->is_module_in_netlist(new_parent))
192  {
193  log_error("module", "module '{}' with ID {} is not contained in netlist with ID {}.", new_parent->get_name(), new_parent->get_id(), m_internal_manager->m_netlist->get_id());
194  return false;
195  }
196 
197  auto children = get_submodules(nullptr, true);
198  if (std::find(children.begin(), children.end(), new_parent) != children.end())
199  {
200  new_parent->set_parent_module(m_parent);
201  }
202 
203  // detach completely before the old parent re-checks its nets: is_parent_module_of() walks up the parent
204  // chain, so the moved subtree must already read as external to the old parent
205  Module* old_parent = m_parent;
206  old_parent->m_submodules_map.erase(m_id);
207  utils::indexed_vector_erase(old_parent->m_submodules, old_parent->m_submodule_positions, this);
208  m_parent = new_parent;
209 
210  if (m_internal_manager->m_net_checks_enabled)
211  {
212  for (Net* net : get_nets(nullptr, true))
213  {
214  if (auto res = old_parent->check_net(net, true); res.is_error())
215  {
216  log_error("module", "{}", res.get_error().get());
217  }
218  }
219  }
220 
221  m_event_handler->notify(ModuleEvent::event::submodule_removed, old_parent, m_id);
222 
223  m_parent->m_submodules_map[m_id] = this;
224  utils::indexed_vector_push_back(m_parent->m_submodules, m_parent->m_submodule_positions, this);
225 
226  if (m_internal_manager->m_net_checks_enabled)
227  {
228  for (Net* net : get_nets(nullptr, true))
229  {
230  if (auto res = m_parent->check_net(net, true); res.is_error())
231  {
232  log_error("module", "{}", res.get_error().get());
233  }
234  }
235  }
236 
237  m_event_handler->notify(ModuleEvent::event::parent_changed, this);
238  m_event_handler->notify(ModuleEvent::event::submodule_added, m_parent, m_id);
239 
240  return true;
241  }
242 
243  bool Module::is_parent_module_of(const Module* module, bool recursive) const
244  {
245  if (module == nullptr)
246  {
247  return false;
248  }
249  // walk up the parent chain of the given module rather than down this module's subtree: the chain is
250  // at most as long as the hierarchy is deep, whereas the subtree of a module near the root can hold most
251  // of the netlist, and this query runs once per endpoint when module nets are recomputed
252  const Module* parent = module->m_parent;
253  if (!recursive)
254  {
255  return parent == this;
256  }
257  while (parent != nullptr)
258  {
259  if (parent == this)
260  {
261  return true;
262  }
263  parent = parent->m_parent;
264  }
265  return false;
266  }
267 
268  std::vector<Module*> Module::get_submodules(const std::function<bool(Module*)>& filter, bool recursive) const
269  {
270  std::vector<Module*> res;
271  if (!filter)
272  {
273  res = m_submodules;
274  }
275  else
276  {
277  for (auto sm : m_submodules)
278  {
279  if (filter(sm))
280  {
281  res.push_back(sm);
282  }
283  }
284  }
285 
286  if (recursive)
287  {
288  for (auto sm : m_submodules)
289  {
290  auto more = sm->get_submodules(filter, true);
291  res.reserve(res.size() + more.size());
292  res.insert(res.end(), more.begin(), more.end());
293  }
294  }
295  return res;
296  }
297 
298  bool Module::is_submodule_of(const Module* module, bool recursive) const
299  {
300  if (module == nullptr)
301  {
302  return false;
303  }
304  if (m_parent == module)
305  {
306  return true;
307  }
308  else if (recursive && m_parent->is_submodule_of(module, true))
309  {
310  return true;
311  }
312 
313  return false;
314  }
315 
316  bool Module::contains_module(const Module* other, bool recursive) const
317  {
318  return is_parent_module_of(other, recursive);
319  }
320 
322  {
323  return m_parent == nullptr;
324  }
325 
327  {
328  return m_internal_manager->m_netlist;
329  }
330 
332  {
333  return m_internal_manager->module_assign_gates(this, {gate});
334  }
335 
336  bool Module::assign_gates(const std::vector<Gate*>& gates)
337  {
338  return m_internal_manager->module_assign_gates(this, gates);
339  }
340 
342  {
343  return remove_gates({gate});
344  }
345 
346  bool Module::remove_gates(const std::vector<Gate*>& gates)
347  {
348  for (Gate* gate : gates)
349  {
350  if (gate == nullptr || !contains_gate(gate))
351  {
352  return false;
353  }
354  }
355 
356  return m_internal_manager->module_assign_gates(m_internal_manager->m_netlist->get_top_module(), gates);
357  }
358 
359  bool Module::contains_gate(Gate* gate, bool recursive) const
360  {
361  if (gate == nullptr)
362  {
363  return false;
364  }
365  bool success = std::find(m_gates.begin(), m_gates.end(), gate) != m_gates.end();
366  if (!success && recursive)
367  {
368  for (auto sm : m_submodules)
369  {
370  if (sm->contains_gate(gate, true))
371  {
372  return true;
373  }
374  }
375  }
376  return success;
377  }
378 
379  Gate* Module::get_gate_by_id(const u32 gate_id, bool recursive) const
380  {
381  auto it = m_gates_map.find(gate_id);
382  if (it == m_gates_map.end())
383  {
384  if (recursive)
385  {
386  for (auto sm : m_submodules)
387  {
388  auto res = sm->get_gate_by_id(gate_id, true);
389  if (res != nullptr)
390  {
391  return res;
392  }
393  }
394  }
395  return nullptr;
396  }
397  return it->second;
398  }
399 
400  const std::vector<Gate*>& Module::get_gates() const
401  {
402  return m_gates;
403  }
404 
405  std::vector<Gate*> Module::get_gates(const std::function<bool(Gate*)>& filter, bool recursive) const
406  {
407  std::vector<Gate*> res;
408  if (!filter)
409  {
410  res = m_gates;
411  }
412  else
413  {
414  for (auto g : m_gates)
415  {
416  if (!filter(g))
417  {
418  continue;
419  }
420  res.push_back(g);
421  }
422  }
423 
424  if (recursive)
425  {
426  for (auto sm : m_submodules)
427  {
428  auto more = sm->get_gates(filter, true);
429  res.reserve(res.size() + more.size());
430  res.insert(res.end(), more.begin(), more.end());
431  }
432  }
433 
434  return res;
435  }
436 
437  /*
438  * ################################################################
439  * net functions
440  * ################################################################
441  */
442 
444  {
445  m_nets.clear();
446  m_input_nets.clear();
447  m_output_nets.clear();
448  m_internal_nets.clear();
449 
450  std::unordered_set<Net*> net_cache;
451  for (const Gate* gate : get_gates(nullptr, true))
452  {
453  for (Net* net : gate->get_fan_in_nets())
454  {
455  net_cache.insert(net);
456  }
457  for (Net* net : gate->get_fan_out_nets())
458  {
459  net_cache.insert(net);
460  }
461  }
462 
463  for (Net* net : net_cache)
464  {
465  NetConnectivity con = check_net_endpoints(net);
466  if (con.has_internal_source || con.has_internal_destination)
467  {
468  m_nets.insert(net);
469 
470  if (con.has_internal_source && con.has_internal_destination)
471  {
472  m_internal_nets.insert(net);
473  }
474 
475  if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
476  {
477  m_input_nets.insert(net);
478  m_output_nets.insert(net);
479  }
480  else if (con.has_external_source && con.has_internal_destination)
481  {
482  m_input_nets.insert(net);
483  }
484  else if (con.has_internal_source && con.has_external_destination)
485  {
486  m_output_nets.insert(net);
487  }
488  }
489  }
490  }
491 
492  bool Module::contains_net(Net* net, bool recursive) const
493  {
494  if (net == nullptr)
495  {
496  return false;
497  }
498  bool success = m_nets.find(net) != m_nets.end();
499  if (!success && recursive)
500  {
501  for (auto sm : m_submodules)
502  {
503  if (sm->contains_net(net, true))
504  {
505  return true;
506  }
507  }
508  }
509  return success;
510  }
511 
512  const std::unordered_set<Net*>& Module::get_nets() const
513  {
514  return m_nets;
515  }
516 
517  std::unordered_set<Net*> Module::get_nets(const std::function<bool(Net*)>& filter, bool recursive) const
518  {
519  std::unordered_set<Net*> res;
520  if (!filter)
521  {
522  return m_nets;
523  }
524  else
525  {
526  for (Net* n : m_nets)
527  {
528  if (!filter(n))
529  {
530  continue;
531  }
532  res.insert(n);
533  }
534  }
535 
536  if (recursive)
537  {
538  for (auto sm : m_submodules)
539  {
540  auto more = sm->get_nets(filter, true);
541  res.reserve(res.size() + more.size());
542  res.insert(more.begin(), more.end());
543  }
544  }
545 
546  return res;
547  }
548 
549  const std::unordered_set<Net*>& Module::get_input_nets() const
550  {
551  return m_input_nets;
552  }
553 
554  const std::unordered_set<Net*>& Module::get_output_nets() const
555  {
556  return m_output_nets;
557  }
558 
559  const std::unordered_set<Net*>& Module::get_internal_nets() const
560  {
561  return m_internal_nets;
562  }
563 
565  {
566  if (net == nullptr)
567  {
568  return false;
569  }
570 
571  return m_input_nets.find(net) != m_input_nets.end();
572  }
573 
575  {
576  if (net == nullptr)
577  {
578  return false;
579  }
580 
581  return m_output_nets.find(net) != m_output_nets.end();
582  }
583 
585  {
586  if (net == nullptr)
587  {
588  return false;
589  }
590 
591  return m_internal_nets.find(net) != m_internal_nets.end();
592  }
593 
594  Module::NetConnectivity Module::check_net_endpoints(const Net* net) const
595  {
596  std::vector<Endpoint*> sources = net->get_sources();
597  std::vector<Endpoint*> destinations = net->get_destinations();
598 
599  NetConnectivity res;
600  res.has_external_source = net->is_global_input_net();
601  res.has_internal_source = false;
602  res.has_external_destination = net->is_global_output_net();
603  res.has_internal_destination = false;
604 
605  for (Endpoint* ep : sources)
606  {
607  if (Module* mod = ep->get_gate()->get_module(); this != mod && !is_parent_module_of(mod, true))
608  {
609  res.has_external_source = true;
610  }
611  else
612  {
613  res.has_internal_source = true;
614  }
615 
616  if (res.has_external_source && res.has_internal_source)
617  {
618  break;
619  }
620  }
621 
622  for (Endpoint* ep : destinations)
623  {
624  if (Module* mod = ep->get_gate()->get_module(); this != mod && !is_parent_module_of(mod, true))
625  {
626  res.has_external_destination = true;
627  }
628  else
629  {
630  res.has_internal_destination = true;
631  }
632 
633  if (res.has_external_destination && res.has_internal_destination)
634  {
635  break;
636  }
637  }
638 
639  return res;
640  }
641 
642  Result<std::monostate> Module::check_net(Net* net, bool recursive)
643  {
644  NetConnectivity con = check_net_endpoints(net);
645  if (con.has_internal_source && con.has_internal_destination)
646  {
647  m_internal_nets.insert(net);
648  }
649  else
650  {
651  m_internal_nets.erase(net);
652  }
653 
654  if (con.has_internal_source || con.has_internal_destination)
655  {
656  m_nets.insert(net);
657  }
658  else
659  {
660  m_nets.erase(net);
661  }
662 
663  if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
664  {
665  if (auto pin = get_pin_by_net(net); pin != nullptr)
666  {
667  auto direction = pin->get_direction();
669  {
670  m_output_nets.insert(net);
671  pin->set_direction(PinDirection::inout);
672  PinChangedEvent(this, PinEvent::PinTypeChange, pin->get_id()).send();
673  }
674  else if (direction == PinDirection::output)
675  {
676  m_input_nets.insert(net);
677  pin->set_direction(PinDirection::inout);
678  PinChangedEvent(this, PinEvent::PinTypeChange, pin->get_id()).send();
679  }
680  }
681  else
682  {
683  if (!assign_pin_net(get_unique_pin_id(), net, PinDirection::inout))
684  {
685  return ERR("could not assign inout pin to net ID " + std::to_string(net->get_id()) + ": failed to create pin");
686  }
687  }
688  }
689  else if (con.has_external_source && con.has_internal_destination)
690  {
691  if (auto pin = get_pin_by_net(net); pin != nullptr)
692  {
693  const auto direction = pin->get_direction();
695  {
696  m_input_nets.insert(net);
697  m_output_nets.erase(net);
698  pin->set_direction(PinDirection::input);
699  PinChangedEvent(this, PinEvent::PinTypeChange, pin->get_id()).send();
700  }
701  }
702  else
703  {
704  m_input_nets.insert(net);
705  if (!assign_pin_net(get_unique_pin_id(), net, PinDirection::input))
706  {
707  return ERR("could not assign input pin to net ID " + std::to_string(net->get_id()) + ": failed to create pin");
708  }
709  }
710  }
711  else if (con.has_internal_source && con.has_external_destination)
712  {
713  if (auto pin = get_pin_by_net(net); pin != nullptr)
714  {
715  const auto direction = pin->get_direction();
717  {
718  m_output_nets.insert(net);
719  m_input_nets.erase(net);
720  pin->set_direction(PinDirection::output);
721  PinChangedEvent(this, PinEvent::PinTypeChange, pin->get_id()).send();
722  }
723  }
724  else
725  {
726  m_output_nets.insert(net);
727  if (!assign_pin_net(get_unique_pin_id(), net, PinDirection::output))
728  {
729  return ERR("could not assign output pin to net ID " + std::to_string(net->get_id()) + ": failed to create pin");
730  }
731  }
732  }
733  else
734  {
735  if (auto pin = get_pin_by_net(net); pin != nullptr)
736  {
737  auto direction = pin->get_direction();
739  {
740  m_input_nets.erase(net);
741  }
743  {
744  m_output_nets.erase(net);
745  }
746  if (!remove_pin_net(net))
747  {
748  return ERR("Remove pin net failed");
749  }
750  }
751  }
752 
753  if (m_internal_manager->m_net_checks_enabled && recursive && m_parent != nullptr)
754  {
755  if (auto res = m_parent->check_net(net, true); res.is_error())
756  {
757  return res;
758  }
759  }
760 
761  return OK({});
762  }
763 
764  /*
765  * ################################################################
766  * pin functions
767  * ################################################################
768  */
769 
771  {
772  if (!m_free_pin_ids.empty())
773  {
774  return *(m_free_pin_ids.begin());
775  }
776  while (m_used_pin_ids.find(m_next_pin_id) != m_used_pin_ids.end())
777  {
778  m_next_pin_id++;
779  }
780  return m_next_pin_id;
781  }
782 
784  {
785  if (!m_free_pin_group_ids.empty())
786  {
787  return *(m_free_pin_group_ids.begin());
788  }
789  while (m_used_pin_group_ids.find(m_next_pin_group_id) != m_used_pin_group_ids.end())
790  {
791  m_next_pin_group_id++;
792  }
793  return m_next_pin_group_id;
794  }
795 
796  Result<ModulePin*> Module::create_pin(const u32 id, const std::string& name, Net* net, PinType type, bool create_group, bool force_name)
797  {
798  if (name.empty())
799  {
800  return ERR("could not create pin for module '" + m_name + "' with ID " + std::to_string(m_id) + ": empty string passed as name");
801  }
802 
803  if (m_internal_manager->m_net_checks_enabled)
804  {
805  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id)
806  + ": unable to manually assign pin as automatic net checks are enabled. Disable these checks using 'Netlist::enable_automatic_net_checks(false)' in case you "
807  "want to manage pins manually.");
808  }
809 
810  if (net == nullptr)
811  {
812  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": net is a 'nullptr'");
813  }
814 
816  bool is_input = is_input_net(net);
817  bool is_output = is_output_net(net);
818 
819  if (is_input && is_output)
820  {
822  }
823  else if (is_input)
824  {
826  }
827  else if (is_output)
828  {
830  }
831  else
832  {
833  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": net '" + net->get_name() + "' with ID " + std::to_string(net->get_id())
834  + " is neither an input nor an output");
835  }
836 
837  if (auto pin_res = create_pin_internal(id, name, net, direction, type, force_name); pin_res.is_error())
838  {
839  return ERR_APPEND(pin_res.get_error(), "could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id));
840  }
841  else
842  {
843  // create_pin_internal OK
844  if (create_group)
845  {
846  if (const auto group_res = create_pin_group_internal(get_unique_pin_group_id(), name, direction, type, true, 0, force_name); group_res.is_error())
847  {
848  assert(delete_pin_internal(pin_res.get()));
849  return ERR_APPEND(group_res.get_error(), "could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to create pin group");
850  }
851  else
852  {
853  // create_pin_group_internal OK
854  if (!group_res.get()->assign_pin(pin_res.get()))
855  {
856  assert(delete_pin_internal(pin_res.get()));
857  assert(delete_pin_group_internal(group_res.get()));
858  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to assign pin to pin group");
859  }
860  else
861  {
862  // pin assigned to new group OK
863  PinChangedEvent(this, PinEvent::GroupCreate, group_res.get()->get_id()).send();
864  }
865  }
866  }
867  else
868  {
869  PinChangedEvent(this, PinEvent::PinCreate, pin_res.get()->get_id()).send();
870  }
871  return pin_res;
872  }
873  }
874 
875  Result<ModulePin*> Module::create_pin(const std::string& name, Net* net, PinType type, bool create_group, bool force_name)
876  {
877  return create_pin(get_unique_pin_id(), name, net, type, create_group, force_name);
878  }
879 
880  std::vector<ModulePin*> Module::get_pins(const std::function<bool(ModulePin*)>& filter) const
881  {
882  std::vector<ModulePin*> res;
883  if (!filter)
884  {
885  res.reserve(m_pins.size());
886  for (const auto& group : m_pin_groups_ordered)
887  {
888  std::vector<ModulePin*> pins = group->get_pins();
889  res.insert(res.end(), pins.begin(), pins.end());
890  }
891  }
892  else
893  {
894  for (PinGroup<ModulePin>* group : m_pin_groups_ordered)
895  {
896  for (ModulePin* pin : group->get_pins())
897  {
898  if (filter(pin))
899  {
900  res.push_back(pin);
901  }
902  }
903  }
904  }
905  return res;
906  }
907 
908  std::vector<std::string> Module::get_pin_names(const std::function<bool(ModulePin*)>& filter) const
909  {
910  std::vector<std::string> res;
911  if (!filter)
912  {
913  res.reserve(m_pins.size());
914  for (const auto& group : m_pin_groups_ordered)
915  {
916  std::vector<ModulePin*> pins = group->get_pins();
917  for (const auto pin : group->get_pins())
918  {
919  res.push_back(pin->get_name());
920  }
921  }
922  }
923  else
924  {
925  for (PinGroup<ModulePin>* group : m_pin_groups_ordered)
926  {
927  for (ModulePin* pin : group->get_pins())
928  {
929  if (filter(pin))
930  {
931  res.push_back(pin->get_name());
932  }
933  }
934  }
935  }
936  return res;
937  }
938 
939  std::vector<ModulePin*> Module::get_input_pins() const
940  {
941  return get_pins([](const ModulePin* pin) {
944  });
945  }
946 
947  std::vector<std::string> Module::get_input_pin_names() const
948  {
949  return get_pin_names([](const ModulePin* pin) {
952  });
953  }
954 
955  std::vector<ModulePin*> Module::get_output_pins() const
956  {
957  return get_pins([](const ModulePin* pin) {
960  });
961  }
962 
963  std::vector<std::string> Module::get_output_pin_names() const
964  {
965  return get_pin_names([](const ModulePin* pin) {
968  });
969  }
970 
971  std::vector<PinGroup<ModulePin>*> Module::get_pin_groups(const std::function<bool(PinGroup<ModulePin>*)>& filter) const
972  {
973  std::vector<PinGroup<ModulePin>*> res;
974  if (!filter)
975  {
976  res.reserve(m_pin_groups_ordered.size());
977  res.insert(res.end(), m_pin_groups_ordered.begin(), m_pin_groups_ordered.end());
978  }
979  else
980  {
981  for (PinGroup<ModulePin>* group : m_pin_groups_ordered)
982  {
983  if (filter(group))
984  {
985  res.push_back(group);
986  }
987  }
988  }
989  return res;
990  }
991 
993  {
994  if (id == 0)
995  {
996  log_warning("module", "could not get pin by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
997  return nullptr;
998  }
999 
1000  if (const auto it = m_pins_map.find(id); it != m_pins_map.end())
1001  {
1002  return it->second;
1003  }
1004 
1005  log_warning("module", "could not get pin by ID for module '{}' with ID {}: no pin with ID {} exists", m_name, m_id, id);
1006  return nullptr;
1007  }
1008 
1009  ModulePin* Module::get_pin_by_name(const std::string& name) const
1010  {
1011  if (name.empty())
1012  {
1013  log_warning("module", "could not get pin by ID for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1014  return nullptr;
1015  }
1016 
1017  if (const auto it = m_pin_names_map.find(name); it != m_pin_names_map.end())
1018  {
1019  return it->second;
1020  }
1021 
1022  log_warning("module", "could not get pin by ID for module '{}' with ID {}: no pin with name '{}' exists", m_name, m_id, name);
1023  return nullptr;
1024  }
1025 
1027  {
1028  if (net == nullptr)
1029  {
1030  log_warning("module", "could not get pin by net for module '{}' with ID {}: net is a 'nullptr'", m_name, m_id);
1031  return nullptr;
1032  }
1033 
1034  if (const auto it = m_pin_nets_map.find(net); it != m_pin_nets_map.end())
1035  {
1036  return it->second;
1037  }
1038 
1039  log_debug("module", "could not get pin by net for module '{}' with ID {}: no pin belongs to net '{}' with ID {}", m_name, m_id, net->get_name(), net->get_id());
1040  return nullptr;
1041  }
1042 
1044  {
1045  if (id == 0)
1046  {
1047  log_warning("module", "could not get pin group by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
1048  return nullptr;
1049  }
1050 
1051  if (const auto it = m_pin_groups_map.find(id); it != m_pin_groups_map.end())
1052  {
1053  return it->second;
1054  }
1055 
1056  log_warning("module", "could not get pin group by ID for module '{}' with ID {}: no pin group with ID {} exists", m_name, m_id, id);
1057  return nullptr;
1058  }
1059 
1061  {
1062  if (name.empty())
1063  {
1064  log_warning("module", "could not get pin group by name for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1065  return nullptr;
1066  }
1067 
1068  if (const auto it = m_pin_group_names_map.find(name); it != m_pin_group_names_map.end())
1069  {
1070  return it->second;
1071  }
1072 
1073  log_warning("module", "could not get pin group by name for module '{}' with ID {}: no pin group with name '{}' exists", m_name, m_id, name);
1074  return nullptr;
1075  }
1076 
1077  bool Module::set_pin_name(ModulePin* pin, const std::string& new_name, bool force_name)
1078  {
1079  if (pin == nullptr)
1080  {
1081  log_warning("module", "could not set name for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1082  return false;
1083  }
1084 
1085  if (new_name.empty())
1086  {
1087  log_warning("module", "could not set name for pin '{}' with ID {} of module '{}' with ID {}: empty string passed as new name", pin->get_name(), pin->get_id(), m_name, m_id);
1088  return false;
1089  }
1090 
1091  if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1092  {
1093  log_warning("module", "could not set name for pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), m_name, m_id);
1094  return false;
1095  }
1096 
1097  if (const auto pin_it = m_pin_names_map.find(new_name); pin_it != m_pin_names_map.end())
1098  {
1099  if (force_name)
1100  {
1101  u32 ctr = 2;
1102  while (!this->set_pin_name(pin_it->second, new_name + "__" + std::to_string(ctr) + "__"))
1103  {
1104  ctr++;
1105  }
1106  }
1107  else
1108  {
1109  log_warning("module",
1110  "could not set name for pin '{}' with ID {} of module '{}' with ID {}: a pin with name '{}' already exists within the module",
1111  pin->get_name(),
1112  pin->get_id(),
1113  m_name,
1114  m_id,
1115  new_name);
1116  return false;
1117  }
1118  }
1119 
1120  if (const std::string& old_name = pin->get_name(); old_name != new_name)
1121  {
1122  m_pin_names_map.erase(old_name);
1123  pin->set_name(new_name);
1124  m_pin_names_map[new_name] = pin;
1126  }
1127 
1128  return true;
1129  }
1130 
1132  {
1133  if (pin == nullptr)
1134  {
1135  log_warning("module", "could not set type for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1136  return false;
1137  }
1138 
1139  if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1140  {
1141  log_warning("module", "could not set type for pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), m_name, m_id);
1142  return false;
1143  }
1144 
1145  if (pin->get_type() != new_type)
1146  {
1147  pin->set_type(new_type);
1149  }
1150 
1151  return true;
1152  }
1153 
1154  bool Module::set_pin_group_name(PinGroup<ModulePin>* pin_group, const std::string& new_name, bool force_name)
1155  {
1156  if (pin_group == nullptr)
1157  {
1158  log_warning("module", "could not set name for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1159  return false;
1160  }
1161 
1162  if (new_name.empty())
1163  {
1164  log_warning(
1165  "module", "could not set name for pin group '{}' with ID {} of module '{}' with ID {}: empty string passed as new name", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1166  return false;
1167  }
1168 
1169  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1170  {
1171  log_warning(
1172  "module", "could not set name for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1173  return false;
1174  }
1175 
1176  if (const auto pin_group_it = m_pin_group_names_map.find(new_name); pin_group_it != m_pin_group_names_map.end())
1177  {
1178  if (force_name)
1179  {
1180  u32 ctr = 2;
1181  while (!this->set_pin_group_name(pin_group_it->second, new_name + "__" + std::to_string(ctr) + "__"))
1182  {
1183  ctr++;
1184  }
1185  }
1186  else
1187  {
1188  log_warning("module",
1189  "could not set name for pin group '{}' with ID {} of module '{}' with ID {}: a pin group with name '{}' already exists within the module",
1190  pin_group->get_name(),
1191  pin_group->get_id(),
1192  m_name,
1193  m_id,
1194  new_name);
1195  return false;
1196  }
1197  }
1198 
1199  if (const std::string& old_name = pin_group->get_name(); old_name != new_name)
1200  {
1201  m_pin_group_names_map.erase(old_name);
1202  pin_group->set_name(new_name);
1203  m_pin_group_names_map[new_name] = pin_group;
1204  PinChangedEvent(this, PinEvent::GroupRename, pin_group->get_id()).send();
1205  }
1206 
1207  return true;
1208  }
1209 
1211  {
1212  if (pin_group == nullptr)
1213  {
1214  log_warning("module", "could not set type for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1215  return false;
1216  }
1217 
1218  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1219  {
1220  log_warning(
1221  "module", "could not set type for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1222  return false;
1223  }
1224 
1225  if (pin_group->get_type() != new_type)
1226  {
1227  pin_group->set_type(new_type);
1228  PinChangedEvent(this, PinEvent::GroupTypeChange, pin_group->get_id()).send();
1229  }
1230  return true;
1231  }
1232 
1234  {
1235  if (pin_group == nullptr)
1236  {
1237  log_warning("module", "could not set direction for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1238  return false;
1239  }
1240 
1241  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1242  {
1243  log_warning("module",
1244  "could not set direction for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1245  pin_group->get_name(),
1246  pin_group->get_id(),
1247  m_name,
1248  m_id);
1249  return false;
1250  }
1251 
1252  if (pin_group->get_direction() != new_direction)
1253  {
1254  pin_group->set_direction(new_direction);
1255  PinChangedEvent(this, PinEvent::GroupDirChange, pin_group->get_id()).send();
1256  }
1257  return true;
1258  }
1259 
1261  const std::string& name,
1262  const std::vector<ModulePin*> pins,
1264  PinType type,
1265  bool ascending,
1266  u32 start_index,
1267  bool delete_empty_groups,
1268  bool force_name)
1269  {
1270  PinChangedEventScope scope(this);
1271 
1272  if (name.empty())
1273  {
1274  return ERR("could not create pin group for module '" + m_name + "' with ID " + std::to_string(m_id) + ": empty string passed as name");
1275  }
1276 
1277  PinGroup<ModulePin>* pin_group;
1278 
1279  if (!ascending && !pins.empty())
1280  {
1281  start_index = start_index - (pins.size() - 1);
1282  }
1283 
1284  if (auto res = create_pin_group_internal(id, name, direction, type, ascending, start_index, force_name); res.is_error())
1285  {
1286  return ERR_APPEND(res.get_error(), "could not create pin group '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id));
1287  }
1288  else
1289  {
1290  pin_group = res.get();
1291  }
1292 
1293  if (ascending)
1294  {
1295  for (auto it = pins.begin(); it != pins.end(); ++it)
1296  {
1297  if (!assign_pin_to_group(pin_group, *it, delete_empty_groups))
1298  {
1299  assert(delete_pin_group(pin_group));
1300  return ERR("Assign pin to group failed.");
1301  }
1302  }
1303  }
1304  else
1305  {
1306  for (auto it = pins.rbegin(); it != pins.rend(); ++it)
1307  {
1308  if (!assign_pin_to_group(pin_group, *it, delete_empty_groups))
1309  {
1310  assert(delete_pin_group(pin_group));
1311  return ERR("Assign pin to group failed.");
1312  }
1313  }
1314  }
1315 
1316  PinChangedEvent(this, PinEvent::GroupCreate, pin_group->get_id()).send();
1317  scope.send_events();
1318  return OK(pin_group);
1319  }
1320 
1322  const std::vector<ModulePin*> pins,
1324  PinType type,
1325  bool ascending,
1326  u32 start_index,
1327  bool delete_empty_groups,
1328  bool force_name)
1329  {
1330  return create_pin_group(get_unique_pin_group_id(), name, pins, direction, type, ascending, start_index, delete_empty_groups, force_name);
1331  }
1332 
1334  {
1335  PinChangedEventScope scope(this);
1336  if (pin_group == nullptr)
1337  {
1338  log_warning("module", "could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1339  return false;
1340  }
1341 
1342  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1343  {
1344  log_warning(
1345  "module", "could not delete pin group '{}' with ID {} from module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1346  return false;
1347  }
1348 
1349  std::vector<ModulePin*> pins_copy = pin_group->get_pins();
1350  for (ModulePin* pin : pins_copy)
1351  {
1352  auto res = create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, false);
1353  if (res.is_error())
1354  {
1355  return false;
1356  }
1357  PinChangedEvent(this, PinEvent::GroupCreate, res.get()->get_id()).send();
1358  PinChangedEvent(this, PinEvent::PinAssignToGroup, pin->get_id()).send();
1359  }
1360 
1361  u32 pin_group_id_to_delete = pin_group->get_id();
1362 
1363  if (!delete_pin_group_internal(pin_group))
1364  {
1365  return false;
1366  }
1367 
1368  PinChangedEvent(this, PinEvent::GroupDelete, pin_group_id_to_delete).send();
1369  scope.send_events();
1370  return true;
1371  }
1372 
1373  bool Module::move_pin_group(PinGroup<ModulePin>* pin_group, u32 new_index)
1374  {
1375  if (pin_group == nullptr)
1376  {
1377  log_warning("module", "could not move pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1378  return false;
1379  }
1380 
1381  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1382  {
1383  log_warning(
1384  "module", "could not move pin group '{}' with ID {} within module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1385  return false;
1386  }
1387 
1388  if (new_index >= m_pin_groups_ordered.size())
1389  {
1390  log_warning("module", "could not move pin group '{}' with ID {} of module '{}' with ID {}: index {} is out of bounds", pin_group->get_name(), pin_group->get_id(), m_name, m_id, new_index);
1391  return false;
1392  }
1393 
1394  auto src_it = std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group);
1395  auto dst_it = m_pin_groups_ordered.begin();
1396  std::advance(dst_it, new_index);
1397  if (src_it == dst_it)
1398  {
1399  return true;
1400  }
1401  else if (std::distance(m_pin_groups_ordered.begin(), src_it) < std::distance(m_pin_groups_ordered.begin(), dst_it))
1402  {
1403  std::advance(dst_it, 1);
1404  m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1405  }
1406  else
1407  {
1408  m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1409  }
1410 
1411  PinChangedEvent(this, PinEvent::GroupReorder, pin_group->get_id()).send();
1412  return true;
1413  }
1414 
1415  bool Module::assign_pin_to_group(PinGroup<ModulePin>* pin_group, ModulePin* pin, bool delete_empty_groups)
1416  {
1417  PinChangedEventScope scope(this);
1418 
1419  if (pin_group == nullptr)
1420  {
1421  log_warning("module", "could not assign pin to pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1422  return false;
1423  }
1424 
1425  if (pin == nullptr)
1426  {
1427  log_warning("module", "could not assign pin to pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1428  return false;
1429  }
1430 
1431  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1432  {
1433  log_warning("module",
1434  "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1435  pin->get_name(),
1436  pin->get_id(),
1437  pin_group->get_name(),
1438  pin_group->get_id(),
1439  m_name,
1440  m_id);
1441  return false;
1442  }
1443 
1444  if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1445  {
1446  log_warning("module",
1447  "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1448  pin->get_name(),
1449  pin->get_id(),
1450  pin_group->get_name(),
1451  pin_group->get_id(),
1452  m_name,
1453  m_id);
1454  return false;
1455  }
1456 
1457  if (pin_group->contains_pin(pin))
1458  {
1459  return true;
1460  }
1461 
1462  if (PinGroup<ModulePin>* pg = pin->get_group().first; pg != nullptr)
1463  {
1464  // remove from old group and potentially delete old group if empty
1465  if (!pg->remove_pin(pin))
1466  {
1467  log_warning("module",
1468  "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to remove pin from pin group '{}' with ID {}",
1469  pin->get_name(),
1470  pin->get_id(),
1471  pin_group->get_name(),
1472  pin_group->get_id(),
1473  m_name,
1474  m_id,
1475  pg->get_name(),
1476  pg->get_id());
1477  return false;
1478  }
1479 
1480  if (delete_empty_groups && pg->empty())
1481  {
1482  PinChangedEvent(this, PinEvent::GroupDelete, pg->get_id()).send();
1483  if (!delete_pin_group_internal(pg))
1484  {
1485  log_warning("module",
1486  "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to delete pin group '{}' with ID {}",
1487  pin->get_name(),
1488  pin->get_id(),
1489  pin_group->get_name(),
1490  pin_group->get_id(),
1491  m_name,
1492  m_id,
1493  pg->get_name(),
1494  pg->get_id());
1495  return false;
1496  }
1497  }
1498  }
1499 
1500  if (!pin_group->assign_pin(pin))
1501  {
1502  log_warning("module",
1503  "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}",
1504  pin->get_name(),
1505  pin->get_id(),
1506  pin_group->get_name(),
1507  pin_group->get_id(),
1508  m_name,
1509  m_id);
1510  return false;
1511  }
1512 
1514  scope.send_events();
1515  return true;
1516  ;
1517  }
1518 
1520  {
1521  if (pin_group == nullptr)
1522  {
1523  log_warning("module", "could not move pin within pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1524  return false;
1525  }
1526 
1527  if (pin == nullptr)
1528  {
1529  log_warning("module", "could not move pin within pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1530  return false;
1531  }
1532 
1533  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1534  {
1535  log_warning("module",
1536  "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1537  pin->get_name(),
1538  pin->get_id(),
1539  pin_group->get_name(),
1540  pin_group->get_id(),
1541  m_name,
1542  m_id);
1543  return false;
1544  }
1545 
1546  if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1547  {
1548  log_warning("module",
1549  "could not move pin '{}' with ID {} within pin group '{}' with return ERRID {} of module '{}' with ID {}: pin does not belong to module",
1550  pin->get_name(),
1551  pin->get_id(),
1552  pin_group->get_name(),
1553  pin_group->get_id(),
1554  m_name,
1555  m_id);
1556  return false;
1557  }
1558 
1559  if (auto res = pin_group->move_pin(pin, new_index); res.is_error())
1560  {
1561  log_warning("module",
1562  "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}",
1563  pin->get_name(),
1564  pin->get_id(),
1565  pin_group->get_name(),
1566  pin_group->get_id(),
1567  m_name,
1568  m_id);
1569  return false;
1570  }
1571 
1573  return true;
1574  }
1575 
1576  bool Module::remove_pin_from_group(PinGroup<ModulePin>* pin_group, ModulePin* pin, bool delete_empty_groups)
1577  {
1578  if (pin_group == nullptr)
1579  {
1580  log_warning("module", "could not remove pin from pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1581  return false;
1582  }
1583 
1584  if (pin == nullptr)
1585  {
1586  log_warning("module", "could not remove pin from pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1587  return false;
1588  }
1589 
1590  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1591  {
1592  log_warning("module",
1593  "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1594  pin->get_name(),
1595  pin->get_id(),
1596  pin_group->get_name(),
1597  pin_group->get_id(),
1598  m_name,
1599  m_id);
1600  return false;
1601  }
1602 
1603  if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1604  {
1605  log_warning("module",
1606  "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1607  pin->get_name(),
1608  pin->get_id(),
1609  pin_group->get_name(),
1610  pin_group->get_id(),
1611  m_name,
1612  m_id);
1613  return false;
1614  }
1615 
1616  if (auto res = create_pin_group(get_unique_pin_group_id(), pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, delete_empty_groups); res.is_error())
1617  {
1618  log_warning("module",
1619  "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID : unable to create new pin group for pin",
1620  pin->get_name(),
1621  pin->get_id(),
1622  pin_group->get_name(),
1623  pin_group->get_id(),
1624  m_name,
1625  m_id);
1626  return false;
1627  }
1628 
1629  return true;
1630  }
1631 
1632  bool Module::assign_pin_net(const u32 pin_id, Net* net, PinDirection direction)
1633  {
1634  PinChangedEventScope scope(this);
1635  std::string port_prefix;
1636  u32 ctr = 0;
1637  switch (direction)
1638  {
1639  case PinDirection::input:
1640  port_prefix = "I";
1641  break;
1642  case PinDirection::inout:
1643  port_prefix = "IO";
1644  break;
1645  case PinDirection::output:
1646  port_prefix = "O";
1647  break;
1648  default:
1649  log_warning("module", "could not assign pin to net ID {}: invalid pin direction '{}'", net->get_id(), enum_to_string(direction));
1650  return false;
1651  }
1652 
1653  std::string name_internal;
1654  do
1655  {
1656  name_internal = port_prefix + "(" + std::to_string(ctr) + ")";
1657  ctr++;
1658  } while (m_pin_names_map.find(name_internal) != m_pin_names_map.end() || m_pin_group_names_map.find(name_internal) != m_pin_group_names_map.end());
1659 
1660  // create pin
1661  ModulePin* pin;
1662  if (auto res = create_pin_internal(pin_id, name_internal, net, direction, PinType::none, false); res.is_error())
1663  {
1664  log_warning("module", "could not assign pin '{}' to net: failed to create pin", name_internal);
1665  return false;
1666  }
1667  else
1668  {
1669  pin = res.get();
1670  PinChangedEvent(this, PinEvent::PinCreate, pin->get_id()).send();
1671  }
1672 
1673  if (const auto group_res = create_pin_group_internal(get_unique_pin_group_id(), name_internal, pin->get_direction(), pin->get_type(), true, 0, false); group_res.is_error())
1674  {
1675  log_warning("module", "could not assign pin '{}' to net: failed to create pin group", name_internal);
1676  return false;
1677  }
1678  else
1679  {
1680  PinChangedEvent(this, PinEvent::GroupCreate, group_res.get()->get_id()).send();
1681  if (!group_res.get()->assign_pin(pin))
1682  {
1683  log_warning("module", "could not assign pin '{}' to net: failed to assign pin to pin group", name_internal);
1684  return false;
1685  }
1686  else
1687  {
1688  PinChangedEvent(this, PinEvent::PinAssignToGroup, pin->get_id()).send();
1689  }
1690  }
1691 
1692  scope.send_events();
1693  return true;
1694  }
1695 
1696  bool Module::remove_pin_net(Net* net)
1697  {
1698  PinChangedEventScope scope(this);
1699  auto pin = get_pin_by_net(net);
1700  if (pin == nullptr)
1701  {
1702  log_warning("module", "could not remove pin from net: failed to get pin corresponding to net");
1703  return false;
1704  }
1705 
1706  PinGroup<ModulePin>* pin_group = pin->get_group().first;
1707  assert(pin_group != nullptr);
1708 
1709  if (!pin_group->remove_pin(pin))
1710  {
1711  log_warning("module",
1712  "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to remove pin from pin group '{}' with ID {}",
1713  pin->get_name(),
1714  pin->get_id(),
1715  net->get_name(),
1716  net->get_id(),
1717  pin_group->get_name(),
1718  pin_group->get_id());
1719  return false;
1720  }
1721 
1722  if (pin_group->empty())
1723  {
1724  PinChangedEvent(this, PinEvent::GroupDelete, pin_group->get_id()).send();
1725  if (!delete_pin_group_internal(pin_group))
1726  {
1727  log_warning("module",
1728  "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}",
1729  pin->get_name(),
1730  pin->get_id(),
1731  net->get_name(),
1732  net->get_id(),
1733  pin_group->get_name(),
1734  pin_group->get_id());
1735  return false;
1736  }
1737  }
1738 
1739  u32 pin_id_to_delete = pin->get_id();
1740 
1741  if (!delete_pin_internal(pin))
1742  {
1743  log_warning("module",
1744  "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin '{}' with ID {}",
1745  pin->get_name(),
1746  pin->get_id(),
1747  net->get_name(),
1748  net->get_id(),
1749  pin->get_name(),
1750  pin->get_id());
1751  return false;
1752  }
1753 
1754  PinChangedEvent(this, PinEvent::PinDelete, pin_id_to_delete).send();
1755  scope.send_events();
1756  return true;
1757  }
1758 
1759  Result<ModulePin*> Module::create_pin_internal(const u32 id, const std::string& name, Net* net, PinDirection direction, PinType type, bool force_name)
1760  {
1761  // some sanity checks
1762  if (id == 0)
1763  {
1764  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": ID 0 is invalid");
1765  }
1766  if (m_used_pin_ids.find(id) != m_used_pin_ids.end())
1767  {
1768  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": ID " + std::to_string(id) + " is already taken");
1769  }
1770  if (const auto pin_it = m_pin_names_map.find(name); pin_it != m_pin_names_map.end())
1771  {
1772  if (force_name)
1773  {
1774  u32 ctr = 2;
1775  while (!this->set_pin_name(pin_it->second, name + "__" + std::to_string(ctr) + "__"))
1776  {
1777  ctr++;
1778  }
1779  }
1780  else
1781  {
1782  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": name '" + name + "' is already taken");
1783  }
1784  }
1785  if (net == nullptr)
1786  {
1787  return ERR("could not create pin '" + name + "' for gate type '" + m_name + "' with ID " + std::to_string(m_id) + ": net is a 'nullptr'");
1788  }
1790  {
1791  return ERR("could not create pin '" + name + "' for module '" + m_name + "' with " + std::to_string(m_id) + ": direction '" + enum_to_string(direction) + "' is invalid");
1792  }
1793 
1794  // create pin
1795  std::unique_ptr<ModulePin> pin_owner(new ModulePin(id, name, net, direction, type));
1796  ModulePin* pin = pin_owner.get();
1797  m_pins.push_back(std::move(pin_owner));
1798  m_pins_map[id] = pin;
1799  m_pin_names_map[name] = pin;
1800  m_pin_nets_map[net] = pin;
1801 
1802  // mark pin ID as used
1803  if (auto free_id_it = m_free_pin_ids.find(id); free_id_it != m_free_pin_ids.end())
1804  {
1805  m_free_pin_ids.erase(free_id_it);
1806  }
1807  m_used_pin_ids.insert(id);
1808 
1809  return OK(pin);
1810  }
1811 
1812  bool Module::delete_pin_internal(ModulePin* pin)
1813  {
1814  // some sanity checks
1815  if (pin == nullptr)
1816  {
1817  log_warning("module", "could not delete pin of gate type '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1818  return false;
1819  }
1820  if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1821  {
1822  log_warning("module", "could not delete pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), m_name, m_id);
1823  return false;
1824  }
1825 
1826  // erase pin
1827  u32 del_id = pin->get_id();
1828  const std::string& del_name = pin->get_name();
1829  m_pins_map.erase(del_id);
1830  m_pin_names_map.erase(del_name);
1831  m_pin_nets_map.erase(pin->get_net());
1832  m_pins.erase(std::find_if(m_pins.begin(), m_pins.end(), [pin](const auto& p) { return p.get() == pin; }));
1833 
1834  // free pin ID
1835  m_free_pin_ids.insert(del_id);
1836  m_used_pin_ids.erase(del_id);
1837 
1838  return true;
1839  }
1840 
1841  Result<PinGroup<ModulePin>*> Module::create_pin_group_internal(const u32 id, const std::string& name, PinDirection direction, PinType type, bool ascending, u32 start_index, bool force_name)
1842  {
1843  // some sanity checks
1844  if (id == 0)
1845  {
1846  return ERR("could not create pin group '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": ID 0 is invalid");
1847  }
1848  if (m_used_pin_group_ids.find(id) != m_used_pin_group_ids.end())
1849  {
1850  return ERR("could not create pin group '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": ID " + std::to_string(id) + " is already taken");
1851  }
1852  if (const auto pin_group_it = m_pin_group_names_map.find(name); pin_group_it != m_pin_group_names_map.end())
1853  {
1854  if (force_name)
1855  {
1856  u32 ctr = 2;
1857  while (!this->set_pin_group_name(pin_group_it->second, name + "__" + std::to_string(ctr) + "__"))
1858  {
1859  ctr++;
1860  }
1861  PinChangedEvent(this, PinEvent::GroupRename, pin_group_it->second->get_id()).send();
1862  }
1863  else
1864  {
1865  return ERR("could not create pin group '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": name '" + name + "' is already taken");
1866  }
1867  }
1868 
1869  // create pin group
1870  std::unique_ptr<PinGroup<ModulePin>> pin_group_owner = std::make_unique<PinGroup<ModulePin>>(id, name, direction, type, ascending, start_index);
1871  m_pin_groups.push_back(std::move(pin_group_owner));
1872  PinGroup<ModulePin>* pin_group = m_pin_groups.back().get();
1873  m_pin_groups_ordered.push_back(pin_group);
1874  m_pin_groups_map[id] = pin_group;
1875  m_pin_group_names_map[name] = pin_group;
1876 
1877  // mark pin group ID as used
1878  if (auto free_id_it = m_free_pin_group_ids.find(id); free_id_it != m_free_pin_group_ids.end())
1879  {
1880  m_free_pin_group_ids.erase(free_id_it);
1881  }
1882  m_used_pin_group_ids.insert(id);
1883 
1884  return OK(pin_group);
1885  }
1886 
1887  bool Module::delete_pin_group_internal(PinGroup<ModulePin>* pin_group)
1888  {
1889  // some sanity checks
1890  if (pin_group == nullptr)
1891  {
1892  log_warning("module", "could not delete pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1893  return false;
1894  }
1895  if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1896  {
1897  log_warning(
1898  "module", "could not delete pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1899  return false;
1900  }
1901 
1902  // erase pin group
1903  u32 del_id = pin_group->get_id();
1904  const std::string& del_name = pin_group->get_name();
1905  m_pin_groups_map.erase(del_id);
1906  m_pin_group_names_map.erase(del_name);
1907  m_pin_groups_ordered.erase(std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group));
1908  m_pin_groups.erase(std::find_if(m_pin_groups.begin(), m_pin_groups.end(), [pin_group](const auto& pg) { return pg.get() == pin_group; }));
1909 
1910  // free pin group ID
1911  m_free_pin_group_ids.insert(del_id);
1912  m_used_pin_group_ids.erase(del_id);
1913 
1914  return true;
1915  }
1916 
1918  {
1919  return m_event_handler;
1920  }
1921 } // namespace hal
void set_name(const std::string &name)
Definition: base_pin.h:100
const std::string & get_name() const
Definition: base_pin.h:110
void set_type(PinType type)
Definition: base_pin.h:140
u32 get_id() const
Definition: base_pin.h:90
PinType get_type() const
Definition: base_pin.h:150
const std::pair< PinGroup< T > *, i32 > & get_group() const
Definition: base_pin.h:160
PinDirection get_direction() const
Definition: base_pin.h:130
void notify(NetlistEvent::event ev, Netlist *netlist, u32 associated_data=0xFFFFFFFF)
Definition: gate.h:58
@ submodule_removed
associated_data = id of removed module
@ type_changed
no associated_data
@ submodule_added
associated_data = id of added module
@ parent_changed
no associated_data
@ name_changed
no associated_data
bool is_input_net(Net *net) const
Definition: module.cpp:564
void set_name(const std::string &name)
Definition: module.cpp:93
const std::unordered_set< Net * > & get_nets() const
Definition: module.cpp:512
void update_nets()
Definition: module.cpp:443
std::vector< std::string > get_pin_names(const std::function< bool(ModulePin *)> &filter=nullptr) const
Definition: module.cpp:908
PinGroup< ModulePin > * get_pin_group_by_name(const std::string &name) const
Definition: module.cpp:1060
bool move_pin_within_group(PinGroup< ModulePin > *pin_group, ModulePin *pin, u32 new_index)
Definition: module.cpp:1519
Module * get_parent_module() const
Definition: module.cpp:126
bool is_parent_module_of(const Module *module, bool recursive=false) const
Definition: module.cpp:243
std::vector< ModulePin * > get_output_pins() const
Definition: module.cpp:955
bool set_parent_module(Module *new_parent)
Definition: module.cpp:171
bool remove_gate(Gate *gate)
Definition: module.cpp:341
std::vector< ModulePin * > get_pins(const std::function< bool(ModulePin *)> &filter=nullptr) const
Definition: module.cpp:880
std::vector< ModulePin * > get_input_pins() const
Definition: module.cpp:939
bool assign_gates(const std::vector< Gate * > &gates)
Definition: module.cpp:336
bool contains_net(Net *net, bool recursive=false) const
Definition: module.cpp:492
bool operator==(const Module &other) const
Definition: module.cpp:27
Gate * get_gate_by_id(const u32 id, bool recursive=false) const
Definition: module.cpp:379
const std::unordered_set< Net * > & get_internal_nets() const
Definition: module.cpp:559
ModulePin * get_pin_by_name(const std::string &name) const
Definition: module.cpp:1009
bool assign_pin_to_group(PinGroup< ModulePin > *pin_group, ModulePin *pin, bool delete_empty_groups=true)
Definition: module.cpp:1415
int get_submodule_depth() const
Definition: module.cpp:160
bool remove_pin_from_group(PinGroup< ModulePin > *pin_group, ModulePin *pin, bool delete_empty_groups=true)
Definition: module.cpp:1576
bool is_top_module() const
Definition: module.cpp:321
bool remove_gates(const std::vector< Gate * > &gates)
Definition: module.cpp:346
ModulePin * get_pin_by_id(const u32 id) const
Definition: module.cpp:992
bool set_pin_group_type(PinGroup< ModulePin > *pin_group, PinType new_type)
Definition: module.cpp:1210
bool set_pin_type(ModulePin *pin, PinType new_type)
Definition: module.cpp:1131
bool assign_gate(Gate *gate)
Definition: module.cpp:331
bool is_output_net(Net *net) const
Definition: module.cpp:574
bool delete_pin_group(PinGroup< ModulePin > *pin_group)
Definition: module.cpp:1333
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:400
bool move_pin_group(PinGroup< ModulePin > *pin_group, u32 new_index)
Definition: module.cpp:1373
Result< PinGroup< ModulePin > * > create_pin_group(const u32 id, const std::string &name, const std::vector< ModulePin * > pins={}, PinDirection direction=PinDirection::none, PinType type=PinType::none, bool ascending=false, u32 start_index=0, bool delete_empty_groups=true, bool force_name=false)
Definition: module.cpp:1260
bool set_pin_name(ModulePin *pin, const std::string &new_name, bool force_name=false)
Definition: module.cpp:1077
std::string get_name() const
Definition: module.cpp:88
Grouping * get_grouping() const
Definition: module.cpp:121
const std::unordered_set< Net * > & get_input_nets() const
Definition: module.cpp:549
std::vector< std::string > get_input_pin_names() const
Definition: module.cpp:947
bool set_pin_group_direction(PinGroup< ModulePin > *pin_group, PinDirection new_direction)
Definition: module.cpp:1233
void set_type(const std::string &type)
Definition: module.cpp:112
u32 get_unique_pin_id()
Definition: module.cpp:770
bool contains_module(const Module *other, bool recursive=false) const
Definition: module.cpp:316
bool operator!=(const Module &other) const
Definition: module.cpp:73
std::vector< Module * > get_parent_modules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=true) const
Definition: module.cpp:131
Netlist * get_netlist() const
Definition: module.cpp:326
ModulePin * get_pin_by_net(Net *net) const
Definition: module.cpp:1026
bool set_pin_group_name(PinGroup< ModulePin > *pin_group, const std::string &new_name, bool force_name=false)
Definition: module.cpp:1154
EventHandler * get_event_handler() const
Definition: module.cpp:1917
std::vector< PinGroup< ModulePin > * > get_pin_groups(const std::function< bool(PinGroup< ModulePin > *)> &filter=nullptr) const
Definition: module.cpp:971
Result< ModulePin * > create_pin(const u32 id, const std::string &name, Net *net, PinType type=PinType::none, bool create_group=true, bool force_name=false)
Definition: module.cpp:796
PinGroup< ModulePin > * get_pin_group_by_id(const u32 id) const
Definition: module.cpp:1043
ssize_t get_hash() const
Definition: module.cpp:78
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
Definition: module.cpp:268
std::vector< std::string > get_output_pin_names() const
Definition: module.cpp:963
bool contains_gate(Gate *gate, bool recursive=false) const
Definition: module.cpp:359
std::string get_type() const
Definition: module.cpp:107
bool is_internal_net(Net *net) const
Definition: module.cpp:584
bool is_submodule_of(const Module *module, bool recursive=false) const
Definition: module.cpp:298
const std::unordered_set< Net * > & get_output_nets() const
Definition: module.cpp:554
u32 get_id() const
Definition: module.cpp:83
u32 get_unique_pin_group_id()
Definition: module.cpp:783
Definition: net.h:58
Module * get_top_module() const
Definition: netlist.cpp:610
u32 get_id() const
Definition: netlist.cpp:77
bool assign_pin(T *pin)
Definition: pin_group.h:373
std::vector< T * > get_pins(const std::function< bool(T *)> &filter=nullptr) const
Definition: pin_group.h:205
Result< std::monostate > move_pin(T *pin, i32 new_index)
Definition: pin_group.h:403
void set_direction(PinDirection direction)
Definition: pin_group.h:183
bool contains_pin(T *pin)
Definition: pin_group.h:530
u32 get_id() const
Definition: pin_group.h:133
const std::string & get_name() const
Definition: pin_group.h:153
void set_name(const std::string &name)
Definition: pin_group.h:143
PinDirection get_direction() const
Definition: pin_group.h:193
void set_type(PinType type)
Definition: pin_group.h:163
PinType get_type() const
Definition: pin_group.h:173
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
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
#define ERR_APPEND(prev_error, message)
Definition: result.h:64
const Module * module(const Gate *g, const NodeBoxes &boxes)
void indexed_vector_push_back(std::vector< T > &vec, std::unordered_map< T, u32 > &positions, T element)
Definition: utils.h:81
bool indexed_vector_erase(std::vector< T > &vec, std::unordered_map< T, u32 > &positions, T element)
Definition: utils.h:97
T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:404
Definition: defines.h:45
PinDirection
Definition: pin_direction.h:36
@ PinTypeChange
pin renamed
@ GroupReorder
changed PinDirection attribute of group (like input)
@ PinCreate
moved group to a new position within containing module
@ GroupTypeChange
pin group renamed
@ PinRename
pin assigned to new group
@ PinAssignToGroup
new pin created
@ PinDelete
moved pin to a new position within containing group
@ GroupRename
new pin group created
@ GroupDelete
pin deleted
@ GroupDirChange
changed PinType attribute of group (like data)
@ PinReorder
changed PinDirection attribute of pin (like input)
PinType
Definition: pin_type.h:36
std::string enum_to_string(T e)
Definition: enums.h:53
PinType type
std::vector< PinInformation > pins
Net * net
u32 start_index
bool ascending
PinDirection direction
std::string name
i32 id