14 Module::Module(NetlistInternalManager* internal_manager, EventHandler* event_handler,
u32 id, Module* parent,
const std::string&
name)
16 m_internal_manager = internal_manager;
22 m_next_pin_group_id = 1;
24 m_event_handler = event_handler;
31 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal ID, name, or type.", m_id, other.
get_id());
39 if (
const auto it = m_submodules_map.find(other_module->get_id()); it == m_submodules_map.end() || *it->second != *other_module)
41 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal submodules.", m_id, other.
get_id());
48 if (
const auto it = m_gates_map.find(other_gate->get_id()); it == m_gates_map.end() || *it->second != *other_gate)
50 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal gates.", m_id, other.
get_id());
57 if (
const auto other_pin_group_res = other.
get_pin_group_by_id(pin_group->get_id()); other_pin_group_res ==
nullptr || *other_pin_group_res != *pin_group)
59 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to an unequal pin group.", m_id, other.
get_id());
64 if (!DataContainer::operator==(other))
66 log_debug(
"module",
"the modules with IDs {} and {} are not equal due to unequal data.", m_id, other.
get_id());
80 return (uintptr_t)
this;
97 log_warning(
"module",
"module name cannot be empty.");
133 std::vector<Module*> res;
134 if (m_parent ==
nullptr)
141 res.push_back(m_parent);
145 if (filter(m_parent))
147 res.push_back(m_parent);
154 res.reserve(res.size() + more.size());
155 res.insert(res.end(), more.begin(), more.end());
173 if (new_parent ==
this)
175 log_error(
"module",
"module '{}' with ID {} in netlist with ID {} cannot be its own parent module.", m_name, m_id, m_internal_manager->m_netlist->
get_id());
179 if (m_parent ==
nullptr)
181 log_error(
"module",
"no parent module can be assigned to top module '{}' with ID {} in netlist with ID {}.", m_name, m_id, m_internal_manager->m_netlist->
get_id());
185 if (new_parent ==
nullptr)
187 log_error(
"module",
"module '{}' with ID {} in netlist with ID {} cannot be assigned to be the top module.", m_name, m_id, m_internal_manager->m_netlist->
get_id());
191 if (!
get_netlist()->is_module_in_netlist(new_parent))
193 log_error(
"module",
"module '{}' with ID {} is not contained in netlist with ID {}.", new_parent->
get_name(), new_parent->
get_id(), m_internal_manager->m_netlist->
get_id());
198 if (std::find(children.begin(), children.end(), new_parent) != children.end())
205 Module* old_parent = m_parent;
206 old_parent->m_submodules_map.erase(m_id);
208 m_parent = new_parent;
210 if (m_internal_manager->m_net_checks_enabled)
214 if (
auto res = old_parent->check_net(
net,
true); res.is_error())
216 log_error(
"module",
"{}", res.get_error().get());
223 m_parent->m_submodules_map[m_id] =
this;
226 if (m_internal_manager->m_net_checks_enabled)
230 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
232 log_error(
"module",
"{}", res.get_error().get());
255 return parent ==
this;
257 while (parent !=
nullptr)
263 parent = parent->m_parent;
270 std::vector<Module*> res;
277 for (
auto sm : m_submodules)
288 for (
auto sm : m_submodules)
290 auto more = sm->get_submodules(filter,
true);
291 res.reserve(res.size() + more.size());
292 res.insert(res.end(), more.begin(), more.end());
323 return m_parent ==
nullptr;
328 return m_internal_manager->m_netlist;
333 return m_internal_manager->module_assign_gates(
this, {gate});
338 return m_internal_manager->module_assign_gates(
this, gates);
348 for (
Gate* gate : gates)
356 return m_internal_manager->module_assign_gates(m_internal_manager->m_netlist->
get_top_module(), gates);
365 bool success = std::find(m_gates.begin(), m_gates.end(), gate) != m_gates.end();
366 if (!success && recursive)
368 for (
auto sm : m_submodules)
370 if (sm->contains_gate(gate,
true))
381 auto it = m_gates_map.find(gate_id);
382 if (it == m_gates_map.end())
386 for (
auto sm : m_submodules)
388 auto res = sm->get_gate_by_id(gate_id,
true);
407 std::vector<Gate*> res;
414 for (
auto g : m_gates)
426 for (
auto sm : m_submodules)
428 auto more = sm->get_gates(filter,
true);
429 res.reserve(res.size() + more.size());
430 res.insert(res.end(), more.begin(), more.end());
446 m_input_nets.clear();
447 m_output_nets.clear();
448 m_internal_nets.clear();
450 std::unordered_set<Net*> net_cache;
453 for (
Net*
net : gate->get_fan_in_nets())
455 net_cache.insert(
net);
457 for (
Net*
net : gate->get_fan_out_nets())
459 net_cache.insert(
net);
463 for (
Net*
net : net_cache)
465 NetConnectivity con = check_net_endpoints(
net);
466 if (con.has_internal_source || con.has_internal_destination)
470 if (con.has_internal_source && con.has_internal_destination)
472 m_internal_nets.insert(
net);
475 if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
477 m_input_nets.insert(
net);
478 m_output_nets.insert(
net);
480 else if (con.has_external_source && con.has_internal_destination)
482 m_input_nets.insert(
net);
484 else if (con.has_internal_source && con.has_external_destination)
486 m_output_nets.insert(
net);
498 bool success = m_nets.find(
net) != m_nets.end();
499 if (!success && recursive)
501 for (
auto sm : m_submodules)
503 if (sm->contains_net(
net,
true))
519 std::unordered_set<Net*> res;
526 for (
Net* n : m_nets)
538 for (
auto sm : m_submodules)
540 auto more = sm->get_nets(filter,
true);
541 res.reserve(res.size() + more.size());
542 res.insert(more.begin(), more.end());
556 return m_output_nets;
561 return m_internal_nets;
571 return m_input_nets.find(
net) != m_input_nets.end();
581 return m_output_nets.find(
net) != m_output_nets.end();
591 return m_internal_nets.find(
net) != m_internal_nets.end();
594 Module::NetConnectivity Module::check_net_endpoints(
const Net*
net)
const
596 std::vector<Endpoint*> sources =
net->get_sources();
597 std::vector<Endpoint*> destinations =
net->get_destinations();
600 res.has_external_source =
net->is_global_input_net();
601 res.has_internal_source =
false;
602 res.has_external_destination =
net->is_global_output_net();
603 res.has_internal_destination =
false;
609 res.has_external_source =
true;
613 res.has_internal_source =
true;
616 if (res.has_external_source && res.has_internal_source)
622 for (Endpoint* ep : destinations)
624 if (Module* mod = ep->get_gate()->get_module();
this != mod && !
is_parent_module_of(mod,
true))
626 res.has_external_destination =
true;
630 res.has_internal_destination =
true;
633 if (res.has_external_destination && res.has_internal_destination)
642 Result<std::monostate> Module::check_net(Net*
net,
bool recursive)
644 NetConnectivity con = check_net_endpoints(
net);
645 if (con.has_internal_source && con.has_internal_destination)
647 m_internal_nets.insert(
net);
651 m_internal_nets.erase(
net);
654 if (con.has_internal_source || con.has_internal_destination)
663 if (con.has_internal_source && con.has_internal_destination && con.has_external_source && con.has_external_destination)
670 m_output_nets.insert(
net);
676 m_input_nets.insert(
net);
685 return ERR(
"could not assign inout pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
689 else if (con.has_external_source && con.has_internal_destination)
693 const auto direction = pin->get_direction();
696 m_input_nets.insert(
net);
697 m_output_nets.erase(
net);
704 m_input_nets.insert(
net);
707 return ERR(
"could not assign input pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
711 else if (con.has_internal_source && con.has_external_destination)
715 const auto direction = pin->get_direction();
718 m_output_nets.insert(
net);
719 m_input_nets.erase(
net);
726 m_output_nets.insert(
net);
729 return ERR(
"could not assign output pin to net ID " + std::to_string(
net->get_id()) +
": failed to create pin");
740 m_input_nets.erase(
net);
744 m_output_nets.erase(
net);
746 if (!remove_pin_net(
net))
748 return ERR(
"Remove pin net failed");
753 if (m_internal_manager->m_net_checks_enabled && recursive && m_parent !=
nullptr)
755 if (
auto res = m_parent->check_net(
net,
true); res.is_error())
772 if (!m_free_pin_ids.empty())
774 return *(m_free_pin_ids.begin());
776 while (m_used_pin_ids.find(m_next_pin_id) != m_used_pin_ids.end())
780 return m_next_pin_id;
785 if (!m_free_pin_group_ids.empty())
787 return *(m_free_pin_group_ids.begin());
789 while (m_used_pin_group_ids.find(m_next_pin_group_id) != m_used_pin_group_ids.end())
791 m_next_pin_group_id++;
793 return m_next_pin_group_id;
800 return ERR(
"could not create pin for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": empty string passed as name");
803 if (m_internal_manager->m_net_checks_enabled)
805 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id)
806 +
": unable to manually assign pin as automatic net checks are enabled. Disable these checks using 'Netlist::enable_automatic_net_checks(false)' in case you "
807 "want to manage pins manually.");
812 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": net is a 'nullptr'");
819 if (is_input && is_output)
833 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id())
834 +
" is neither an input nor an output");
837 if (
auto pin_res = create_pin_internal(
id,
name,
net,
direction,
type, force_name); pin_res.is_error())
839 return ERR_APPEND(pin_res.get_error(),
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id));
848 assert(delete_pin_internal(pin_res.get()));
849 return ERR_APPEND(group_res.get_error(),
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": failed to create pin group");
854 if (!group_res.get()->assign_pin(pin_res.get()))
856 assert(delete_pin_internal(pin_res.get()));
857 assert(delete_pin_group_internal(group_res.get()));
858 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": failed to assign pin to pin group");
882 std::vector<ModulePin*> res;
885 res.reserve(m_pins.size());
886 for (
const auto& group : m_pin_groups_ordered)
888 std::vector<ModulePin*>
pins = group->get_pins();
889 res.insert(res.end(),
pins.begin(),
pins.end());
910 std::vector<std::string> res;
913 res.reserve(m_pins.size());
914 for (
const auto& group : m_pin_groups_ordered)
916 std::vector<ModulePin*>
pins = group->get_pins();
917 for (
const auto pin : group->get_pins())
919 res.push_back(pin->get_name());
931 res.push_back(pin->get_name());
973 std::vector<PinGroup<ModulePin>*> res;
976 res.reserve(m_pin_groups_ordered.size());
977 res.insert(res.end(), m_pin_groups_ordered.begin(), m_pin_groups_ordered.end());
985 res.push_back(group);
996 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
1000 if (
const auto it = m_pins_map.find(
id); it != m_pins_map.end())
1005 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: no pin with ID {} exists", m_name, m_id,
id);
1013 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1017 if (
const auto it = m_pin_names_map.find(
name); it != m_pin_names_map.end())
1022 log_warning(
"module",
"could not get pin by ID for module '{}' with ID {}: no pin with name '{}' exists", m_name, m_id,
name);
1030 log_warning(
"module",
"could not get pin by net for module '{}' with ID {}: net is a 'nullptr'", m_name, m_id);
1034 if (
const auto it = m_pin_nets_map.find(
net); it != m_pin_nets_map.end())
1039 log_debug(
"module",
"could not get pin by net for module '{}' with ID {}: no pin belongs to net '{}' with ID {}", m_name, m_id,
net->get_name(),
net->get_id());
1047 log_warning(
"module",
"could not get pin group by ID for module '{}' with ID {}: ID 0 is invalid", m_name, m_id);
1051 if (
const auto it = m_pin_groups_map.find(
id); it != m_pin_groups_map.end())
1056 log_warning(
"module",
"could not get pin group by ID for module '{}' with ID {}: no pin group with ID {} exists", m_name, m_id,
id);
1064 log_warning(
"module",
"could not get pin group by name for module '{}' with ID {}: empty string provided as name", m_name, m_id);
1068 if (
const auto it = m_pin_group_names_map.find(
name); it != m_pin_group_names_map.end())
1073 log_warning(
"module",
"could not get pin group by name for module '{}' with ID {}: no pin group with name '{}' exists", m_name, m_id,
name);
1081 log_warning(
"module",
"could not set name for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1085 if (new_name.empty())
1087 log_warning(
"module",
"could not set name for pin '{}' with ID {} of module '{}' with ID {}: empty string passed as new name", pin->
get_name(), pin->
get_id(), m_name, m_id);
1091 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1093 log_warning(
"module",
"could not set name for pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->
get_name(), pin->
get_id(), m_name, m_id);
1097 if (
const auto pin_it = m_pin_names_map.find(new_name); pin_it != m_pin_names_map.end())
1102 while (!this->
set_pin_name(pin_it->second, new_name +
"__" + std::to_string(ctr) +
"__"))
1110 "could not set name for pin '{}' with ID {} of module '{}' with ID {}: a pin with name '{}' already exists within the module",
1120 if (
const std::string& old_name = pin->
get_name(); old_name != new_name)
1122 m_pin_names_map.erase(old_name);
1124 m_pin_names_map[new_name] = pin;
1135 log_warning(
"module",
"could not set type for pin of module '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1139 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1141 log_warning(
"module",
"could not set type for pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->
get_name(), pin->
get_id(), m_name, m_id);
1156 if (pin_group ==
nullptr)
1158 log_warning(
"module",
"could not set name for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1162 if (new_name.empty())
1165 "module",
"could not set name for pin group '{}' with ID {} of module '{}' with ID {}: empty string passed as new name", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1169 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1172 "module",
"could not set name for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1176 if (
const auto pin_group_it = m_pin_group_names_map.find(new_name); pin_group_it != m_pin_group_names_map.end())
1181 while (!this->
set_pin_group_name(pin_group_it->second, new_name +
"__" + std::to_string(ctr) +
"__"))
1189 "could not set name for pin group '{}' with ID {} of module '{}' with ID {}: a pin group with name '{}' already exists within the module",
1199 if (
const std::string& old_name = pin_group->
get_name(); old_name != new_name)
1201 m_pin_group_names_map.erase(old_name);
1203 m_pin_group_names_map[new_name] = pin_group;
1212 if (pin_group ==
nullptr)
1214 log_warning(
"module",
"could not set type for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1218 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1221 "module",
"could not set type for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1225 if (pin_group->
get_type() != new_type)
1235 if (pin_group ==
nullptr)
1237 log_warning(
"module",
"could not set direction for pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1241 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1244 "could not set direction for pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1261 const std::string&
name,
1262 const std::vector<ModulePin*>
pins,
1267 bool delete_empty_groups,
1274 return ERR(
"could not create pin group for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": empty string passed as name");
1286 return ERR_APPEND(res.get_error(),
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id));
1290 pin_group = res.get();
1295 for (
auto it =
pins.begin(); it !=
pins.end(); ++it)
1300 return ERR(
"Assign pin to group failed.");
1306 for (
auto it =
pins.rbegin(); it !=
pins.rend(); ++it)
1311 return ERR(
"Assign pin to group failed.");
1318 return OK(pin_group);
1322 const std::vector<ModulePin*>
pins,
1327 bool delete_empty_groups,
1336 if (pin_group ==
nullptr)
1338 log_warning(
"module",
"could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1342 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1345 "module",
"could not delete pin group '{}' with ID {} from module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1349 std::vector<ModulePin*> pins_copy = pin_group->
get_pins();
1352 auto res =
create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(),
true, 0,
false);
1361 u32 pin_group_id_to_delete = pin_group->
get_id();
1363 if (!delete_pin_group_internal(pin_group))
1375 if (pin_group ==
nullptr)
1377 log_warning(
"module",
"could not move pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1381 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1384 "module",
"could not move pin group '{}' with ID {} within module '{}' with ID {}: pin group does not belong to module", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1388 if (new_index >= m_pin_groups_ordered.size())
1390 log_warning(
"module",
"could not move pin group '{}' with ID {} of module '{}' with ID {}: index {} is out of bounds", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id, new_index);
1394 auto src_it = std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group);
1395 auto dst_it = m_pin_groups_ordered.begin();
1396 std::advance(dst_it, new_index);
1397 if (src_it == dst_it)
1401 else if (std::distance(m_pin_groups_ordered.begin(), src_it) < std::distance(m_pin_groups_ordered.begin(), dst_it))
1403 std::advance(dst_it, 1);
1404 m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1408 m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it);
1419 if (pin_group ==
nullptr)
1421 log_warning(
"module",
"could not assign pin to pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1427 log_warning(
"module",
"could not assign pin to pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1431 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1434 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1444 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1447 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1465 if (!pg->remove_pin(pin))
1468 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to remove pin from pin group '{}' with ID {}",
1480 if (delete_empty_groups && pg->empty())
1483 if (!delete_pin_group_internal(pg))
1486 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to delete pin group '{}' with ID {}",
1503 "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}",
1521 if (pin_group ==
nullptr)
1523 log_warning(
"module",
"could not move pin within pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1529 log_warning(
"module",
"could not move pin within pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1533 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1536 "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1546 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1549 "could not move pin '{}' with ID {} within pin group '{}' with return ERRID {} of module '{}' with ID {}: pin does not belong to module",
1559 if (
auto res = pin_group->
move_pin(pin, new_index); res.is_error())
1562 "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}",
1578 if (pin_group ==
nullptr)
1580 log_warning(
"module",
"could not remove pin from pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1586 log_warning(
"module",
"could not remove pin from pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->
get_name(), pin_group->
get_id(), m_name, m_id);
1590 if (
const auto it = m_pin_groups_map.find(pin_group->
get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1593 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module",
1603 if (
const auto it = m_pins_map.find(pin->
get_id()); it == m_pins_map.end() || it->second != pin)
1606 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module",
1619 "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID : unable to create new pin group for pin",
1635 std::string port_prefix;
1653 std::string name_internal;
1656 name_internal = port_prefix +
"(" + std::to_string(ctr) +
")";
1658 }
while (m_pin_names_map.find(name_internal) != m_pin_names_map.end() || m_pin_group_names_map.find(name_internal) != m_pin_group_names_map.end());
1664 log_warning(
"module",
"could not assign pin '{}' to net: failed to create pin", name_internal);
1673 if (
const auto group_res = create_pin_group_internal(
get_unique_pin_group_id(), name_internal, pin->get_direction(), pin->get_type(),
true, 0,
false); group_res.is_error())
1675 log_warning(
"module",
"could not assign pin '{}' to net: failed to create pin group", name_internal);
1681 if (!group_res.get()->assign_pin(pin))
1683 log_warning(
"module",
"could not assign pin '{}' to net: failed to assign pin to pin group", name_internal);
1692 scope.send_events();
1696 bool Module::remove_pin_net(Net*
net)
1698 PinChangedEventScope scope(
this);
1702 log_warning(
"module",
"could not remove pin from net: failed to get pin corresponding to net");
1706 PinGroup<ModulePin>* pin_group = pin->get_group().first;
1707 assert(pin_group !=
nullptr);
1709 if (!pin_group->remove_pin(pin))
1712 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to remove pin from pin group '{}' with ID {}",
1717 pin_group->get_name(),
1718 pin_group->get_id());
1722 if (pin_group->empty())
1725 if (!delete_pin_group_internal(pin_group))
1728 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}",
1733 pin_group->get_name(),
1734 pin_group->get_id());
1739 u32 pin_id_to_delete = pin->get_id();
1741 if (!delete_pin_internal(pin))
1744 "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin '{}' with ID {}",
1755 scope.send_events();
1764 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID 0 is invalid");
1766 if (m_used_pin_ids.find(
id) != m_used_pin_ids.end())
1768 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID " + std::to_string(
id) +
" is already taken");
1770 if (
const auto pin_it = m_pin_names_map.find(
name); pin_it != m_pin_names_map.end())
1775 while (!this->
set_pin_name(pin_it->second,
name +
"__" + std::to_string(ctr) +
"__"))
1782 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": name '" +
name +
"' is already taken");
1787 return ERR(
"could not create pin '" +
name +
"' for gate type '" + m_name +
"' with ID " + std::to_string(m_id) +
": net is a 'nullptr'");
1791 return ERR(
"could not create pin '" +
name +
"' for module '" + m_name +
"' with " + std::to_string(m_id) +
": direction '" +
enum_to_string(
direction) +
"' is invalid");
1796 ModulePin* pin = pin_owner.get();
1797 m_pins.push_back(std::move(pin_owner));
1798 m_pins_map[
id] = pin;
1799 m_pin_names_map[
name] = pin;
1800 m_pin_nets_map[
net] = pin;
1803 if (
auto free_id_it = m_free_pin_ids.find(
id); free_id_it != m_free_pin_ids.end())
1805 m_free_pin_ids.erase(free_id_it);
1807 m_used_pin_ids.insert(
id);
1812 bool Module::delete_pin_internal(ModulePin* pin)
1817 log_warning(
"module",
"could not delete pin of gate type '{}' with ID {}: pin is a 'nullptr'", m_name, m_id);
1820 if (
const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin)
1822 log_warning(
"module",
"could not delete pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), m_name, m_id);
1827 u32 del_id = pin->get_id();
1828 const std::string& del_name = pin->get_name();
1829 m_pins_map.erase(del_id);
1830 m_pin_names_map.erase(del_name);
1831 m_pin_nets_map.erase(pin->get_net());
1832 m_pins.erase(std::find_if(m_pins.begin(), m_pins.end(), [pin](
const auto& p) { return p.get() == pin; }));
1835 m_free_pin_ids.insert(del_id);
1836 m_used_pin_ids.erase(del_id);
1846 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID 0 is invalid");
1848 if (m_used_pin_group_ids.find(
id) != m_used_pin_group_ids.end())
1850 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": ID " + std::to_string(
id) +
" is already taken");
1852 if (
const auto pin_group_it = m_pin_group_names_map.find(
name); pin_group_it != m_pin_group_names_map.end())
1865 return ERR(
"could not create pin group '" +
name +
"' for module '" + m_name +
"' with ID " + std::to_string(m_id) +
": name '" +
name +
"' is already taken");
1871 m_pin_groups.push_back(std::move(pin_group_owner));
1872 PinGroup<ModulePin>* pin_group = m_pin_groups.back().get();
1873 m_pin_groups_ordered.push_back(pin_group);
1874 m_pin_groups_map[
id] = pin_group;
1875 m_pin_group_names_map[
name] = pin_group;
1878 if (
auto free_id_it = m_free_pin_group_ids.find(
id); free_id_it != m_free_pin_group_ids.end())
1880 m_free_pin_group_ids.erase(free_id_it);
1882 m_used_pin_group_ids.insert(
id);
1884 return OK(pin_group);
1887 bool Module::delete_pin_group_internal(PinGroup<ModulePin>* pin_group)
1890 if (pin_group ==
nullptr)
1892 log_warning(
"module",
"could not delete pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id);
1895 if (
const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group)
1898 "module",
"could not delete pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin_group->get_name(), pin_group->get_id(), m_name, m_id);
1903 u32 del_id = pin_group->get_id();
1904 const std::string& del_name = pin_group->get_name();
1905 m_pin_groups_map.erase(del_id);
1906 m_pin_group_names_map.erase(del_name);
1907 m_pin_groups_ordered.erase(std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group));
1908 m_pin_groups.erase(std::find_if(m_pin_groups.begin(), m_pin_groups.end(), [pin_group](
const auto& pg) { return pg.get() == pin_group; }));
1911 m_free_pin_group_ids.insert(del_id);
1912 m_used_pin_group_ids.erase(del_id);
1919 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
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)
Result< PinGroup< ModulePin > * > create_pin_group(const u32 id, const std::string &name, const std::vector< ModulePin * > pins={}, PinDirection direction=PinDirection::none, PinType type=PinType::none, bool ascending=false, u32 start_index=0, bool delete_empty_groups=true, bool force_name=false)
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
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)
void indexed_vector_push_back(std::vector< T > &vec, std::unordered_map< T, u32 > &positions, T element)
bool indexed_vector_erase(std::vector< T > &vec, std::unordered_map< T, u32 > &positions, T element)
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
@ GroupDirChange
changed PinType attribute of group (like data)
@ PinReorder
changed PinDirection attribute of pin (like input)
std::string enum_to_string(T e)
std::vector< PinInformation > pins