14 #include <unordered_set>
18 namespace netlist_utils
22 std::vector<Gate*> get_shortest_path_internal(
Gate* start_gate,
Gate* end_gate)
24 if (start_gate == end_gate)
25 return std::vector<Gate*>();
26 std::vector<Gate*> v0;
27 v0.push_back(start_gate);
28 std::unordered_map<Gate*, Gate*> originMap;
31 std::vector<Gate*> v1;
36 if (originMap.find(g1) != originMap.end())
43 std::vector<Gate*> retval;
45 while (
g != start_gate)
47 retval.insert(retval.begin(),
g);
48 auto it = originMap.find(
g);
49 assert(it != originMap.end());
52 retval.insert(retval.begin(), start_gate);
61 return std::vector<Gate*>();
69 return ERR(
"could not get subgraph function: net is a 'nullptr'");
78 return ERR(res.get_error());
87 return ERR(res.get_error());
97 if (
auto res = nl->
copy(); res.is_error())
99 log_error(
"netlist_utils",
"error encountered while copying netlist:\n{}", res.get_error().get());
110 std::map<u32, Gate*> matrix_id_to_gate;
111 std::map<Gate*, u32> gate_to_matrix_id;
112 std::vector<std::vector<int>> matrix;
114 u32 matrix_gates = 0;
121 gate_to_matrix_id[gate] = matrix_gates;
122 matrix_id_to_gate[matrix_gates] = gate;
126 for (
const auto& [
id, gate] : matrix_id_to_gate)
128 std::vector<int> line_of_matrix;
130 std::set<u32> gates_to_add;
133 gates_to_add.insert(gate_to_matrix_id[pred_gate]);
136 for (
u32 i = 0; i < matrix_gates; i++)
138 if (gates_to_add.find(i) != gates_to_add.end())
140 line_of_matrix.push_back(1);
144 line_of_matrix.push_back(0);
147 matrix.push_back(line_of_matrix);
150 return std::make_pair(matrix_id_to_gate, matrix);
161 log_error(
"netlist_utils",
"error encountered while copying subgraph netlist:\n{}", res.get_error().get());
166 std::vector<Gate*>
get_next_gates(
const Gate* gate,
bool get_successors,
int depth,
const std::function<
bool(
const Gate*)>& filter)
168 std::vector<Gate*> retval;
169 std::unordered_map<u32, std::vector<Gate*>> cache;
170 std::vector<const Gate*> v0;
172 std::unordered_set<const Gate*> gats_handled;
173 std::unordered_set<const Net*> nets_handled;
174 gats_handled.insert(gate);
176 for (
int round = 0; !depth || round < depth; round++)
178 std::vector<const Gate*> v1;
179 for (
const Gate* g0 : v0)
181 for (
const Net*
n : get_successors ? g0->get_fan_out_nets() : g0->get_fan_in_nets())
183 if (nets_handled.find(
n) != nets_handled.end())
187 nets_handled.insert(
n);
189 for (
const Endpoint* ep : get_successors ?
n->get_destinations() :
n->get_sources())
191 Gate* g1 = ep->get_gate();
192 if (gats_handled.find(g1) != gats_handled.end())
196 gats_handled.insert(g1);
197 if (!filter || filter(g1))
200 retval.push_back(g1);
216 std::vector<Gate*> retval;
217 std::unordered_map<u32, std::vector<Gate*>> cache;
218 std::vector<const Gate*> v0;
219 std::unordered_set<const Gate*> gates_handled;
220 std::unordered_set<const Net*> nets_handled;
221 for (
const Endpoint* ep : (get_successors ?
net->get_destinations() :
net->get_sources()))
223 Gate*
g = ep->get_gate();
224 if (!filter || filter(
g))
227 gates_handled.insert(
g);
228 nets_handled.insert(
net);
233 for (
int round = 1; depth == 0 || round < depth; round++)
235 std::vector<const Gate*> v1;
236 for (
const Gate* g0 : v0)
238 for (
const Net*
n : get_successors ? g0->get_fan_out_nets() : g0->get_fan_in_nets())
240 if (nets_handled.find(
n) != nets_handled.end())
244 nets_handled.insert(
n);
246 for (
const Endpoint* ep : get_successors ?
n->get_destinations() :
n->get_sources())
248 Gate* g1 = ep->get_gate();
249 if (gates_handled.find(g1) != gates_handled.end())
253 gates_handled.insert(g1);
254 if (!filter || filter(g1))
257 retval.push_back(g1);
273 std::vector<Gate*> path_forward = get_shortest_path_internal(start_gate, end_gate);
274 if (!search_both_directions)
276 std::vector<Gate*> path_reverse = get_shortest_path_internal(end_gate, start_gate);
277 return (path_reverse.size() < path_forward.size()) ? path_reverse : path_forward;
282 std::vector<Gate*> get_next_sequential_gates_internal(
const Net* start_net,
bool forward, std::unordered_set<u32>& seen, std::unordered_map<
u32, std::vector<Gate*>>& cache)
284 if (
auto it = cache.find(start_net->
get_id()); it != cache.end())
289 if (seen.find(start_net->
get_id()) != seen.end())
294 seen.insert(start_net->
get_id());
296 std::vector<Gate*> found_ffs;
300 auto next_gate = endpoint->get_gate();
304 found_ffs.push_back(next_gate);
308 for (
auto n : forward ? next_gate->get_fan_out_nets() : next_gate->get_fan_in_nets())
310 auto next_gates = get_next_sequential_gates_internal(
n, forward, seen, cache);
311 found_ffs.insert(found_ffs.end(), next_gates.begin(), next_gates.end());
316 std::sort(found_ffs.begin(), found_ffs.end());
317 found_ffs.erase(std::unique(found_ffs.begin(), found_ffs.end()), found_ffs.end());
319 cache.emplace(start_net->
get_id(), found_ffs);
326 std::vector<Gate*> found_ffs;
330 found_ffs.insert(found_ffs.end(), suc.begin(), suc.end());
333 std::sort(found_ffs.begin(), found_ffs.end());
334 found_ffs.erase(std::unique(found_ffs.begin(), found_ffs.end()), found_ffs.end());
341 std::unordered_set<u32> seen;
342 return get_next_sequential_gates_internal(
net, get_successors, seen, cache);
347 std::unordered_map<u32, std::vector<Gate*>> cache;
353 std::unordered_map<u32, std::vector<Gate*>> cache;
360 get_path_internal(
const Net* start_net,
bool forward, std::set<GateTypeProperty> stop_types, std::unordered_set<u32>& seen, std::unordered_map<
u32, std::vector<Gate*>>& cache)
362 if (
auto it = cache.find(start_net->
get_id()); it != cache.end())
367 if (seen.find(start_net->
get_id()) != seen.end())
372 seen.insert(start_net->
get_id());
374 std::vector<Gate*> found_combinational;
378 auto next_gate = endpoint->get_gate();
383 if (stop_types.find(property) != stop_types.end())
391 found_combinational.push_back(next_gate);
393 for (
auto n : forward ? next_gate->get_fan_out_nets() : next_gate->get_fan_in_nets())
395 auto next_gates = get_path_internal(
n, forward, stop_types, seen, cache);
396 found_combinational.insert(found_combinational.end(), next_gates.begin(), next_gates.end());
401 std::sort(found_combinational.begin(), found_combinational.end());
402 found_combinational.erase(std::unique(found_combinational.begin(), found_combinational.end()), found_combinational.end());
404 cache.emplace(start_net->
get_id(), found_combinational);
405 return found_combinational;
409 std::vector<Gate*>
get_path(
const Gate* gate,
bool get_successors, std::set<GateTypeProperty> stop_properties, std::unordered_map<
u32, std::vector<Gate*>>& cache)
411 std::vector<Gate*> found_combinational;
414 auto suc =
get_path(
n, get_successors, stop_properties, cache);
415 found_combinational.insert(found_combinational.end(), suc.begin(), suc.end());
418 std::sort(found_combinational.begin(), found_combinational.end());
419 found_combinational.erase(std::unique(found_combinational.begin(), found_combinational.end()), found_combinational.end());
421 return found_combinational;
424 std::vector<Gate*>
get_path(
const Net*
net,
bool get_successors, std::set<GateTypeProperty> stop_properties, std::unordered_map<
u32, std::vector<Gate*>>& cache)
426 std::unordered_set<u32> seen;
427 return get_path_internal(
net, get_successors, stop_properties, seen, cache);
430 std::vector<Gate*>
get_path(
const Gate* gate,
bool get_successors, std::set<GateTypeProperty> stop_properties)
432 std::unordered_map<u32, std::vector<Gate*>> cache;
433 return get_path(gate, get_successors, stop_properties, cache);
436 std::vector<Gate*>
get_path(
const Net*
net,
bool get_successors, std::set<GateTypeProperty> stop_properties)
438 std::unordered_map<u32, std::vector<Gate*>> cache;
439 return get_path(
net, get_successors, stop_properties, cache);
444 std::vector<Net*> nets;
446 for (
const auto& pin :
pins)
450 log_warning(
"netlist_utils",
"'nullptr' given as pin.");
463 log_warning(
"netlist_utils",
"could not retrieve fan-in net for pin '{}' of gate '{}' with ID {}.", pin->get_name(), gate->
get_name(), gate->
get_id());
474 log_warning(
"netlist_utils",
"could not retrieve fan-out net for pin '{}' of gate '{}' with ID {}.", pin->get_name(), gate->
get_name(), gate->
get_id());
486 for (
const auto& gate :
netlist->get_gates())
497 if (fan_out.size() != 1)
504 if (functions.size() != 1)
510 Endpoint* out_endpoint = *(fan_out.begin());
524 auto sources = ep->get_net()->get_sources();
525 if (sources.size() != 1)
530 if (sources.front()->get_gate()->is_gnd_gate())
534 func = substitution.get();
537 else if (sources.front()->get_gate()->is_vcc_gate())
541 func = substitution.get();
551 if (std::find(in_pins.begin(), in_pins.end(), func_str) != in_pins.end())
556 for (
Endpoint* in_endpoint : fan_in)
558 Net* in_net = in_endpoint->get_net();
560 if (in_endpoint->get_pin()->get_name() == func_str)
565 Gate* dst_gate = dst->get_gate();
566 GatePin* dst_pin = dst->get_pin();
569 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to remove destination from output net '"
570 + out_net->
get_name() +
"' with ID " + std::to_string(out_net->
get_id()) +
" of buffer gate '" + gate->
get_name() +
"' with ID "
571 + std::to_string(gate->
get_id()));
575 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to add destination to input net '"
576 + in_net->
get_name() +
"' with ID " + std::to_string(in_net->
get_id()) +
" of buffer gate '" + gate->
get_name() +
"' with ID "
577 + std::to_string(gate->
get_id()));
586 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to remove destination from input net '"
587 + in_net->
get_name() +
"' with ID " + std::to_string(in_net->
get_id()) +
" of buffer gate '" + gate->
get_name() +
"' with ID "
588 + std::to_string(gate->
get_id()));
598 else if (func_str ==
"0" || func_str ==
"1")
602 const std::vector<Gate*>& gnd_gates =
netlist->get_gnd_gates();
603 const std::vector<Gate*>& vcc_gates =
netlist->get_vcc_gates();
604 if (gnd_gates.empty() || vcc_gates.empty())
608 Net* gnd_net = gnd_gates.front()->get_fan_out_nets().front();
609 Net* vcc_net = vcc_gates.front()->get_fan_out_nets().front();
611 for (
Endpoint* in_endpoint : fan_in)
613 Net* in_net = in_endpoint->get_net();
618 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to remove destination from input net '"
619 + in_net->
get_name() +
"' with ID " + std::to_string(in_net->
get_id()) +
" of buffer gate '" + gate->
get_name() +
"' with ID " + std::to_string(gate->
get_id()));
626 Gate* dst_gate = dst->get_gate();
627 GatePin* dst_pin = dst->get_pin();
630 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to remove destination from output net '"
631 + out_net->
get_name() +
"' with ID " + std::to_string(out_net->
get_id()) +
" of buffer gate '" + gate->
get_name() +
"' with ID "
632 + std::to_string(gate->
get_id()));
636 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to add destination to GND net '"
637 + gnd_net->
get_name() +
"' with ID " + std::to_string(gnd_net->
get_id()));
641 else if (func_str ==
"1")
645 Gate* dst_gate = dst->get_gate();
646 GatePin* dst_pin = dst->get_pin();
649 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to remove destination from output net '"
650 + out_net->
get_name() +
"' with ID " + std::to_string(out_net->
get_id()) +
" of buffer gate '" + gate->
get_name() +
"' with ID "
651 + std::to_string(gate->
get_id()));
655 return ERR(
"could not completely remove buffers from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to add destination to VCC net '"
656 + gnd_net->
get_name() +
"' with ID " + std::to_string(gnd_net->
get_id()));
668 return OK(num_gates);
676 const std::vector<Gate*>& gnd_gates =
netlist->get_gnd_gates();
677 if (gnd_gates.empty())
679 return ERR(
"could not completely remove unused LUT endpoints from netlist with ID " + std::to_string(
netlist->get_id()) +
": no GND net available within netlist");
681 Net* gnd_net = gnd_gates.front()->get_fan_out_nets().front();
684 for (
const auto& gate :
netlist->get_gates([](
const Gate*
g) { return g->get_type()->has_property(GateTypeProperty::c_lut); }))
690 if (functions.size() != 1)
695 auto active_pins = functions.begin()->second.get_variable_names();
698 if (fan_in.size() > active_pins.size())
700 for (
const auto& ep : fan_in)
702 if (std::find(active_pins.begin(), active_pins.end(), ep->get_pin()->get_name()) == active_pins.end())
706 if (!ep->get_net()->remove_destination(gate, pin))
708 return ERR(
"could not completely remove unused LUT endpoints from netlist with ID " + std::to_string(
netlist->get_id())
709 +
": failed to remove inactive endpoint from gate '" + gate->
get_name() +
"' with ID " + std::to_string(gate->
get_id()));
713 return ERR(
"could not completely remove unused LUT endpoints from netlist with ID " + std::to_string(
netlist->get_id()) +
": failed to connect inactive input of gate '"
714 + gate->
get_name() +
"' with ID " + std::to_string(gate->
get_id()) +
" to GND net");
729 threshold = gates.size();
733 std::map<Net*, u32> net_count;
734 for (
Gate*
g : gates)
736 for (
Endpoint* pred :
g->get_predecessors())
738 if (pred->get_gate()->is_gnd_gate() || pred->get_gate()->is_vcc_gate())
743 Net* pred_net = pred->get_net();
744 if (
const auto it = net_count.find(pred_net); it != net_count.end())
750 net_count[pred_net] = 1;
756 std::vector<Net*> common_inputs;
757 for (
const auto& [
n, cnt] : net_count)
759 if (cnt >= threshold)
761 common_inputs.push_back(
n);
765 return common_inputs;
776 return ERR(res.get_error());
781 get_gate_chain(
Gate* start_gate,
const std::vector<const GatePin*>& input_pins,
const std::vector<const GatePin*>& output_pins,
const std::function<
bool(
const Gate*)>& filter)
783 if (start_gate ==
nullptr)
785 return ERR(
"could not detect gate chain at start gate: start gate is a 'nullptr'");
789 if (filter && !filter(start_gate))
791 return ERR(
"could not detect gate chain at start gate '" + start_gate->
get_name() +
"' with ID " + std::to_string(start_gate->
get_id())
792 +
": filter evaluates to 'false' for start gate");
795 std::deque<Gate*> gate_chain = {start_gate};
796 std::unordered_set<Gate*> visited_gates = {start_gate};
798 bool found_next_gate;
801 const Gate* current_gate = start_gate;
804 found_next_gate =
false;
807 std::vector<Endpoint*> successors = current_gate->
get_successors([input_pins, output_pins, target_type, filter](
const GatePin* ep_pin,
Endpoint* ep) {
810 if (output_pins.empty() || std::find(output_pins.begin(), output_pins.end(), ep_pin) != output_pins.end())
812 if (input_pins.empty() || std::find(input_pins.begin(), input_pins.end(), ep->get_pin()) != input_pins.end())
814 if (!filter || filter(ep->get_gate()))
824 if (successors.size() > 1)
827 "detected more than one valid successor gate for gate '{}' with ID {} in netlist with ID {}.",
833 else if (!successors.empty())
835 Gate* suc_gate = successors.at(0)->get_gate();
837 if (visited_gates.find(suc_gate) != visited_gates.end())
839 log_debug(
"netlist_utils",
"detected a loop at gate with ID {}.", suc_gate->
get_id());
843 gate_chain.push_back(suc_gate);
844 visited_gates.insert(suc_gate);
845 current_gate = suc_gate;
846 found_next_gate =
true;
848 }
while (found_next_gate);
851 current_gate = start_gate;
854 found_next_gate =
false;
857 std::vector<Endpoint*> predecessors = current_gate->
get_predecessors([input_pins, output_pins, target_type, filter](
const GatePin* ep_pin,
Endpoint* ep) {
860 if (input_pins.empty() || std::find(input_pins.begin(), input_pins.end(), ep_pin) != input_pins.end())
862 if (output_pins.empty() || std::find(output_pins.begin(), output_pins.end(), ep->get_pin()) != output_pins.end())
864 if (!filter || filter(ep->get_gate()))
874 if (predecessors.size() > 1)
877 "detected more than one valid predecessor gate for gate '{}' with ID {} in netlist with ID {}.",
878 current_gate->get_name(),
879 current_gate->get_id(),
880 current_gate->get_netlist()->get_id());
883 else if (!predecessors.empty())
885 Gate* pred_gate = predecessors.at(0)->get_gate();
887 if (visited_gates.find(pred_gate) != visited_gates.end())
889 log_debug(
"netlist_utils",
"detected a loop at gate with ID {}.", pred_gate->get_id());
893 gate_chain.push_front(pred_gate);
894 visited_gates.insert(pred_gate);
895 current_gate = pred_gate;
896 found_next_gate =
true;
897 log_debug(
"netlist_utils",
"found predecessor gate with ID {}.", pred_gate->get_id());
899 }
while (found_next_gate);
901 return OK(std::vector<Gate*>(gate_chain.begin(), gate_chain.end()));
905 const std::vector<GateType*>& chain_types,
906 const std::map<
GateType*, std::vector<const GatePin*>>& input_pins,
907 const std::map<
GateType*, std::vector<const GatePin*>>& output_pins,
908 const std::function<
bool(
const Gate*)>& filter)
910 if (start_gate ==
nullptr)
912 return ERR(
"could not detect gate chain at start gate: start gate is a 'nullptr'");
914 if (chain_types.size() < 2)
916 return ERR(
"could not detect gate chain at start gate: 'chain_types' comprises less than two target gate types");
918 if (start_gate->
get_type() != chain_types.at(0))
920 return ERR(
"could not detect gate chain at start gate '" + start_gate->
get_name() +
"' with ID " + std::to_string(start_gate->
get_id()) +
": start gate is not of type '"
921 + chain_types.front()->get_name() +
"'");
923 if (filter && !filter(start_gate))
925 return ERR(
"could not detect gate chain at start gate '" + start_gate->
get_name() +
"' with ID " + std::to_string(start_gate->
get_id())
926 +
": filter evaluates to 'false' for start gate");
929 std::deque<Gate*> gate_chain = {start_gate};
930 std::unordered_set<Gate*> visited_gates;
933 u32 current_index = (last_index + 1) % chain_types.size();
936 bool found_next_gate;
937 const Gate* current_gate = start_gate;
940 found_next_gate =
false;
943 GateType* target_type = chain_types.at(current_index);
944 const std::vector<const GatePin*>& inputs = input_pins.at(target_type);
945 const std::vector<const GatePin*>& outputs = output_pins.at(chain_types.at(last_index));
946 std::vector<Endpoint*> successors = current_gate->
get_successors([target_type, inputs, outputs, filter](
const GatePin* ep_pin,
Endpoint* ep) {
949 if (outputs.empty() || std::find(outputs.begin(), outputs.end(), ep_pin) != outputs.end())
951 if (inputs.empty() || std::find(inputs.begin(), inputs.end(), ep->
get_pin()) != inputs.end())
953 if (!filter || filter(ep->
get_gate()))
963 if (successors.size() > 1)
966 "detected more than one valid successor gate for gate '{}' with ID {} in netlist with ID {}.",
972 else if (!successors.empty())
974 Gate* suc_gate = successors.at(0)->get_gate();
976 if (visited_gates.find(suc_gate) != visited_gates.end())
978 log_debug(
"netlist_utils",
"detected a loop at gate with ID {}.", suc_gate->
get_id());
982 gate_chain.push_back(suc_gate);
983 visited_gates.insert(suc_gate);
984 current_gate = suc_gate;
985 last_index = current_index;
986 current_index = (current_index + 1) % chain_types.size();
987 found_next_gate =
true;
989 }
while (found_next_gate);
992 while (current_index != 0)
994 gate_chain.pop_back();
998 current_gate = start_gate;
1000 current_index = chain_types.size() - 1;
1005 found_next_gate =
false;
1008 GateType* target_type = chain_types.at(current_index);
1009 const std::vector<const GatePin*>& inputs = input_pins.at(chain_types.at(last_index));
1010 const std::vector<const GatePin*>& outputs = output_pins.at(target_type);
1014 if (inputs.empty() || std::find(inputs.begin(), inputs.end(), ep_pin) != inputs.end())
1016 if (outputs.empty() || std::find(outputs.begin(), outputs.end(), ep->
get_pin()) != outputs.end())
1018 if (!filter || filter(ep->
get_gate()))
1028 if (predecessors.size() > 1)
1031 "detected more than one valid predecessor gate for gate '{}' with ID {} in netlist with ID {}.",
1037 else if (!predecessors.empty())
1039 Gate* pred_gate = predecessors.at(0)->get_gate();
1041 if (visited_gates.find(pred_gate) != visited_gates.end())
1043 log_debug(
"netlist_utils",
"detected a loop at gate with ID {}.", pred_gate->
get_id());
1047 gate_chain.push_front(pred_gate);
1048 visited_gates.insert(pred_gate);
1049 current_gate = pred_gate;
1050 last_index = current_index;
1051 current_index = (current_index == 0) ? chain_types.size() - 1 : current_index - 1;
1052 found_next_gate =
true;
1054 }
while (found_next_gate);
1057 while (last_index != 0)
1059 gate_chain.pop_front();
1063 return OK(std::vector<Gate*>(gate_chain.begin(), gate_chain.end()));
const std::string & get_name() const
BooleanFunction simplify() const
static std::string to_string(Value value)
static BooleanFunction Const(const BooleanFunction::Value &value)
BooleanFunction substitute(const std::string &old_variable_name, const std::string &new_variable_name) const
GatePin * get_pin() const
Net * get_fan_in_net(const std::string &pin_name) const
const std::vector< Net * > & get_fan_in_nets() const
const std::vector< Endpoint * > & get_fan_out_endpoints() const
GateType * get_type() const
std::vector< Endpoint * > get_predecessors(const std::function< bool(const GatePin *pin, Endpoint *ep)> &filter=nullptr) const
Net * get_fan_out_net(const std::string &pin_name) const
std::vector< Endpoint * > get_successors(const std::function< bool(const GatePin *pin, Endpoint *ep)> &filter=nullptr) const
const std::string & get_name() const
const std::vector< Net * > & get_fan_out_nets() const
const std::vector< Endpoint * > & get_fan_in_endpoints() const
Netlist * get_netlist() const
std::unordered_map< std::string, BooleanFunction > get_boolean_functions(bool only_custom_functions=false) const
std::vector< std::string > get_input_pin_names() const
bool has_property(GateTypeProperty property) const
Endpoint * add_destination(Gate *gate, const std::string &pin_name)
const std::string & get_name() const
std::vector< Endpoint * > get_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
bool remove_destination(Gate *gate, const std::string &pin_name)
std::vector< Endpoint * > get_sources(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
const std::vector< Gate * > & get_gates() const
Result< std::unique_ptr< Netlist > > copy() const
Result< Gate * > replace_gate(Gate *gate, GateType *target_type, const std::map< GatePin *, GatePin * > &pin_map)
Result< std::unique_ptr< Netlist > > copy_subgraph_netlist(const std::vector< const Gate * > &subgraph_gates, const bool all_global_io=false) const
Result< BooleanFunction > get_subgraph_function(const std::vector< const Gate * > &subgraph_gates, const Net *subgraph_output, std::map< std::pair< u32, const GatePin * >, BooleanFunction > &cache) const
#define log_error(channel,...)
#define log_debug(channel,...)
#define log_warning(channel,...)
std::vector< Net * > get_common_inputs(const std::vector< Gate * > &gates, u32 threshold)
std::unique_ptr< Netlist > get_partial_netlist(const Netlist *nl, const std::vector< const Gate * > &subgraph_gates)
std::vector< Gate * > get_next_gates(const Gate *gate, bool get_successors, int depth, const std::function< bool(const Gate *)> &filter)
Result< std::vector< Gate * > > get_gate_chain(Gate *start_gate, const std::vector< const GatePin * > &input_pins, const std::vector< const GatePin * > &output_pins, const std::function< bool(const Gate *)> &filter)
Result< std::vector< Gate * > > get_complex_gate_chain(Gate *start_gate, const std::vector< GateType * > &chain_types, const std::map< GateType *, std::vector< const GatePin * >> &input_pins, const std::map< GateType *, std::vector< const GatePin * >> &output_pins, const std::function< bool(const Gate *)> &filter)
std::vector< Gate * > get_path(const Gate *gate, bool get_successors, std::set< GateTypeProperty > stop_properties, std::unordered_map< u32, std::vector< Gate * >> &cache)
std::unique_ptr< Netlist > copy_netlist(const Netlist *nl)
Result< std::monostate > replace_gate(Gate *gate, GateType *target_type, std::map< GatePin *, GatePin * > pin_map)
std::vector< Net * > get_nets_at_pins(Gate *gate, std::vector< GatePin * > pins)
Result< u32 > remove_unused_lut_endpoints(Netlist *netlist)
Result< BooleanFunction > get_subgraph_function(const Net *net, const std::vector< const Gate * > &subgraph_gates, std::map< std::pair< u32, const GatePin * >, BooleanFunction > &cache)
std::vector< Gate * > get_next_sequential_gates(const Gate *gate, bool get_successors, std::unordered_map< u32, std::vector< Gate * >> &cache)
std::vector< Gate * > get_shortest_path(Gate *start_gate, Gate *end_gate, bool search_both_directions)
std::pair< std::map< u32, Gate * >, std::vector< std::vector< int > > > get_ff_dependency_matrix(const Netlist *nl)
Result< u32 > remove_buffers(Netlist *netlist, bool analyze_inputs)
std::vector< PinInformation > pins
This file contains various functions to create and load netlists.