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());
170 if (new_parent ==
this)
172 log_error(
"module",
"module '{}' with ID {} in netlist with ID {} cannot be its own parent module.", m_name, m_id, m_internal_manager->m_netlist->
get_id());
176 if (m_parent ==
nullptr)
178 log_error(
"module",
"no parent module can be assigned to top module '{}' with ID {} in netlist with ID {}.", m_name, m_id, m_internal_manager->m_netlist->
get_id());
182 if (new_parent ==
nullptr)
184 log_error(
"module",
"module '{}' with ID {} in netlist with ID {} cannot be assigned to be the top module.", m_name, m_id, m_internal_manager->m_netlist->
get_id());
188 if (!
get_netlist()->is_module_in_netlist(new_parent))
190 log_error(
"module",
"module '{}' with ID {} is not contained in netlist with ID {}.", new_parent->
get_name(), new_parent->
get_id(), m_internal_manager->m_netlist->
get_id());
195 if (std::find(children.begin(), children.end(), new_parent) != children.end())
200 m_parent->m_submodules_map.erase(m_id);
201 m_parent->m_submodules.erase(std::find(m_parent->m_submodules.begin(), m_parent->m_submodules.end(),
this));
203 if (m_internal_manager->m_net_checks_enabled)
207 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
209 log_error(
"module",
"{}", res.get_error().get());
216 m_parent = new_parent;
218 m_parent->m_submodules_map[m_id] =
this;
219 m_parent->m_submodules.push_back(
this);
221 if (m_internal_manager->m_net_checks_enabled)
225 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
227 log_error(
"module",
"{}", res.get_error().get());
244 for (
auto sm : m_submodules)
250 else if (recursive && sm->is_parent_module_of(
module,
true))
261 std::vector<Module*> res;
268 for (
auto sm : m_submodules)
279 for (
auto sm : m_submodules)
281 auto more = sm->get_submodules(filter,
true);
282 res.reserve(res.size() + more.size());
283 res.insert(res.end(), more.begin(), more.end());
314 return m_parent ==
nullptr;
319 return m_internal_manager->m_netlist;
324 return m_internal_manager->module_assign_gates(
this, {gate});
329 return m_internal_manager->module_assign_gates(
this, gates);
339 for (
Gate* gate : gates)
347 return m_internal_manager->module_assign_gates(m_internal_manager->m_netlist->
get_top_module(), gates);
356 bool success = std::find(m_gates.begin(), m_gates.end(), gate) != m_gates.end();
357 if (!success && recursive)
359 for (
auto sm : m_submodules)
361 if (sm->contains_gate(gate,
true))
372 auto it = m_gates_map.find(gate_id);
373 if (it == m_gates_map.end())
377 for (
auto sm : m_submodules)
379 auto res = sm->get_gate_by_id(gate_id,
true);
398 std::vector<Gate*> res;
405 for (
auto g : m_gates)
417 for (
auto sm : m_submodules)
419 auto more = sm->get_gates(filter,
true);
420 res.reserve(res.size() + more.size());
421 res.insert(res.end(), more.begin(), more.end());
437 m_input_nets.clear();
438 m_output_nets.clear();
439 m_internal_nets.clear();
441 std::unordered_set<Net*> net_cache;
444 for (
Net*
net : gate->get_fan_in_nets())
446 net_cache.insert(
net);
448 for (
Net*
net : gate->get_fan_out_nets())
450 net_cache.insert(
net);
454 for (
Net*
net : net_cache)
456 NetConnectivity con = check_net_endpoints(
net);
457 if (con.has_internal_source || con.has_internal_destination)
461 if (con.has_internal_source && con.has_internal_destination)
463 m_internal_nets.insert(
net);
466 if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
468 m_input_nets.insert(
net);
469 m_output_nets.insert(
net);
471 else if (con.has_external_source && con.has_internal_destination)
473 m_input_nets.insert(
net);
475 else if (con.has_internal_source && con.has_external_destination)
477 m_output_nets.insert(
net);
489 bool success = m_nets.find(
net) != m_nets.end();
490 if (!success && recursive)
492 for (
auto sm : m_submodules)
494 if (sm->contains_net(
net,
true))
510 std::unordered_set<Net*> res;
517 for (
Net*
n : m_nets)
529 for (
auto sm : m_submodules)
531 auto more = sm->get_nets(filter,
true);
532 res.reserve(res.size() + more.size());
533 res.insert(more.begin(), more.end());
547 return m_output_nets;
552 return m_internal_nets;
562 return m_input_nets.find(
net) != m_input_nets.end();
572 return m_output_nets.find(
net) != m_output_nets.end();
582 return m_internal_nets.find(
net) != m_internal_nets.end();
585 Module::NetConnectivity Module::check_net_endpoints(
const Net*
net)
const
587 std::vector<Endpoint*> sources =
net->get_sources();
588 std::vector<Endpoint*> destinations =
net->get_destinations();
591 res.has_external_source =
net->is_global_input_net();
592 res.has_internal_source =
false;
593 res.has_external_destination =
net->is_global_output_net();
594 res.has_internal_destination =
false;
600 res.has_external_source =
true;
604 res.has_internal_source =
true;
607 if (res.has_external_source && res.has_internal_source)
613 for (Endpoint* ep : destinations)
615 if (Module* mod = ep->get_gate()->get_module();
this != mod && !
is_parent_module_of(mod,
true))
617 res.has_external_destination =
true;
621 res.has_internal_destination =
true;
624 if (res.has_external_destination && res.has_internal_destination)
633 Result<std::monostate> Module::check_net(Net*
net,
bool recursive)
635 NetConnectivity con = check_net_endpoints(
net);
636 if (con.has_internal_source && con.has_internal_destination)
638 m_internal_nets.insert(
net);
642 m_internal_nets.erase(
net);
645 if (con.has_internal_source || con.has_internal_destination)
654 if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
661 m_output_nets.insert(
net);
667 m_input_nets.insert(
net);
676 return ERR(
"could not assign inout pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
680 else if (con.has_external_source && con.has_internal_destination)
684 const auto direction = pin->get_direction();
687 m_input_nets.insert(
net);
688 m_output_nets.erase(
net);
695 m_input_nets.insert(
net);
698 return ERR(
"could not assign input pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
702 else if (con.has_internal_source && con.has_external_destination)
706 const auto direction = pin->get_direction();
709 m_output_nets.insert(
net);
710 m_input_nets.erase(
net);
717 m_output_nets.insert(
net);
720 return ERR(
"could not assign output pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
731 m_input_nets.erase(
net);
735 m_output_nets.erase(
net);
737 if (!remove_pin_net(
net))
739 return ERR(
"Remove pin net failed");
744 if (m_internal_manager->m_net_checks_enabled && recursive && m_parent !=
nullptr)
746 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
763 if (!m_free_pin_ids.empty())
765 return *(m_free_pin_ids.begin());
767 while (m_used_pin_ids.find(m_next_pin_id) != m_used_pin_ids.end())
771 return m_next_pin_id;
776 if (!m_free_pin_group_ids.empty())
778 return *(m_free_pin_group_ids.begin());
780 while (m_used_pin_group_ids.find(m_next_pin_group_id) != m_used_pin_group_ids.end())
782 m_next_pin_group_id++;
784 return m_next_pin_group_id;
791 return ERR(
"could not create pin for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": empty string passed as name");
794 if (m_internal_manager->m_net_checks_enabled)
796 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id)
797 +
": unable to manually assign pin as automatic net checks are enabled. Disable these checks using 'Netlist::enable_automatic_net_checks(false)' in case you "
798 "want to manage pins manually.");
803 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": net is a 'nullptr'");
810 if (is_input && is_output)
824 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id())
825 +
" is neither an input nor an output");
828 if (
auto pin_res = create_pin_internal(
id,
name,
net,
direction,
type, force_name); pin_res.is_error())
830 return ERR_APPEND(pin_res.get_error(),
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id));
839 assert(delete_pin_internal(pin_res.get()));
840 return ERR_APPEND(group_res.get_error(),
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": failed to create pin group");
845 if (!group_res.get()->assign_pin(pin_res.get()))
847 assert(delete_pin_internal(pin_res.get()));
848 assert(delete_pin_group_internal(group_res.get()));
849 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": failed to assign pin to pin group");
873 std::vector<ModulePin*> res;
876 res.reserve(m_pins.size());
877 for (
const auto& group : m_pin_groups_ordered)
879 std::vector<ModulePin*>
pins = group->get_pins();
880 res.insert(res.end(),
pins.begin(),
pins.end());
901 std::vector<std::string> res;
904 res.reserve(m_pins.size());
905 for (
const auto& group : m_pin_groups_ordered)
907 std::vector<ModulePin*>
pins = group->get_pins();
908 for (
const auto pin : group->get_pins())
910 res.push_back(pin->get_name());
922 res.push_back(pin->get_name());
964 std::vector<PinGroup<ModulePin>*> res;
967 res.reserve(m_pin_groups_ordered.size());
968 res.insert(res.end(), m_pin_groups_ordered.begin(), m_pin_groups_ordered.end());
976 res.push_back(group);
987 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
991 if (
const auto it = m_pins_map.find(
id); it != m_pins_map.end())
996 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: no pin with ID {} exists", m_name, m_id,
id);
1004 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1008 if (
const auto it = m_pin_names_map.find(
name); it != m_pin_names_map.end())
1013 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: no pin with name '{}' exists", m_name, m_id,
name);
1021 log_warning(
"module",
"could not get pin by net for module '{}' with ID {}: net is a 'nullptr'", m_name, m_id);
1025 if (
const auto it = std::find_if(m_pins.begin(), m_pins.end(), [
net](
const std::unique_ptr<ModulePin>& pin) { return pin->get_net() == net; }); it != m_pins.end())
1030 log_debug(
"module",
"could not get pin by net for module '{}' with ID {}: no pin belongs to net '{}' with ID {}", m_name, m_id,
net->get_name(),
net->get_id());
1038 log_warning(
"module",
"could not get pin group by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
1042 if (
const auto it = m_pin_groups_map.find(
id); it != m_pin_groups_map.end())
1047 log_warning(
"module",
"could not get pin group by ID for module '{}' with ID {}: no pin with ID {} exists", m_name, m_id,
id);
1055 log_warning(
"module",
"could not get pin group by name for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1059 if (
const auto it = m_pin_group_names_map.find(
name); it != m_pin_group_names_map.end())
1064 log_warning(
"module",
"could not get pin group by name for module '{}' with ID {}: no pin with name '{}' exists", m_name, m_id,
name);
1072 log_warning(
"module",
"could not set name for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1076 if (new_name.empty())
1078 log_warning(
"module",
"could not set name for pin '{}' with ID {} of module '{}' with ID {}: empty string passed as new name", pin->
get_name(), pin->
get_id(), m_name, m_id);
1082 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1084 log_warning(
"module",
"could not set name for pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->
get_name(), pin->
get_id(), m_name, m_id);
1088 if (
const auto pin_it = m_pin_names_map.find(new_name); pin_it != m_pin_names_map.end())
1093 while (!this->
set_pin_name(pin_it->second, new_name +
"__" + std::to_string(ctr) +
"__"))
1101 "could not set name for pin '{}' with ID {} of module '{}' with ID {}: a pin with name '{}' already exists within the module",
1111 if (
const std::string& old_name = pin->
get_name(); old_name != new_name)
1113 m_pin_names_map.erase(old_name);
1115 m_pin_names_map[new_name] = pin;
1126 log_warning(
"module",
"could not set type for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1130 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1132 log_warning(
"module",
"could not set type for pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->
get_name(), pin->
get_id(), m_name, m_id);
1147 if (pin_group ==
nullptr)
1149 log_warning(
"module",
"could not set name for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1153 if (new_name.empty())
1156 "module",
"could not set name for pin group '{}' with ID {} of module '{}' with ID {}: empty string passed as new name", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1160 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1163 "module",
"could not set name for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1167 if (
const auto pin_group_it = m_pin_group_names_map.find(new_name); pin_group_it != m_pin_group_names_map.end())
1172 while (!this->
set_pin_group_name(pin_group_it->second, new_name +
"__" + std::to_string(ctr) +
"__"))
1180 "could not set name for pin group '{}' with ID {} of module '{}' with ID {}: a pin group with name '{}' already exists within the module",
1190 if (
const std::string& old_name = pin_group->
get_name(); old_name != new_name)
1192 m_pin_group_names_map.erase(old_name);
1194 m_pin_group_names_map[new_name] = pin_group;
1203 if (pin_group ==
nullptr)
1205 log_warning(
"module",
"could not set type for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1209 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1212 "module",
"could not set type for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1216 if (pin_group->
get_type() != new_type)
1226 if (pin_group ==
nullptr)
1228 log_warning(
"module",
"could not set direction for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1232 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1235 "could not set direction for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1252 const std::string&
name,
1253 const std::vector<ModulePin*>
pins,
1258 bool delete_empty_groups,
1265 return ERR(
"could not create pin group for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": empty string passed as name");
1277 return ERR_APPEND(res.get_error(),
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id));
1281 pin_group = res.get();
1286 for (
auto it =
pins.begin(); it !=
pins.end(); ++it)
1290 return ERR(
"Assign pin to group failed.");
1295 for (
auto it =
pins.rbegin(); it !=
pins.rend(); ++it)
1299 return ERR(
"Assign pin to group failed.");
1305 return OK(pin_group);
1309 const std::vector<ModulePin*>
pins,
1314 bool delete_empty_groups,
1323 if (pin_group ==
nullptr)
1325 log_warning(
"module",
"could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1329 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1332 "module",
"could not delete pin group '{}' with ID {} from module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1336 std::vector<ModulePin*> pins_copy = pin_group->
get_pins();
1339 auto res =
create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(),
true, 0,
false);
1348 u32 pin_group_id_to_delete = pin_group->
get_id();
1350 if (!delete_pin_group_internal(pin_group))
1362 if (pin_group ==
nullptr)
1364 log_warning(
"module",
"could not move pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1368 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1371 "module",
"could not move pin group '{}' with ID {} within module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1375 if (new_index >= m_pin_groups_ordered.size())
1377 log_warning(
"module",
"could not move pin group '{}' with ID {} of module '{}' with ID {}: index {} is out of bounds", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id, new_index);
1381 auto src_it = std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group);
1382 auto dst_it = m_pin_groups_ordered.begin();
1383 std::advance(dst_it, new_index);
1384 if (src_it == dst_it)
1388 else if (std::distance(m_pin_groups_ordered.begin(), src_it) < std::distance(m_pin_groups_ordered.begin(), dst_it))
1390 std::advance(dst_it, 1);
1391 m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1395 m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1406 if (pin_group ==
nullptr)
1408 log_warning(
"module",
"could not assign pin to pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1414 log_warning(
"module",
"could not assign pin to pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1418 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1421 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1431 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1434 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1452 if (!pg->remove_pin(pin))
1455 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to remove pin from pin group '{}' with ID {}",
1467 if (delete_empty_groups && pg->empty())
1470 if (!delete_pin_group_internal(pg))
1473 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to delete pin group '{}' with ID {}",
1490 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}",
1508 if (pin_group ==
nullptr)
1510 log_warning(
"module",
"could not move pin within pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1516 log_warning(
"module",
"could not move pin within pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1520 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1523 "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1533 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1536 "could not move pin '{}' with ID {} within pin group '{}' with return ERRID {} of module '{}' with ID {}: pin does not belong to module",
1546 if (
auto res = pin_group->
move_pin(pin, new_index); res.is_error())
1549 "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}",
1565 if (pin_group ==
nullptr)
1567 log_warning(
"module",
"could not remove pin from pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1573 log_warning(
"module",
"could not remove pin from pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1577 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1580 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1590 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1593 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1606 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID : unable to create new pin group for pin",
1622 std::string port_prefix;
1640 std::string name_internal;
1643 name_internal = port_prefix +
"(" + std::to_string(ctr) +
")";
1645 }
while (m_pin_names_map.find(name_internal) != m_pin_names_map.end() || m_pin_group_names_map.find(name_internal) != m_pin_group_names_map.end());
1651 log_warning(
"module",
"could not assign pin '{}' to net: failed to create pin", name_internal);
1660 if (
const auto group_res = create_pin_group_internal(
get_unique_pin_group_id(), name_internal, pin->get_direction(), pin->get_type(),
true, 0,
false); group_res.is_error())
1662 log_warning(
"module",
"could not assign pin '{}' to net: failed to create pin group", name_internal);
1668 if (!group_res.get()->assign_pin(pin))
1670 log_warning(
"module",
"could not assign pin '{}' to net: failed to assign pin to pin group", name_internal);
1677 scope.send_events();
1681 bool Module::remove_pin_net(Net*
net)
1683 PinChangedEventScope scope(
this);
1687 log_warning(
"module",
"could not remove pin from net: failed to get pin corresponding to net");
1691 PinGroup<ModulePin>* pin_group = pin->get_group().first;
1692 assert(pin_group !=
nullptr);
1694 if (!pin_group->remove_pin(pin))
1697 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to remove pin from pin group '{}' with ID {}",
1702 pin_group->get_name(),
1703 pin_group->get_id());
1707 if (pin_group->empty())
1710 if (!delete_pin_group_internal(pin_group))
1713 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}",
1718 pin_group->get_name(),
1719 pin_group->get_id());
1724 u32 pin_id_to_delete = pin->get_id();
1726 if (!delete_pin_internal(pin))
1729 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin '{}' with ID {}",
1740 scope.send_events();
1749 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID 0 is invalid");
1751 if (m_used_pin_ids.find(
id) != m_used_pin_ids.end())
1753 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID " + std::to_string(
id) +
" is already taken");
1755 if (
const auto pin_it = m_pin_names_map.find(
name); pin_it != m_pin_names_map.end())
1760 while (!this->
set_pin_name(pin_it->second,
name +
"__" + std::to_string(ctr) +
"__"))
1767 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": name '" +
name +
"' is already taken");
1772 return ERR(
"could not create pin '" +
name +
"' for gate type '" + m_name +
"' with ID " + std::to_string(m_id) +
": net is a 'nullptr'");
1776 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with " + std::to_string(m_id) +
": direction '" +
enum_to_string(
direction) +
"' is invalid");
1781 ModulePin* pin = pin_owner.get();
1782 m_pins.push_back(std::move(pin_owner));
1783 m_pins_map[
id] = pin;
1784 m_pin_names_map[
name] = pin;
1787 if (
auto free_id_it = m_free_pin_ids.find(
id); free_id_it != m_free_pin_ids.end())
1789 m_free_pin_ids.erase(free_id_it);
1791 m_used_pin_ids.insert(
id);
1796 bool Module::delete_pin_internal(ModulePin* pin)
1801 log_warning(
"module",
"could not delete pin of gate type '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1804 if (
const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1806 log_warning(
"module",
"could not delete pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), m_name, m_id);
1811 u32 del_id = pin->get_id();
1812 const std::string& del_name = pin->get_name();
1813 m_pins_map.erase(del_id);
1814 m_pin_names_map.erase(del_name);
1815 m_pins.erase(std::find_if(m_pins.begin(), m_pins.end(), [pin](
const auto& p) { return p.get() == pin; }));
1818 m_free_pin_ids.insert(del_id);
1819 m_used_pin_ids.erase(del_id);
1829 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID 0 is invalid");
1831 if (m_used_pin_group_ids.find(
id) != m_used_pin_group_ids.end())
1833 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID " + std::to_string(
id) +
" is already taken");
1835 if (
const auto pin_group_it = m_pin_group_names_map.find(
name); pin_group_it != m_pin_group_names_map.end())
1847 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": name '" +
name +
"' is already taken");
1853 m_pin_groups.push_back(std::move(pin_group_owner));
1854 PinGroup<ModulePin>* pin_group = m_pin_groups.back().get();
1855 m_pin_groups_ordered.push_back(pin_group);
1856 m_pin_groups_map[
id] = pin_group;
1857 m_pin_group_names_map[
name] = pin_group;
1860 if (
auto free_id_it = m_free_pin_group_ids.find(
id); free_id_it != m_free_pin_group_ids.end())
1862 m_free_pin_group_ids.erase(free_id_it);
1864 m_used_pin_group_ids.insert(
id);
1866 return OK(pin_group);
1869 bool Module::delete_pin_group_internal(PinGroup<ModulePin>* pin_group)
1872 if (pin_group ==
nullptr)
1874 log_warning(
"module",
"could not delete pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1877 if (
const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1880 "module",
"could not delete pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1885 u32 del_id = pin_group->get_id();
1886 const std::string& del_name = pin_group->get_name();
1887 m_pin_groups_map.erase(del_id);
1888 m_pin_group_names_map.erase(del_name);
1889 m_pin_groups_ordered.erase(std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group));
1890 m_pin_groups.erase(std::find_if(m_pin_groups.begin(), m_pin_groups.end(), [pin_group](
const auto& pg) { return pg.get() == pin_group; }));
1893 m_free_pin_group_ids.insert(del_id);
1894 m_used_pin_group_ids.erase(del_id);
1901 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