16 NetlistInternalManager::NetlistInternalManager(Netlist* nl, EventHandler* eh)
20 assert(nl !=
nullptr);
21 assert(eh !=
nullptr);
28 Result<std::unique_ptr<Netlist>> NetlistInternalManager::copy_netlist(
const Netlist* nl)
const
31 if (c_netlist ==
nullptr)
33 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create netlist");
36 c_netlist->enable_automatic_net_checks(
false);
41 c_netlist->set_design_name(nl->get_design_name());
42 c_netlist->set_device_name(nl->get_device_name());
43 c_netlist->set_input_filename(nl->get_input_filename());
46 for (
const Net*
net : nl->m_nets)
48 Net* c_net = c_netlist->create_net(
net->m_id,
net->m_name);
51 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create copied net '" +
net->m_name +
"' with ID " + std::to_string(
net->m_id));
53 c_net->m_data =
net->m_data;
57 for (
const Gate* gate : nl->m_gates)
59 Gate* c_gate = c_netlist->create_gate(gate->m_id, gate->m_type, gate->m_name, gate->m_x, gate->m_y);
60 if (c_gate ==
nullptr)
62 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create copied gate '" + gate->m_name +
"' with ID " + std::to_string(gate->m_id));
65 for (
const auto& [
name, func] : gate->get_boolean_functions(
true))
67 c_gate->add_boolean_function(
name, func);
70 for (
const Endpoint* in_point : gate->get_fan_in_endpoints())
72 const auto net_id = in_point->get_net()->m_id;
73 auto c_net = c_netlist->get_net_by_id(net_id);
76 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to get copied net by ID " + std::to_string(net_id));
79 if (!c_net->add_destination(c_gate, in_point->get_pin()))
81 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to add destination to copied net '" + c_net->m_name +
"' with ID "
82 + std::to_string(c_net->m_id));
86 for (
const Endpoint* out_point : gate->get_fan_out_endpoints())
88 const auto net_id = out_point->get_net()->m_id;
89 auto c_net = c_netlist->get_net_by_id(net_id);
92 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to get copied net by ID " + std::to_string(net_id));
95 if (!c_net->add_source(c_gate, out_point->get_pin()))
97 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to add source to copied net '" + c_net->m_name +
"' with ID "
98 + std::to_string(c_net->m_id));
102 c_gate->m_data = gate->m_data;
112 c_netlist->m_top_module->m_type =
module->m_type;
116 std::vector<Gate*> c_gates;
120 Gate* c_gate = c_netlist->get_gate_by_id(gate->m_id);
121 if (c_gate ==
nullptr)
123 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to get copied gate by ID " + std::to_string(gate->m_id));
125 c_gates.push_back(c_gate);
129 Module* c_module = c_netlist->create_module(
module->m_id,
module->m_name, c_netlist->m_top_module, c_gates);
130 if (c_module ==
nullptr)
132 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create copied module '" +
module->m_name +
"' with ID " + std::to_string(
module->m_id));
136 c_module->m_type =
module->m_type;
143 if (
module->m_parent ==
nullptr)
150 const u32 parent_id =
module->m_parent->m_id;
151 Module* c_module = c_netlist->get_module_by_id(module_id);
152 Module* c_parent = c_netlist->get_module_by_id(parent_id);
154 if (!c_module->set_parent_module(c_parent))
156 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to set copied module '" + c_parent->m_name +
"' with ID " + std::to_string(
module->m_id)
157 +
" as parent module of '" + c_module->m_name +
"' with ID " + std::to_string(c_module->m_id));
162 for (
const Grouping* grouping : nl->m_groupings)
164 Grouping* c_grouping = c_netlist->create_grouping(grouping->m_id, grouping->m_name);
165 if (c_grouping ==
nullptr)
167 return ERR(
"could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create copied grouping '" + grouping->m_name +
"' with ID "
168 + std::to_string(grouping->m_id));
174 c_grouping->assign_module_by_id(module_id);
177 for (
const Net*
net : grouping->m_nets)
179 const u32 net_id =
net->m_id;
180 c_grouping->assign_net_by_id(net_id);
183 for (
const Gate* gate : grouping->m_gates)
185 const u32 gate_id = gate->m_id;
186 c_grouping->assign_gate_by_id(gate_id);
191 for (
const Net* global_input_net : nl->m_global_input_nets)
193 Net* c_global_input_net = c_netlist->get_net_by_id(global_input_net->m_id);
194 c_netlist->mark_global_input_net(c_global_input_net);
196 for (
const Net* global_output_net : nl->m_global_output_nets)
198 Net* c_global_output_net = c_netlist->get_net_by_id(global_output_net->m_id);
199 c_netlist->mark_global_output_net(c_global_output_net);
201 for (
const Gate* gnd_gate : nl->m_gnd_gates)
203 Gate* c_gnd_gate = c_netlist->get_gate_by_id(gnd_gate->m_id);
204 c_netlist->mark_gnd_gate(c_gnd_gate);
206 for (
const Gate* vcc_gate : nl->m_vcc_gates)
208 Gate* c_vcc_gate = c_netlist->get_gate_by_id(vcc_gate->m_id);
209 c_netlist->mark_vcc_gate(c_vcc_gate);
212 c_netlist->m_design_name = nl->m_design_name;
213 c_netlist->m_device_name = nl->m_device_name;
214 c_netlist->m_file_name = nl->m_file_name;
217 c_netlist->m_next_gate_id = nl->m_next_gate_id;
218 c_netlist->m_used_gate_ids = nl->m_used_gate_ids;
219 c_netlist->m_free_gate_ids = nl->m_free_gate_ids;
221 c_netlist->m_next_net_id = nl->m_next_net_id;
222 c_netlist->m_used_net_ids = nl->m_used_net_ids;
223 c_netlist->m_free_net_ids = nl->m_free_net_ids;
225 c_netlist->m_next_module_id = nl->m_next_module_id;
226 c_netlist->m_used_module_ids = nl->m_used_module_ids;
227 c_netlist->m_free_module_ids = nl->m_free_module_ids;
229 c_netlist->m_next_grouping_id = nl->m_next_grouping_id;
230 c_netlist->m_used_grouping_ids = nl->m_used_grouping_ids;
231 c_netlist->m_free_grouping_ids = nl->m_free_grouping_ids;
236 Module* c_module = c_netlist->get_module_by_id(
module->m_id);
237 c_module->update_nets();
239 for (
const std::unique_ptr<PinGroup<ModulePin>>& pin_group :
module->m_pin_groups)
241 std::vector<ModulePin*> c_pins;
242 for (ModulePin* pin : pin_group->get_pins())
244 if (
const auto res = c_module->create_pin(pin->get_id(), pin->get_name(), c_netlist->get_net_by_id(pin->get_net()->m_id),
PinType::none,
false); res.is_error())
247 "could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create copied module pin '" + pin->get_name() +
"' of module '"
248 + c_module->m_name +
"' with ID " + std::to_string(c_module->m_id));
252 c_pins.push_back(res.get());
256 if (
const auto res = c_module->create_pin_group(
257 pin_group->get_id(), pin_group->get_name(), c_pins, pin_group->get_direction(), pin_group->get_type(), pin_group->is_ascending(), pin_group->get_start_index());
261 "could not copy netlist with ID " + std::to_string(nl->get_id()) +
": failed to create copied module pin group '" + pin_group->get_name() +
"' of module '"
262 + c_module->m_name +
"' with ID " + std::to_string(c_module->m_id));
266 c_module->m_next_input_index =
module->m_next_input_index;
267 c_module->m_next_inout_index =
module->m_next_inout_index;
268 c_module->m_next_output_index =
module->m_next_output_index;
271 c_netlist->enable_automatic_net_checks(
true);
272 return OK(std::move(c_netlist));
279 Gate* NetlistInternalManager::create_gate(
const u32 id, GateType* gt,
const std::string&
name,
i32 x,
i32 y)
283 log_error(
"gate",
"ID 0 represents an invalid gate ID.");
286 if (m_netlist->m_used_gate_ids.find(
id) != m_netlist->m_used_gate_ids.end())
288 log_error(
"gate",
"gate ID {} is already taken in netlist with ID {}.",
id, m_netlist->m_netlist_id);
293 log_error(
"gate",
"nullptr given for gate type.",
id);
296 if (this->is_gate_type_invalid(gt))
298 log_error(
"gate",
"gate type '{}' with ID {} is invalid.", gt->get_name(), gt->get_id());
303 log_error(
"gate",
"gate name cannot be empty.");
307 auto new_gate = std::unique_ptr<Gate>(
new Gate(
this, m_event_handler,
id, gt,
name, x, y));
309 auto free_id_it = m_netlist->m_free_gate_ids.find(
id);
310 if (free_id_it != m_netlist->m_free_gate_ids.end())
312 m_netlist->m_free_gate_ids.erase(free_id_it);
315 m_netlist->m_used_gate_ids.insert(
id);
318 new_gate->m_module = m_netlist->m_top_module;
320 auto raw = new_gate.get();
322 m_netlist->m_gates_map[
id] = std::move(new_gate);
323 m_netlist->m_gates_set.insert(raw);
324 m_netlist->m_gates.push_back(raw);
326 m_netlist->m_top_module->m_gates_map[
id] = raw;
327 m_netlist->m_top_module->m_gates.push_back(raw);
336 bool NetlistInternalManager::delete_gate(Gate* gate)
343 for (
auto ep : gate->get_fan_out_endpoints())
345 if (!net_remove_source(ep->get_net(), ep))
351 for (
auto ep : gate->get_fan_in_endpoints())
353 if (!net_remove_destination(ep->get_net(), ep))
360 if (
Grouping*
g = gate->get_grouping();
g !=
nullptr)
362 g->remove_gate(gate);
370 gate->m_module->m_gates_map.erase(gate->m_module->m_gates_map.find(gate->get_id()));
373 auto it = m_netlist->m_gates_map.find(gate->get_id());
374 auto ptr = std::move(it->second);
375 m_netlist->m_gates_map.erase(it);
376 m_netlist->m_gates_set.erase(gate);
380 m_netlist->m_free_gate_ids.insert(gate->get_id());
381 m_netlist->m_used_gate_ids.erase(gate->get_id());
389 bool NetlistInternalManager::is_gate_type_invalid(GateType* gt)
const
398 Net* NetlistInternalManager::create_net(
const u32 id,
const std::string&
name)
402 log_error(
"net",
"ID 0 represents an invalid net ID.");
405 if (m_netlist->m_used_net_ids.find(
id) != m_netlist->m_used_net_ids.end())
407 log_error(
"net",
"net ID {} is already taken in netlist with ID {}.",
id, m_netlist->m_netlist_id);
412 log_error(
"net",
"net name cannot be empty.");
416 auto new_net = std::unique_ptr<Net>(
new Net(
this, m_event_handler,
id,
name));
418 auto free_id_it = m_netlist->m_free_net_ids.find(
id);
419 if (free_id_it != m_netlist->m_free_net_ids.end())
421 m_netlist->m_free_net_ids.erase(free_id_it);
424 m_netlist->m_used_net_ids.insert(
id);
427 auto raw = new_net.get();
428 m_netlist->m_nets_map[
id] = std::move(new_net);
429 m_netlist->m_nets_set.insert(raw);
430 m_netlist->m_nets.push_back(raw);
438 bool NetlistInternalManager::delete_net(Net*
net)
445 auto dsts =
net->m_destinations_raw;
446 for (
auto dst : dsts)
448 if (!this->net_remove_destination(
net, dst))
454 auto srcs =
net->m_sources_raw;
455 for (
auto src : srcs)
457 if (!this->net_remove_source(
net, src))
474 auto it = m_netlist->m_nets_map.find(
net->get_id());
475 auto ptr = std::move(it->second);
476 m_netlist->m_nets_map.erase(it);
477 m_netlist->m_nets_set.erase(
net);
480 m_netlist->m_free_net_ids.insert(
net->get_id());
481 m_netlist->m_used_net_ids.erase(
net->get_id());
488 Endpoint* NetlistInternalManager::net_add_source(Net*
net, Gate* gate, GatePin* pin)
495 if (
net->is_a_source(gate, pin))
498 "pin '{}' of gate '{}' with ID {} is already a source of net '{}' with ID {} in netlist with ID {}.",
504 m_netlist->m_netlist_id);
509 auto output_pins = gate->get_type()->get_output_pins();
511 if ((std::find(output_pins.begin(), output_pins.end(), pin) == output_pins.end()))
513 log_error(
"net",
"gate '{}' with ID {} has no output pin called '{}' in netlist with ID {}.", gate->get_name(), gate->get_id(), pin->get_name(), m_netlist->m_netlist_id);
518 if (
auto fan_out_net = gate->get_fan_out_net(pin); fan_out_net !=
nullptr)
521 "gate '{}' with ID {} is already connected to net '{}' with ID {} at output pin '{}', cannot assign new net '{}' with ID {} in netlist with ID {}.",
524 fan_out_net->get_name(),
525 fan_out_net->get_id(),
529 m_netlist->m_netlist_id);
533 auto new_endpoint = std::unique_ptr<Endpoint>(
new Endpoint(gate, pin,
net,
false));
534 auto new_endpoint_raw = new_endpoint.get();
535 net->m_sources.push_back(std::move(new_endpoint));
536 net->m_sources_raw.push_back(new_endpoint_raw);
537 gate->m_out_endpoints.push_back(new_endpoint_raw);
538 gate->m_out_nets.push_back(
net);
541 if (m_net_checks_enabled)
543 if (
const auto res = gate->get_module()->check_net(
net,
true); res.is_error())
545 log_error(
"net",
"{}", res.get_error().get());
549 for (Endpoint* ep :
net->get_destinations())
551 if (
const auto res = ep->get_gate()->get_module()->check_net(
net,
true); res.is_error())
553 log_error(
"net",
"{}", res.get_error().get());
561 return new_endpoint_raw;
564 bool NetlistInternalManager::net_remove_source(Net*
net, Endpoint* ep)
566 auto gate = ep->get_gate();
573 bool removed =
false;
574 for (
u32 i = 0; i <
net->m_sources.size(); ++i)
576 if (
net->m_sources_raw[i] == ep)
580 net->m_sources[i] = std::move(
net->m_sources.back());
581 net->m_sources.pop_back();
582 net->m_sources_raw[i] =
net->m_sources_raw.back();
583 net->m_sources_raw.pop_back();
593 "output pin '{}' of gate '{}' with ID {} is not a source of net '{}' with ID {} in netlist with ID {}",
594 ep->get_pin()->get_name(),
599 m_netlist->m_netlist_id);
604 if (m_net_checks_enabled)
606 if (
const auto res = gate->get_module()->check_net(
net,
true); res.is_error())
608 log_error(
"net",
"{}", res.get_error().get());
612 for (Endpoint* dst :
net->get_destinations())
614 if (
const auto res = dst->get_gate()->get_module()->check_net(
net,
true); res.is_error())
616 log_error(
"net",
"{}", res.get_error().get());
626 Endpoint* NetlistInternalManager::net_add_destination(Net*
net, Gate* gate, GatePin* pin)
633 if (
net->is_a_destination(gate, pin))
636 "pin '{}' of gate '{}' with ID {} is already a destination of net '{}' with ID {} in netlist with ID {}.",
642 m_netlist->m_netlist_id);
647 auto input_pins = gate->get_type()->get_input_pins();
649 if ((std::find(input_pins.begin(), input_pins.end(), pin) == input_pins.end()))
651 log_error(
"net",
"gate '{}' with ID {} has no input pin called '{}' in netlist with ID {}.", gate->get_name(), gate->get_id(), pin->get_name(), m_netlist->m_netlist_id);
656 if (
auto fan_in_net = gate->get_fan_in_net(pin); fan_in_net !=
nullptr)
659 "gate '{}' with ID {} is already connected to net '{}' with ID {} at input pin '{}', cannot assign new net '{}' with ID {} in netlist with ID {}.",
662 fan_in_net->get_name(),
663 fan_in_net->get_id(),
667 m_netlist->m_netlist_id);
671 std::unique_ptr<Endpoint> new_endpoint = std::unique_ptr<Endpoint>(
new Endpoint(gate, pin,
net,
true));
672 Endpoint* new_endpoint_raw = new_endpoint.get();
673 net->m_destinations.push_back(std::move(new_endpoint));
674 net->m_destinations_raw.push_back(new_endpoint_raw);
675 gate->m_in_endpoints.push_back(new_endpoint_raw);
676 gate->m_in_nets.push_back(
net);
679 if (m_net_checks_enabled)
681 if (
const auto res = gate->get_module()->check_net(
net,
true); res.is_error())
683 log_error(
"net",
"{}", res.get_error().get());
687 for (Endpoint* ep :
net->get_sources())
689 if (
const auto res = ep->get_gate()->get_module()->check_net(
net,
true); res.is_error())
691 log_error(
"net",
"{}", res.get_error().get());
699 return new_endpoint_raw;
702 bool NetlistInternalManager::net_remove_destination(Net*
net, Endpoint* ep)
704 auto gate = ep->get_gate();
710 bool removed =
false;
711 for (
u32 i = 0; i <
net->m_destinations.size(); ++i)
713 if (
net->m_destinations_raw[i] == ep)
717 net->m_destinations[i] = std::move(
net->m_destinations.back());
718 net->m_destinations.pop_back();
719 net->m_destinations_raw[i] =
net->m_destinations_raw.back();
720 net->m_destinations_raw.pop_back();
730 "input pin '{}' of gate '{}' with ID {} is not a destination of net '{}' with ID {} in netlist with ID {}",
731 ep->get_pin()->get_name(),
736 m_netlist->m_netlist_id);
740 if (m_net_checks_enabled)
742 if (
const auto res = gate->get_module()->check_net(
net,
true); res.is_error())
744 log_error(
"net",
"{}", res.get_error().get());
748 for (Endpoint* src :
net->get_sources())
750 if (
const auto res = src->get_gate()->get_module()->check_net(
net,
true); res.is_error())
752 log_error(
"net",
"{}", res.get_error().get());
766 Module* NetlistInternalManager::create_module(
const u32 id, Module* parent,
const std::string&
name)
770 log_error(
"module",
"ID 0 represents an invalid module ID.");
773 if (m_netlist->m_used_module_ids.find(
id) != m_netlist->m_used_module_ids.end())
775 log_error(
"module",
"module ID {} is already taken in netlist with ID {}.",
id, m_netlist->m_netlist_id);
780 log_error(
"module",
"module name cannot be empty.");
783 if (parent ==
nullptr && m_netlist->m_top_module !=
nullptr)
785 log_error(
"module",
"parent module cannot not be nullptr.");
788 if (parent !=
nullptr && m_netlist != parent->get_netlist())
790 log_error(
"module",
"parent module must belong to netlist with ID {}.", m_netlist->m_netlist_id);
794 auto m = std::unique_ptr<Module>(
new Module(
this, m_event_handler,
id, parent,
name));
796 auto free_id_it = m_netlist->m_free_module_ids.find(
id);
797 if (free_id_it != m_netlist->m_free_module_ids.end())
799 m_netlist->m_free_module_ids.erase(free_id_it);
802 m_netlist->m_used_module_ids.insert(
id);
805 m_netlist->m_modules_map[
id] = std::move(m);
806 m_netlist->m_modules_set.insert(raw);
807 m_netlist->m_modules.push_back(raw);
809 if (parent !=
nullptr)
811 parent->m_submodules_map[
id] = raw;
812 parent->m_submodules.push_back(raw);
817 if (parent !=
nullptr)
825 bool NetlistInternalManager::delete_module(Module* to_remove)
832 if (to_remove == m_netlist->m_top_module)
840 if (
Grouping*
g = to_remove->get_grouping();
g !=
nullptr)
842 g->remove_module(to_remove);
846 std::vector<Gate*> gates_copy = to_remove->m_gates;
847 to_remove->m_parent->assign_gates(gates_copy);
850 for (
auto sm : to_remove->m_submodules)
852 to_remove->m_parent->m_submodules_map[sm->get_id()] = sm;
853 to_remove->m_parent->m_submodules.push_back(sm);
857 sm->m_parent = to_remove->m_parent;
864 to_remove->m_parent->m_submodules_map.erase(to_remove->get_id());
868 auto it = m_netlist->m_modules_map.find(to_remove->get_id());
869 auto ptr = std::move(it->second);
870 m_netlist->m_modules_map.erase(it);
871 m_netlist->m_modules_set.erase(to_remove);
874 m_netlist->m_free_module_ids.insert(to_remove->get_id());
875 m_netlist->m_used_module_ids.erase(to_remove->get_id());
881 bool NetlistInternalManager::module_assign_gate(Module* m, Gate*
g)
883 return module_assign_gates(m, {
g});
886 bool NetlistInternalManager::module_assign_gates(Module*
module,
const std::vector<Gate*>& gates)
891 log_error(
"module",
"module cannot be a nullptr.");
895 std::map<Module*, u32> prev_modules;
897 for (
const Gate*
g : gates)
901 log_error(
"module",
"gate cannot be a nullptr.");
905 Module* prev_mod =
g->m_module;
910 "gate '{}' with ID {} is already contained in module '{}' with ID {} in netlist with ID {}.",
915 m_netlist->m_netlist_id);
919 if (
auto it = prev_modules.find(prev_mod); it == prev_modules.end())
921 prev_modules[prev_mod] = 1;
930 for (
const auto& [prev_mod, num_gates] : prev_modules)
934 prev_modules.clear();
937 std::unordered_map<Module*, std::unordered_set<Net*>> nets_to_check;
938 for (
Gate*
g : gates)
941 Module* prev_mod =
g->m_module;
942 const auto it = prev_mod->m_gates_map.find(
g->get_id());
943 assert(it != prev_mod->m_gates_map.end());
944 prev_mod->m_gates_map.erase(it);
949 module->m_gates_map[
g->get_id()] =
g;
954 std::vector<Net*> fan_in =
g->get_fan_in_nets();
955 nets_to_check[prev_mod].insert(fan_in.begin(), fan_in.end());
956 nets_to_check[
module].insert(fan_in.begin(), fan_in.end());
958 std::vector<Net*> fan_out =
g->get_fan_out_nets();
959 nets_to_check[prev_mod].insert(fan_out.begin(), fan_out.end());
960 nets_to_check[
module].insert(fan_out.begin(), fan_out.end());
964 if (
auto prev_mod_it = prev_modules.find(prev_mod); prev_mod_it == prev_modules.end())
966 prev_modules[prev_mod] = 1;
970 std::get<1>(*prev_mod_it)++;
974 if (m_net_checks_enabled)
976 for (
const auto& [affected_module, nets] : nets_to_check)
980 if (
const auto res = affected_module->check_net(
net,
true); res.is_error())
982 log_error(
"module",
"{}", res.get_error().get());
990 for (
const auto& [prev_mod, num_gates] : prev_modules)
998 bool NetlistInternalManager::module_check_net(Module*
module, Net*
net,
bool recursive)
1000 if (
const auto res =
module->check_net(
net, recursive); res.is_error())
1011 Grouping* NetlistInternalManager::create_grouping(
u32 id,
const std::string
name)
1015 log_error(
"grouping",
"ID 0 represents an invalid grouping ID.");
1018 if (m_netlist->m_used_grouping_ids.find(
id) != m_netlist->m_used_grouping_ids.end())
1020 log_error(
"grouping",
"grouping ID {} is already taken in netlist with ID {}.",
id, m_netlist->m_netlist_id);
1025 log_error(
"grouping",
"grouping name cannot be empty.");
1029 auto new_grouping = std::unique_ptr<Grouping>(
new Grouping(
this, m_event_handler,
id,
name));
1031 auto free_id_it = m_netlist->m_free_grouping_ids.find(
id);
1032 if (free_id_it != m_netlist->m_free_grouping_ids.end())
1034 m_netlist->m_free_grouping_ids.erase(free_id_it);
1037 m_netlist->m_used_grouping_ids.insert(
id);
1039 auto raw = new_grouping.get();
1041 m_netlist->m_groupings_map[
id] = std::move(new_grouping);
1042 m_netlist->m_groupings_set.insert(raw);
1043 m_netlist->m_groupings.push_back(raw);
1051 bool NetlistInternalManager::delete_grouping(Grouping* grouping)
1058 for (
Gate* gate : grouping->get_gates())
1060 gate->m_grouping =
nullptr;
1063 for (
Net*
net : grouping->get_nets())
1065 net->m_grouping =
nullptr;
1070 module->m_grouping =
nullptr;
1073 auto it = m_netlist->m_groupings_map.find(grouping->get_id());
1074 auto ptr = std::move(it->second);
1075 m_netlist->m_groupings_map.erase(it);
1076 m_netlist->m_groupings_set.erase(grouping);
1080 m_netlist->m_free_grouping_ids.insert(grouping->get_id());
1081 m_netlist->m_used_grouping_ids.erase(grouping->get_id());
1089 bool NetlistInternalManager::grouping_assign_gate(Grouping* grouping, Gate* gate,
bool force)
1091 if (gate ==
nullptr || gate->get_grouping() == grouping)
1096 u32 gate_id = gate->get_id();
1098 if (
Grouping* other = gate->get_grouping(); other !=
nullptr)
1102 other->remove_gate(gate);
1107 "gate '{}' with ID {} is already part of another grouping called '{}' with ID {} in netlist with ID {}.",
1112 m_netlist->m_netlist_id);
1117 grouping->m_gates.push_back(gate);
1118 grouping->m_gates_map.emplace(gate_id, gate);
1119 gate->m_grouping = grouping;
1126 bool NetlistInternalManager::grouping_remove_gate(Grouping* grouping, Gate* gate)
1128 if (gate ==
nullptr)
1133 u32 gate_id = gate->get_id();
1135 if (!grouping->contains_gate(gate))
1138 "gate '{}' with ID {} is not part of grouping '{}' with ID {} in netlist with ID {}.",
1141 grouping->get_name(),
1143 m_netlist->m_netlist_id);
1147 auto vec_it = std::find(grouping->m_gates.begin(), grouping->m_gates.end(), gate);
1149 *vec_it = grouping->m_gates.back();
1150 grouping->m_gates.pop_back();
1151 grouping->m_gates_map.erase(gate_id);
1152 gate->m_grouping =
nullptr;
1159 bool NetlistInternalManager::grouping_assign_net(Grouping* grouping, Net*
net,
bool force)
1161 if (
net ==
nullptr ||
net->get_grouping() == grouping)
1166 u32 net_id =
net->get_id();
1168 if (
Grouping* other =
net->get_grouping(); other !=
nullptr)
1172 other->remove_net(
net);
1177 "net '{}' with ID {} is already part of another grouping called '{}' with ID {} in netlist with ID {}.",
1182 m_netlist->m_netlist_id);
1187 grouping->m_nets.push_back(
net);
1188 grouping->m_nets_map.emplace(net_id,
net);
1189 net->m_grouping = grouping;
1196 bool NetlistInternalManager::grouping_remove_net(Grouping* grouping, Net*
net)
1203 u32 net_id =
net->get_id();
1205 if (!grouping->contains_net(
net))
1208 "net '{}' with ID {} is not part of grouping '{}' with ID {} in netlist with ID {}.",
1211 grouping->get_name(),
1213 m_netlist->m_netlist_id);
1217 auto vec_it = std::find(grouping->m_nets.begin(), grouping->m_nets.end(),
net);
1219 *vec_it = grouping->m_nets.back();
1220 grouping->m_nets.pop_back();
1221 grouping->m_nets_map.erase(net_id);
1222 net->m_grouping =
nullptr;
1229 bool NetlistInternalManager::grouping_assign_module(Grouping* grouping, Module*
module,
bool force)
1242 other->remove_module(
module);
1247 "module '{}' with ID {} is already part of another grouping called '{}' with ID {} in netlist with ID {}.",
1252 m_netlist->m_netlist_id);
1257 grouping->m_modules.push_back(
module);
1258 grouping->m_modules_map.emplace(module_id,
module);
1259 module->m_grouping = grouping;
1266 bool NetlistInternalManager::grouping_remove_module(Grouping* grouping, Module*
module)
1275 if (!grouping->contains_module(
module))
1278 "module '{}' with ID {} is not part of grouping '{}' with ID {} in netlist with ID {}.",
1281 grouping->get_name(),
1283 m_netlist->m_netlist_id);
1287 auto vec_it = std::find(grouping->m_modules.begin(), grouping->m_modules.end(),
module);
1289 *vec_it = grouping->m_modules.back();
1290 grouping->m_modules.pop_back();
1291 grouping->m_modules_map.erase(module_id);
1292 module->m_grouping =
nullptr;
1303 void NetlistInternalManager::clear_caches()
1305 m_lut_function_cache.clear();
const std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string > > & get_data_map() const
std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string > > m_data
NETLIST_API void notify(NetlistEvent::event ev, Netlist *netlist, u32 associated_data=0xFFFFFFFF)
@ removed
no associated_data
@ created
no associated_data
bool contains_gate_type(GateType *gate_type) const
@ net_assigned
associated_data = id of inserted net
@ module_removed
associated_data = id of removed module
@ gate_assigned
associated_data = id of inserted gate
@ module_assigned
associated_data = id of inserted module
@ gate_removed
associated_data = id of removed gate
@ removed
no associated_data
@ net_removed
associated_data = id of removed net
@ created
no associated_data
@ gates_remove_end
associated_data = number of removed gates
@ gate_assigned
associated_data = id of inserted gate
@ gate_removed
associated_data = id of removed gate
@ submodule_removed
associated_data = id of removed module
@ gates_assign_begin
associated_data = number of gates to assign
@ gates_assign_end
associated_data = number of assigned gates
@ gates_remove_begin
associated_data = number of gates to remove
@ submodule_added
associated_data = id of added module
@ removed
no associated_data
@ parent_changed
no associated_data
@ created
no associated_data
std::string get_name() const
Grouping * get_grouping() const
@ src_added
associated_data = id of src gate
@ dst_removed
associated_data = id of dst gate
@ src_removed
associated_data = id of src gate
@ dst_added
associated_data = id of dst gate
@ removed
no associated_data
@ created
no associated_data
bool is_gate_in_netlist(const Gate *gate) const
bool is_module_in_netlist(const Module *module) const
bool unmark_gnd_gate(Gate *gate)
bool is_grouping_in_netlist(const Grouping *grouping) const
bool unmark_vcc_gate(Gate *gate)
bool is_net_in_netlist(const Net *net) const
bool unmark_global_output_net(Net *net)
bool unmark_global_input_net(Net *net)
#define log_error(channel,...)
#define log_warning(channel,...)
#define ERR_APPEND(prev_error, message)
const Module * module(const Gate *g, const NodeBoxes &boxes)
std::unique_ptr< Netlist > create_netlist(const GateLibrary *gate_library)
Create a new empty netlist using the specified gate library.
CORE_API T trim(const T &s, const char *to_remove=" \t\r\n")
CORE_API bool unordered_vector_erase(std::vector< T > &vec, T element)
This file contains various functions to create and load netlists.