13 Module::Module(NetlistInternalManager* internal_manager, EventHandler* event_handler,
u32 id, Module* parent,
const std::string&
name)
15 m_internal_manager = internal_manager;
21 m_next_pin_group_id = 1;
23 m_event_handler = event_handler;
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());
38 if (
const auto it = m_submodules_map.find(other_module->get_id()); it == m_submodules_map.end() || *it->second != *other_module)
40 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal submodules.", m_id, other.
get_id());
47 if (
const auto it = m_gates_map.find(other_gate->get_id()); it == m_gates_map.end() || *it->second != *other_gate)
49 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal gates.", m_id, other.
get_id());
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)
58 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal pin group.", m_id, other.
get_id());
63 if (!DataContainer::operator==(other))
65 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to unequal data.", m_id, other.
get_id());
79 return (uintptr_t)
this;
96 log_warning(
"module",
"module name cannot be empty.");
132 std::vector<Module*> res;
133 if (m_parent ==
nullptr)
140 res.push_back(m_parent);
144 if (filter(m_parent))
146 res.push_back(m_parent);
153 res.reserve(res.size() + more.size());
154 res.insert(res.end(), more.begin(), more.end());
172 if (new_parent ==
this)
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());
178 if (m_parent ==
nullptr)
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());
184 if (new_parent ==
nullptr)
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());
190 if (!
get_netlist()->is_module_in_netlist(new_parent))
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());
197 if (std::find(children.begin(), children.end(), new_parent) != children.end())
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));
205 if (m_internal_manager->m_net_checks_enabled)
209 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
211 log_error(
"module",
"{}", res.get_error().get());
218 m_parent = new_parent;
220 m_parent->m_submodules_map[m_id] =
this;
221 m_parent->m_submodules.push_back(
this);
223 if (m_internal_manager->m_net_checks_enabled)
227 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
229 log_error(
"module",
"{}", res.get_error().get());
246 for (
auto sm : m_submodules)
252 else if (recursive && sm->is_parent_module_of(
module,
true))
263 std::vector<Module*> res;
270 for (
auto sm : m_submodules)
281 for (
auto sm : m_submodules)
283 auto more = sm->get_submodules(filter,
true);
284 res.reserve(res.size() + more.size());
285 res.insert(res.end(), more.begin(), more.end());
316 return m_parent ==
nullptr;
321 return m_internal_manager->m_netlist;
326 return m_internal_manager->module_assign_gates(
this, {gate});
331 return m_internal_manager->module_assign_gates(
this, gates);
341 for (
Gate* gate : gates)
349 return m_internal_manager->module_assign_gates(m_internal_manager->m_netlist->
get_top_module(), gates);
358 bool success = std::find(m_gates.begin(), m_gates.end(), gate) != m_gates.end();
359 if (!success && recursive)
361 for (
auto sm : m_submodules)
363 if (sm->contains_gate(gate,
true))
374 auto it = m_gates_map.find(gate_id);
375 if (it == m_gates_map.end())
379 for (
auto sm : m_submodules)
381 auto res = sm->get_gate_by_id(gate_id,
true);
400 std::vector<Gate*> res;
407 for (
auto g : m_gates)
419 for (
auto sm : m_submodules)
421 auto more = sm->get_gates(filter,
true);
422 res.reserve(res.size() + more.size());
423 res.insert(res.end(), more.begin(), more.end());
439 m_input_nets.clear();
440 m_output_nets.clear();
441 m_internal_nets.clear();
443 std::unordered_set<Net*> net_cache;
446 for (
Net*
net : gate->get_fan_in_nets())
448 net_cache.insert(
net);
450 for (
Net*
net : gate->get_fan_out_nets())
452 net_cache.insert(
net);
456 for (
Net*
net : net_cache)
458 NetConnectivity con = check_net_endpoints(
net);
459 if (con.has_internal_source || con.has_internal_destination)
463 if (con.has_internal_source && con.has_internal_destination)
465 m_internal_nets.insert(
net);
468 if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
470 m_input_nets.insert(
net);
471 m_output_nets.insert(
net);
473 else if (con.has_external_source && con.has_internal_destination)
475 m_input_nets.insert(
net);
477 else if (con.has_internal_source && con.has_external_destination)
479 m_output_nets.insert(
net);
491 bool success = m_nets.find(
net) != m_nets.end();
492 if (!success && recursive)
494 for (
auto sm : m_submodules)
496 if (sm->contains_net(
net,
true))
512 std::unordered_set<Net*> res;
519 for (
Net*
n : m_nets)
531 for (
auto sm : m_submodules)
533 auto more = sm->get_nets(filter,
true);
534 res.reserve(res.size() + more.size());
535 res.insert(more.begin(), more.end());
549 return m_output_nets;
554 return m_internal_nets;
564 return m_input_nets.find(
net) != m_input_nets.end();
574 return m_output_nets.find(
net) != m_output_nets.end();
584 return m_internal_nets.find(
net) != m_internal_nets.end();
587 Module::NetConnectivity Module::check_net_endpoints(
const Net*
net)
const
589 std::vector<Endpoint*> sources =
net->get_sources();
590 std::vector<Endpoint*> destinations =
net->get_destinations();
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;
602 res.has_external_source =
true;
606 res.has_internal_source =
true;
609 if (res.has_external_source && res.has_internal_source)
615 for (Endpoint* ep : destinations)
617 if (Module* mod = ep->get_gate()->get_module();
this != mod && !
is_parent_module_of(mod,
true))
619 res.has_external_destination =
true;
623 res.has_internal_destination =
true;
626 if (res.has_external_destination && res.has_internal_destination)
635 Result<std::monostate> Module::check_net(Net*
net,
bool recursive)
637 NetConnectivity con = check_net_endpoints(
net);
638 if (con.has_internal_source && con.has_internal_destination)
640 m_internal_nets.insert(
net);
644 m_internal_nets.erase(
net);
647 if (con.has_internal_source || con.has_internal_destination)
656 if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
663 m_output_nets.insert(
net);
669 m_input_nets.insert(
net);
678 return ERR(
"could not assign inout pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
682 else if (con.has_external_source && con.has_internal_destination)
686 const auto direction = pin->get_direction();
689 m_input_nets.insert(
net);
690 m_output_nets.erase(
net);
697 m_input_nets.insert(
net);
700 return ERR(
"could not assign input pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
704 else if (con.has_internal_source && con.has_external_destination)
708 const auto direction = pin->get_direction();
711 m_output_nets.insert(
net);
712 m_input_nets.erase(
net);
719 m_output_nets.insert(
net);
722 return ERR(
"could not assign output pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
733 m_input_nets.erase(
net);
737 m_output_nets.erase(
net);
739 if (!remove_pin_net(
net))
741 return ERR(
"Remove pin net failed");
746 if (m_internal_manager->m_net_checks_enabled && recursive && m_parent !=
nullptr)
748 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
765 if (!m_free_pin_ids.empty())
767 return *(m_free_pin_ids.begin());
769 while (m_used_pin_ids.find(m_next_pin_id) != m_used_pin_ids.end())
773 return m_next_pin_id;
778 if (!m_free_pin_group_ids.empty())
780 return *(m_free_pin_group_ids.begin());
782 while (m_used_pin_group_ids.find(m_next_pin_group_id) != m_used_pin_group_ids.end())
784 m_next_pin_group_id++;
786 return m_next_pin_group_id;
793 return ERR(
"could not create pin for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": empty string passed as name");
796 if (m_internal_manager->m_net_checks_enabled)
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.");
805 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": net is a 'nullptr'");
812 if (is_input && is_output)
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");
830 if (
auto pin_res = create_pin_internal(
id,
name,
net,
direction,
type, force_name); pin_res.is_error())
832 return ERR_APPEND(pin_res.get_error(),
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id));
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");
847 if (!group_res.get()->assign_pin(pin_res.get()))
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");
875 std::vector<ModulePin*> res;
878 res.reserve(m_pins.size());
879 for (
const auto& group : m_pin_groups_ordered)
881 std::vector<ModulePin*>
pins = group->get_pins();
882 res.insert(res.end(),
pins.begin(),
pins.end());
903 std::vector<std::string> res;
906 res.reserve(m_pins.size());
907 for (
const auto& group : m_pin_groups_ordered)
909 std::vector<ModulePin*>
pins = group->get_pins();
910 for (
const auto pin : group->get_pins())
912 res.push_back(pin->get_name());
924 res.push_back(pin->get_name());
966 std::vector<PinGroup<ModulePin>*> res;
969 res.reserve(m_pin_groups_ordered.size());
970 res.insert(res.end(), m_pin_groups_ordered.begin(), m_pin_groups_ordered.end());
978 res.push_back(group);
989 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
993 if (
const auto it = m_pins_map.find(
id); it != m_pins_map.end())
998 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: no pin with ID {} exists", m_name, m_id,
id);
1006 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1010 if (
const auto it = m_pin_names_map.find(
name); it != m_pin_names_map.end())
1015 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: no pin with name '{}' exists", m_name, m_id,
name);
1023 log_warning(
"module",
"could not get pin by net for module '{}' with ID {}: net is a 'nullptr'", m_name, m_id);
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())
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());
1040 log_warning(
"module",
"could not get pin group by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
1044 if (
const auto it = m_pin_groups_map.find(
id); it != m_pin_groups_map.end())
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);
1057 log_warning(
"module",
"could not get pin group by name for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1061 if (
const auto it = m_pin_group_names_map.find(
name); it != m_pin_group_names_map.end())
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);
1074 log_warning(
"module",
"could not set name for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1078 if (new_name.empty())
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);
1084 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
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);
1090 if (
const auto pin_it = m_pin_names_map.find(new_name); pin_it != m_pin_names_map.end())
1095 while (!this->
set_pin_name(pin_it->second, new_name +
"__" + std::to_string(ctr) +
"__"))
1103 "could not set name for pin '{}' with ID {} of module '{}' with ID {}: a pin with name '{}' already exists within the module",
1113 if (
const std::string& old_name = pin->
get_name(); old_name != new_name)
1115 m_pin_names_map.erase(old_name);
1117 m_pin_names_map[new_name] = pin;
1128 log_warning(
"module",
"could not set type for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1132 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
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);
1149 if (pin_group ==
nullptr)
1151 log_warning(
"module",
"could not set name for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1155 if (new_name.empty())
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);
1162 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
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);
1169 if (
const auto pin_group_it = m_pin_group_names_map.find(new_name); pin_group_it != m_pin_group_names_map.end())
1174 while (!this->
set_pin_group_name(pin_group_it->second, new_name +
"__" + std::to_string(ctr) +
"__"))
1182 "could not set name for pin group '{}' with ID {} of module '{}' with ID {}: a pin group with name '{}' already exists within the module",
1192 if (
const std::string& old_name = pin_group->
get_name(); old_name != new_name)
1194 m_pin_group_names_map.erase(old_name);
1196 m_pin_group_names_map[new_name] = pin_group;
1205 if (pin_group ==
nullptr)
1207 log_warning(
"module",
"could not set type for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1211 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
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);
1218 if (pin_group->
get_type() != new_type)
1228 if (pin_group ==
nullptr)
1230 log_warning(
"module",
"could not set direction for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1234 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1237 "could not set direction for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1254 const std::string&
name,
1255 const std::vector<ModulePin*>
pins,
1260 bool delete_empty_groups,
1267 return ERR(
"could not create pin group for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": empty string passed as name");
1279 return ERR_APPEND(res.get_error(),
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id));
1283 pin_group = res.get();
1288 for (
auto it =
pins.begin(); it !=
pins.end(); ++it)
1293 return ERR(
"Assign pin to group failed.");
1299 for (
auto it =
pins.rbegin(); it !=
pins.rend(); ++it)
1304 return ERR(
"Assign pin to group failed.");
1311 return OK(pin_group);
1315 const std::vector<ModulePin*>
pins,
1320 bool delete_empty_groups,
1329 if (pin_group ==
nullptr)
1331 log_warning(
"module",
"could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1335 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
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);
1342 std::vector<ModulePin*> pins_copy = pin_group->
get_pins();
1345 auto res =
create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(),
true, 0,
false);
1354 u32 pin_group_id_to_delete = pin_group->
get_id();
1356 if (!delete_pin_group_internal(pin_group))
1368 if (pin_group ==
nullptr)
1370 log_warning(
"module",
"could not move pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1374 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
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);
1381 if (new_index >= m_pin_groups_ordered.size())
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);
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)
1394 else if (std::distance(m_pin_groups_ordered.begin(), src_it) < std::distance(m_pin_groups_ordered.begin(), dst_it))
1396 std::advance(dst_it, 1);
1397 m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1401 m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1412 if (pin_group ==
nullptr)
1414 log_warning(
"module",
"could not assign pin to pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
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);
1424 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1427 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1437 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1440 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1458 if (!pg->remove_pin(pin))
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 {}",
1473 if (delete_empty_groups && pg->empty())
1476 if (!delete_pin_group_internal(pg))
1479 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to delete pin group '{}' with ID {}",
1496 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}",
1514 if (pin_group ==
nullptr)
1516 log_warning(
"module",
"could not move pin within pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
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);
1526 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1529 "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1539 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1542 "could not move pin '{}' with ID {} within pin group '{}' with return ERRID {} of module '{}' with ID {}: pin does not belong to module",
1552 if (
auto res = pin_group->
move_pin(pin, new_index); res.is_error())
1555 "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}",
1571 if (pin_group ==
nullptr)
1573 log_warning(
"module",
"could not remove pin from pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
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);
1583 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1586 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1596 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1599 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to 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",
1628 std::string port_prefix;
1646 std::string name_internal;
1649 name_internal = port_prefix +
"(" + std::to_string(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());
1657 log_warning(
"module",
"could not assign pin '{}' to net: failed to create pin", name_internal);
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())
1668 log_warning(
"module",
"could not assign pin '{}' to net: failed to create pin group", name_internal);
1674 if (!group_res.get()->assign_pin(pin))
1676 log_warning(
"module",
"could not assign pin '{}' to net: failed to assign pin to pin group", name_internal);
1685 scope.send_events();
1689 bool Module::remove_pin_net(Net*
net)
1691 PinChangedEventScope scope(
this);
1695 log_warning(
"module",
"could not remove pin from net: failed to get pin corresponding to net");
1699 PinGroup<ModulePin>* pin_group = pin->get_group().first;
1700 assert(pin_group !=
nullptr);
1702 if (!pin_group->remove_pin(pin))
1705 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to remove pin from pin group '{}' with ID {}",
1710 pin_group->get_name(),
1711 pin_group->get_id());
1715 if (pin_group->empty())
1718 if (!delete_pin_group_internal(pin_group))
1721 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}",
1726 pin_group->get_name(),
1727 pin_group->get_id());
1732 u32 pin_id_to_delete = pin->get_id();
1734 if (!delete_pin_internal(pin))
1737 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin '{}' with ID {}",
1748 scope.send_events();
1757 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID 0 is invalid");
1759 if (m_used_pin_ids.find(
id) != m_used_pin_ids.end())
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");
1763 if (
const auto pin_it = m_pin_names_map.find(
name); pin_it != m_pin_names_map.end())
1768 while (!this->
set_pin_name(pin_it->second,
name +
"__" + std::to_string(ctr) +
"__"))
1775 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": name '" +
name +
"' is already taken");
1780 return ERR(
"could not create pin '" +
name +
"' for gate type '" + m_name +
"' with ID " + std::to_string(m_id) +
": net is a 'nullptr'");
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");
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;
1795 if (
auto free_id_it = m_free_pin_ids.find(
id); free_id_it != m_free_pin_ids.end())
1797 m_free_pin_ids.erase(free_id_it);
1799 m_used_pin_ids.insert(
id);
1804 bool Module::delete_pin_internal(ModulePin* pin)
1809 log_warning(
"module",
"could not delete pin of gate type '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1812 if (
const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
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);
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; }));
1826 m_free_pin_ids.insert(del_id);
1827 m_used_pin_ids.erase(del_id);
1837 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID 0 is invalid");
1839 if (m_used_pin_group_ids.find(
id) != m_used_pin_group_ids.end())
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");
1843 if (
const auto pin_group_it = m_pin_group_names_map.find(
name); pin_group_it != m_pin_group_names_map.end())
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");
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;
1869 if (
auto free_id_it = m_free_pin_group_ids.find(
id); free_id_it != m_free_pin_group_ids.end())
1871 m_free_pin_group_ids.erase(free_id_it);
1873 m_used_pin_group_ids.insert(
id);
1875 return OK(pin_group);
1878 bool Module::delete_pin_group_internal(PinGroup<ModulePin>* pin_group)
1881 if (pin_group ==
nullptr)
1883 log_warning(
"module",
"could not delete pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1886 if (
const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
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);
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; }));
1902 m_free_pin_group_ids.insert(del_id);
1903 m_used_pin_group_ids.erase(del_id);
1910 return m_event_handler;
void set_name(const std::string &name)
const std::string & get_name() const
void set_type(PinType type)
const std::pair< PinGroup< T > *, i32 > & get_group() const
PinDirection get_direction() const
NETLIST_API void notify(NetlistEvent::event ev, Netlist *netlist, u32 associated_data=0xFFFFFFFF)
@ 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
void set_name(const std::string &name)
const std::unordered_set< Net * > & get_nets() const
std::vector< std::string > get_pin_names(const std::function< bool(ModulePin *)> &filter=nullptr) const
PinGroup< ModulePin > * get_pin_group_by_name(const std::string &name) const
bool move_pin_within_group(PinGroup< ModulePin > *pin_group, ModulePin *pin, u32 new_index)
Module * get_parent_module() const
bool is_parent_module_of(const Module *module, bool recursive=false) const
std::vector< ModulePin * > get_output_pins() const
bool set_parent_module(Module *new_parent)
bool remove_gate(Gate *gate)
std::vector< ModulePin * > get_pins(const std::function< bool(ModulePin *)> &filter=nullptr) const
std::vector< ModulePin * > get_input_pins() const
bool assign_gates(const std::vector< Gate * > &gates)
bool contains_net(Net *net, bool recursive=false) const
bool operator==(const Module &other) const
Gate * get_gate_by_id(const u32 id, bool recursive=false) const
const std::unordered_set< Net * > & get_internal_nets() const
ModulePin * get_pin_by_name(const std::string &name) const
bool assign_pin_to_group(PinGroup< ModulePin > *pin_group, ModulePin *pin, bool delete_empty_groups=true)
int get_submodule_depth() const
bool remove_pin_from_group(PinGroup< ModulePin > *pin_group, ModulePin *pin, bool delete_empty_groups=true)
bool is_top_module() const
bool remove_gates(const std::vector< Gate * > &gates)
ModulePin * get_pin_by_id(const u32 id) const
bool set_pin_group_type(PinGroup< ModulePin > *pin_group, PinType new_type)
bool set_pin_type(ModulePin *pin, PinType new_type)
bool assign_gate(Gate *gate)
bool is_output_net(Net *net) const
bool delete_pin_group(PinGroup< ModulePin > *pin_group)
const std::vector< Gate * > & get_gates() const
bool move_pin_group(PinGroup< ModulePin > *pin_group, u32 new_index)
bool set_pin_name(ModulePin *pin, const std::string &new_name, bool force_name=false)
std::string get_name() const
Grouping * get_grouping() const
const std::unordered_set< Net * > & get_input_nets() const
std::vector< std::string > get_input_pin_names() const
bool set_pin_group_direction(PinGroup< ModulePin > *pin_group, PinDirection new_direction)
void set_type(const std::string &type)
bool contains_module(const Module *other, bool recursive=false) const
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)
bool operator!=(const Module &other) const
std::vector< Module * > get_parent_modules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=true) const
Netlist * get_netlist() const
ModulePin * get_pin_by_net(Net *net) const
bool set_pin_group_name(PinGroup< ModulePin > *pin_group, const std::string &new_name, bool force_name=false)
EventHandler * get_event_handler() const
std::vector< PinGroup< ModulePin > * > get_pin_groups(const std::function< bool(PinGroup< ModulePin > *)> &filter=nullptr) const
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)
PinGroup< ModulePin > * get_pin_group_by_id(const u32 id) const
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
std::vector< std::string > get_output_pin_names() const
bool contains_gate(Gate *gate, bool recursive=false) const
std::string get_type() const
bool is_internal_net(Net *net) const
bool is_submodule_of(const Module *module, bool recursive=false) const
const std::unordered_set< Net * > & get_output_nets() const
u32 get_unique_pin_group_id()
Module * get_top_module() const
std::vector< T * > get_pins(const std::function< bool(T *)> &filter=nullptr) const
Result< std::monostate > move_pin(T *pin, i32 new_index)
void set_direction(PinDirection direction)
bool contains_pin(T *pin)
const std::string & get_name() const
void set_name(const std::string &name)
PinDirection get_direction() const
void set_type(PinType type)
#define log_error(channel,...)
#define log_debug(channel,...)
#define log_warning(channel,...)
#define ERR_APPEND(prev_error, message)
const Module * module(const Gate *g, const NodeBoxes &boxes)
CORE_API T trim(const T &s, const char *to_remove=" \t\r\n")
@ 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
@ PinReorder
changed PinDirection attribute of pin (like input)
std::string enum_to_string(T e)
std::vector< PinInformation > pins