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