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