16 namespace module_identification
18 Result::Result(
Netlist* nl,
const std::vector<std::pair<BaseCandidate, VerifiedCandidate>>& result,
const std::string& timing_stats_json)
19 : m_netlist{nl}, m_candidates{result}, m_timing_stats_json{timing_stats_json}
30 std::map<u32, std::vector<Gate*>> result;
32 for (
u32 idx = 0; idx < m_candidates.size(); idx++)
34 const auto& [base_candidate, verified_candidate] = m_candidates[idx];
35 if (verified_candidate.is_verified())
37 result.insert(std::make_pair(idx, verified_candidate.m_gates));
45 std::map<u32, VerifiedCandidate> result;
46 for (
u32 idx = 0; idx < m_candidates.size(); idx++)
48 const auto& [base_candidate, verified_candidate] = m_candidates[idx];
49 if (verified_candidate.is_verified())
51 result.insert(std::make_pair(idx, verified_candidate));
59 std::map<u32, std::vector<Gate*>> result;
60 for (
u32 idx = 0; idx < m_candidates.size(); idx++)
62 const auto& [base_candidate, verified_candidate] = m_candidates[idx];
63 result.insert(std::make_pair(idx, verified_candidate.m_gates));
70 std::map<u32, VerifiedCandidate> result;
71 for (
u32 idx = 0; idx < m_candidates.size(); idx++)
73 const auto& [base_candidate, verified_candidate] = m_candidates[idx];
74 result.insert(std::make_pair(idx, verified_candidate));
81 if (
id >= m_candidates.size())
83 return ERR(
"cannot get candidate with id " + std::to_string(
id));
86 const auto& [base_candidate, verified_candidate] = m_candidates[
id];
87 if (verified_candidate.is_verified())
89 return OK(verified_candidate.m_gates);
93 return OK(base_candidate.m_gates);
99 if (
id >= m_candidates.size())
101 return ERR(
"cannot get candidate with id " + std::to_string(
id));
103 auto [base_candidate, verified_candidate] = m_candidates[
id];
104 return OK(verified_candidate);
109 std::set<Gate*> result;
110 for (
const auto& [base_candidate, verified_candidate] : m_candidates)
112 if (verified_candidate.is_verified())
114 std::copy(verified_candidate.m_gates.begin(), verified_candidate.m_gates.end(), std::inserter(result, result.end()));
118 std::copy(base_candidate.m_gates.begin(), base_candidate.m_gates.end(), std::inserter(result, result.end()));
126 std::set<Gate*> result;
127 for (
const auto& [base_candidate, verified_candidate] : m_candidates)
129 if (verified_candidate.is_verified())
131 std::copy(verified_candidate.m_gates.begin(), verified_candidate.m_gates.end(), std::inserter(result, result.end()));
139 std::pair<std::map<Gate*, std::vector<u32>>, std::map<Gate*, std::vector<u32>>> check_for_conflicting_gates(
const std::vector<std::pair<BaseCandidate, VerifiedCandidate>>& candidates)
141 std::map<Gate*, std::vector<u32>> gate_to_candidates;
142 std::map<Gate*, std::vector<u32>> conflicts;
144 u32 candidate_id = 0;
145 for (
auto [base_cand, verified_cand] : candidates)
147 if (verified_cand.is_verified())
149 for (
auto gate : verified_cand.m_gates)
151 if (gate_to_candidates.find(gate) == gate_to_candidates.end())
153 gate_to_candidates.insert(std::make_pair(gate, std::vector<u32>()));
155 gate_to_candidates[gate].push_back(candidate_id);
160 for (
auto cur_gate : base_cand.m_gates)
162 if (gate_to_candidates.find(cur_gate) == gate_to_candidates.end())
164 gate_to_candidates.insert(std::make_pair(cur_gate, std::vector<u32>()));
166 gate_to_candidates[cur_gate].push_back(candidate_id);
172 for (
auto [gate, list] : gate_to_candidates)
176 conflicts.insert(std::make_pair(gate, list));
180 return {gate_to_candidates, conflicts};
183 std::pair<Gate*, u32> get_possible_conflict(
const std::map<Gate*, std::vector<u32>>& conflicts)
186 for (
auto [gate, conflicting_candidates] : conflicts)
188 std::set<u32> successor_conflicts;
189 for (
const auto& ep : gate->get_fan_out_endpoints())
191 for (
const auto& dest : ep->get_net()->get_destinations())
193 if (dest->get_gate() ==
nullptr)
197 if (conflicts.find(dest->get_gate()) == conflicts.end())
201 const auto& dest_conflicts = conflicts.at(dest->get_gate());
202 for (
u32 dest_conflict : dest_conflicts)
204 successor_conflicts.insert(dest_conflict);
210 for (
u32 conflict_id : conflicting_candidates)
212 if (std::find(successor_conflicts.begin(), successor_conflicts.end(), conflict_id) == successor_conflicts.end())
215 return std::make_pair(gate, conflict_id);
221 "could not resolve conflicts in duplicate gates due to cyclic dependency. Continuing with following broken gate: {}",
222 conflicts.begin()->first->get_name());
224 return std::make_pair(conflicts.begin()->first, conflicts.begin()->second[0]);
227 void resolve_conflicts_by_cloning(Netlist* nl,
228 std::map<Gate*, std::vector<u32>>& conflicts,
229 std::map<Gate*, std::vector<u32>>& gate_to_candidates,
230 std::vector<std::pair<BaseCandidate, VerifiedCandidate>>& candidates)
233 while (conflicts.size() > 0)
235 std::pair<Gate*, u32> available_conflict = get_possible_conflict(conflicts);
240 auto gate = available_conflict.first;
241 auto current_candidate = available_conflict.second;
243 u32 new_gate_id = nl->get_unique_gate_id();
244 std::string new_gate_name = gate->get_name() +
"_CLONE_" + std::to_string(gate->get_id()) +
"_" + std::to_string(new_gate_id);
245 Gate* new_gate = nl->create_gate(new_gate_id, gate->get_type(), new_gate_name);
248 for (
const auto& [pin, bf] : gate->get_boolean_functions())
250 new_gate->add_boolean_function(pin, bf);
254 for (
const auto& ep : gate->get_fan_in_endpoints())
256 ep->get_net()->add_destination(new_gate, ep->get_pin());
260 new_gate->set_data_map(gate->get_data_map());
263 std::vector<Gate*>* relevant_vector;
264 auto& [base_candidate, verified_candidate] = candidates[current_candidate];
265 if (verified_candidate.is_verified())
267 relevant_vector = &(verified_candidate.m_gates);
271 relevant_vector = &(base_candidate.m_gates);
273 std::vector<Gate*>::iterator position = std::find(relevant_vector->begin(), relevant_vector->end(), gate);
274 if (position != relevant_vector->end())
276 relevant_vector->erase(position);
280 log_error(
"module_identification",
"trying to erase gate {} / {} from candidate that the gate is not part of", gate->get_id(), gate->get_name());
282 relevant_vector->push_back(new_gate);
284 gate_to_candidates.insert({new_gate, {current_candidate}});
287 std::vector<u32>::iterator old_id_position = std::find(gate_to_candidates[gate].begin(), gate_to_candidates[gate].end(), current_candidate);
288 if (old_id_position != gate_to_candidates[gate].end())
290 gate_to_candidates[gate].erase(old_id_position);
294 log_error(
"module_identification",
"trying to erase gate {} / {} from candidate that the gate is not part of", gate->get_id(), gate->get_name());
298 std::map<GatePin*, std::map<Gate*, std::vector<GatePin*>>> new_destinations;
299 for (
const auto& ep : gate->get_fan_out_endpoints())
301 for (
const auto& dest : ep->get_net()->get_destinations())
303 if (dest->get_gate() ==
nullptr)
309 auto dest_gate_mod = gate_to_candidates.find(dest->get_gate());
310 if (dest_gate_mod == gate_to_candidates.end())
322 const auto& dest_mod_vec = dest_gate_mod->second;
323 if (std::find(dest_mod_vec.begin(), dest_mod_vec.end(), current_candidate) == dest_mod_vec.end())
332 new_destinations[ep->get_pin()][dest->get_gate()].push_back(dest->get_pin());
338 ep->get_net()->remove_destination(dest);
344 if (verified_candidate.is_verified()
345 && (std::find(verified_candidate.m_output_nets.begin(), verified_candidate.m_output_nets.end(), ep->get_net()) != verified_candidate.m_output_nets.end()))
350 u32 new_net_id = nl->get_unique_net_id();
351 std::string new_net_name =
"n" + std::to_string(new_net_id) +
"_OUTPUT";
352 Net* new_net = nl->create_net(new_net_id, new_net_name);
355 new_net->add_source(new_gate, ep->get_pin());
357 std::replace(verified_candidate.m_output_nets.begin(), verified_candidate.m_output_nets.end(), ep->get_net(), new_net);
362 for (
const auto& [src_pin, destinations] : new_destinations)
365 if (
auto fan_out_net = new_gate->get_fan_out_net(src_pin); fan_out_net !=
nullptr)
367 new_net = fan_out_net;
371 u32 new_net_id = nl->get_unique_net_id();
372 std::string new_net_name =
"n" + std::to_string(new_net_id) +
"_CLONED";
373 new_net = nl->create_net(new_net_id, new_net_name);
375 if (!new_net->add_source(new_gate, src_pin))
378 "failed to add source to net {} with ID {} at gate {} with ID {} and pin {}",
381 new_gate->get_name(),
383 src_pin->get_name());
391 for (
const auto& [dest_gate, dest_pins] : destinations)
393 for (
const auto& dest_pin : dest_pins)
395 if (!new_net->add_destination(dest_gate, dest_pin))
398 "failed to add destination to net {} with ID {} at gate {} with ID {} and pin {}",
401 dest_gate->get_name(),
403 dest_pin->get_name());
410 std::vector<u32>::iterator conflict_position = std::find(conflicts[gate].begin(), conflicts[gate].end(), current_candidate);
411 if (conflict_position != conflicts[gate].end())
413 conflicts[gate].erase(conflict_position);
415 if (conflicts[gate].
size() <= 1)
417 conflicts.erase(gate);
430 std::vector<std::pair<BaseCandidate, VerifiedCandidate>> filtered_candidates;
432 for (
u32 i = 0; i < m_candidates.size(); i++)
434 const auto& [bi, vi] = m_candidates.at(i);
435 if (vi.is_verified())
437 filtered_candidates.push_back(m_candidates.at(i));
442 for (
u32 j = 0; i < m_candidates.size(); j++)
449 const auto& [bj, vj] = m_candidates.at(j);
451 if (!vj.is_verified())
465 filtered_candidates.push_back(m_candidates.at(i));
469 auto [gate_to_candidates, conflicts] = check_for_conflicting_gates(filtered_candidates);
471 resolve_conflicts_by_cloning(m_netlist, conflicts, gate_to_candidates, filtered_candidates);
473 std::map<std::string, u32> type_counter;
475 for (
u32 candidate_idx = 0; candidate_idx < filtered_candidates.size(); candidate_idx++)
477 auto& [base_candidate, selected_candidate] = filtered_candidates.at(candidate_idx);
479 const std::string candidate_name = selected_candidate.get_name();
481 if (type_counter.find(candidate_name) == type_counter.end())
483 type_counter.insert(std::make_pair(candidate_name, 0));
486 const auto mod_gates = selected_candidate.is_verified() ? selected_candidate.m_gates : selected_candidate.m_base_gates;
488 auto mod = m_netlist->
create_module(candidate_name +
"_" + std::to_string(type_counter[candidate_name]), m_netlist->
get_top_module(), mod_gates);
489 type_counter[candidate_name]++;
491 std::set<u32> ctrl_mapping_values;
492 for (
const auto& cm : selected_candidate.m_control_signal_mappings)
495 for (
const auto& [
net, val] : cm)
500 ctrl_mapping_values.insert(ctrl_val);
503 mod->
set_data(
"ModuleIdentification",
"VERIFIED_CANDIDATE_ID",
"String", std::to_string(candidate_idx));
505 mod->set_data(
"ModuleIdentification",
"VERIFIED_TYPES",
"String",
utils::join(
", ", selected_candidate.m_types));
507 mod->set_data(
"ModuleIdentification",
"CTRL_MAPPINGS",
"String",
utils::join(
", ", ctrl_mapping_values));
509 std::string word_level_operation_str =
"";
510 for (
const auto& [cm, bf] : selected_candidate.m_word_level_operations)
513 for (
const auto& [
net, val] : cm)
518 word_level_operation_str += std::to_string(ctrl_val) +
": " + bf.to_string() +
"\n";
521 mod->set_data(
"ModuleIdentification",
"OPERATIONS",
"String", word_level_operation_str);
525 const std::vector<std::string> op_names = {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"J",
"K",
"L",
"M",
"N",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W"};
527 if (selected_candidate.m_operands.size() > op_names.size())
529 return ERR(
"cannot create modules: encountered candidate with more operands than operand names");
532 std::map<std::string, std::vector<Net*>> named_operands;
533 for (
u32 op_idx = 0; op_idx < selected_candidate.m_operands.size(); op_idx++)
535 named_operands.insert({op_names.at(op_idx), selected_candidate.m_operands.at(op_idx)});
539 std::map<Net*, std::map<std::string, std::vector<u32>>> nets_to_indices;
540 for (
const auto& [
name, nets] : named_operands)
542 for (
u32 idx = 0; idx < nets.size(); idx++)
544 const auto&
net = nets.at(idx);
545 nets_to_indices[
net][
name].push_back(idx);
563 std::set<Net*> visited;
564 for (
const auto& [
name, nets] : named_operands)
566 std::vector<hal::ModulePin*> operand_pins;
567 for (
const auto&
net : nets)
569 auto pin = mod->get_pin_by_net(
net);
572 log_error(
"module_identification",
"module {} / {} does not have a pin connected to net {} / {}", mod->get_name(), mod->get_id(),
net->get_name(),
net->get_id());
577 if (std::find(visited.begin(), visited.end(),
net) != visited.end())
584 std::vector<std::string> operand_pin_names;
585 for (
const auto& [op_name, indices] : nets_to_indices.at(
net))
587 operand_pin_names.push_back(op_name +
"_" +
utils::join(
", ", indices));
589 std::string new_pin_name =
utils::join(
" | ", operand_pin_names);
591 mod->set_pin_name(pin, new_pin_name);
592 operand_pins.push_back(pin);
595 std::reverse(operand_pins.begin(), operand_pins.end());
599 log_error(
"module_identification",
"could not create input pin group: {}", res.get_error().get());
604 std::vector<hal::ModulePin*> output_pins;
606 for (
const auto& out_net : selected_candidate.m_output_nets)
608 auto pin = mod->get_pin_by_net(out_net);
611 log_error(
"module_identification",
"module {} / {} does not have a pin connected to net {} / {}", mod->get_name(), mod->get_id(), out_net->get_name(), out_net->get_id());
615 std::string pin_name =
"OUT_" + std::to_string(
counter++);
616 mod->set_pin_name(pin, pin_name);
617 output_pins.push_back(pin);
620 std::reverse(output_pins.begin(), output_pins.end());
622 if (output_res.is_error())
624 hal::log_error(
"module_identification",
"could not create output pin group: {}", output_res.get_error().get());
629 std::vector<hal::ModulePin*> ctrl_pins;
630 for (
const auto& ctrl_net : selected_candidate.m_control_signals)
632 auto pin = mod->get_pin_by_net(ctrl_net);
635 log_error(
"module_identification",
"module {} / {} does not have a pin connected to net {} / {}", mod->get_name(), mod->get_id(), ctrl_net->get_name(), ctrl_net->get_id());
639 std::string pin_name =
"CTRL_" + std::to_string(
counter++);
640 mod->set_pin_name(pin, pin_name);
641 ctrl_pins.push_back(pin);
643 if (!ctrl_pins.empty())
645 std::reverse(ctrl_pins.begin(), ctrl_pins.end());
647 if (ctrl_res.is_error())
649 log_info(
"module_identification",
"could not create ctrl pin group: {}", ctrl_res.get_error().get());
654 std::string word_level_operation_hr_str =
"";
655 for (
const auto& [cm, bf] : selected_candidate.m_word_level_operations)
658 for (
const auto& [
net, val] : cm)
664 if (bf_hr_res.is_error())
666 log_warning(
"module_identification",
"{}", bf_hr_res.get_error().get());
669 const auto bf_hr = bf_hr_res.get().simplify_local();
671 word_level_operation_hr_str += std::to_string(ctrl_val) +
": " + bf_hr.to_string() +
"\n";
674 mod->set_data(
"ModuleIdentification",
"OPERATIONS_HR",
"String", word_level_operation_hr_str);
682 return m_timing_stats_json;
687 std::unordered_set<Gate*> base_gates;
688 std::map<const std::set<Gate*>, std::vector<VerifiedCandidate>> base_candidate_to_verified_candidate;
690 for (
const auto& [bc, vc] : other.m_candidates)
692 const std::set<Gate*> bc_set = {bc.m_gates.begin(), bc.m_gates.end()};
695 if (
auto it = base_candidate_to_verified_candidate.find(bc_set); it != base_candidate_to_verified_candidate.end())
697 it->second.push_back(vc);
702 for (
const auto& g : bc.m_gates)
706 return ERR(
"failed to merge results: other result contains a base candidate with a nullptr gate");
711 return ERR(
"failed to merge results: base candidate gate " + std::to_string((
u64)(
void**)g) +
" is not (or no longer) part of the netlist!");
720 base_gates.insert(g);
724 base_candidate_to_verified_candidate[bc_set].push_back(vc);
727 for (
const auto& [bc, vc] : m_candidates)
729 const std::set<Gate*> bc_set = {bc.m_gates.begin(), bc.m_gates.end()};
732 if (
auto it = base_candidate_to_verified_candidate.find(bc_set); it != base_candidate_to_verified_candidate.end())
734 it->second.push_back(vc);
739 for (
const auto& g : bc.m_gates)
743 return ERR(
"failed to merge results: result contains a base candidate with a nullptr gate");
748 return ERR(
"failed to merge results: base candidate gate " + std::to_string((
u64)(
void**)g) +
" is not part of the netlist!");
757 base_gates.insert(g);
761 base_candidate_to_verified_candidate[bc_set].push_back(vc);
764 std::vector<std::pair<BaseCandidate, VerifiedCandidate>> result_candidates;
765 for (
auto& [bc_set, vc] : base_candidate_to_verified_candidate)
767 result_candidates.push_back(std::make_pair(
BaseCandidate({bc_set.begin(), bc_set.end()}),
post_processing(vc, this->m_netlist, dana_cache)));
770 return OK(
Result{this->m_netlist, result_candidates});
779 std::set<Net*> covered_nets;
782 for (
const auto&
net : op)
784 if (
net->is_gnd_net() ||
net->is_vcc_net())
788 covered_nets.insert(
net);
794 u64 ignored_inputs = 0;
797 if (covered_nets.find(input_net) == covered_nets.end())
803 return ignored_inputs;
807 u64 calculate_ignored_output_signals(
const VerifiedCandidate& vc)
809 const auto all_outputs = vc.m_total_output_nets.size();
810 const auto c_outputs = vc.m_output_nets.size();
811 const auto outputs_ignored = (c_outputs > all_outputs) ? 0 : all_outputs - c_outputs;
813 return outputs_ignored;
816 u64 calculate_ctrl_score(
const VerifiedCandidate& vc)
818 return vc.m_control_signals.size();
821 u64 compute_total_io_score(
const VerifiedCandidate& vc)
823 std::set<Net*> total_data_io;
824 for (
const auto& nets : vc.m_operands)
826 for (
const auto& n : nets)
828 if (n->is_gnd_net() || n->is_vcc_net())
832 total_data_io.insert(n);
835 for (
const auto& n : vc.m_output_nets)
837 total_data_io.insert(n);
840 return (
u64)total_data_io.size();
843 u64 compute_is_verified(
const VerifiedCandidate& vc)
845 return (vc.is_verified() ? 1 : 0);
848 bool compare_candidates(
const VerifiedCandidate& vc1,
const VerifiedCandidate& vc2)
850 const std::vector<std::pair<bool, std::function<
u64(
const VerifiedCandidate&)>>> metrics = {
851 {
false, compute_is_verified}, {
false, compute_total_io_score}, {
true, calculate_ignored_input_signals}, {
true, calculate_ctrl_score}, {
true, calculate_ignored_output_signals}};
853 for (
const auto& [higher_is_better, metric_func] : metrics)
855 const auto score_1 = metric_func(vc1);
856 const auto score_2 = metric_func(vc2);
858 if (score_1 < score_2)
860 return higher_is_better;
862 else if (score_1 > score_2)
864 return !higher_is_better;
875 std::set<std::set<Gate*>> all_base_candidates;
876 for (
const auto& res : iteration_results)
878 for (
const auto& [bc, _] : res.m_candidates)
880 all_base_candidates.insert({bc.m_gates.begin(), bc.m_gates.end()});
885 std::map<const std::set<Gate*>, std::vector<std::pair<u32, VerifiedCandidate>>> base_candidate_to_verified_candidates;
887 for (
u32 iteration_idx = 0; iteration_idx < iteration_results.size(); iteration_idx++)
889 const auto& res = iteration_results.at(iteration_idx);
891 for (
const auto& bc : all_base_candidates)
894 std::find_if(res.m_candidates.begin(), res.m_candidates.end(), [&bc](
const auto& p) { return std::set<Gate*>{p.first.m_gates.begin(), p.first.m_gates.end()} == bc; });
896 if (it == res.m_candidates.end())
898 base_candidate_to_verified_candidates[bc].push_back({iteration_idx,
VerifiedCandidate{}});
902 base_candidate_to_verified_candidates[bc].push_back({iteration_idx, it->second});
907 std::vector<std::vector<std::set<Gate*>>> iteration_assignments{iteration_results.size()};
909 for (
const auto& [bc, candidates] : base_candidate_to_verified_candidates)
912 auto candidates_sorted = candidates;
913 std::sort(candidates_sorted.begin(), candidates_sorted.end(), [](
const auto& p1,
const auto& p2) { return compare_candidates(p1.second, p2.second); });
914 const auto best_iteration = candidates_sorted.front().first;
917 const std::string base_name = candidates_sorted.front().second.m_base_gates.empty() ?
"EMPTY" : candidates_sorted.front().second.m_base_gates.front()->get_name();
918 std::cout <<
"Found the following candidates [" << base_name <<
"]: " << std::endl;
919 for (
const auto& [it_idx, c] : candidates)
922 std::cout << it_idx <<
" - " << c.is_verified() <<
" " <<
enum_to_string(c_type) <<
" [" << compute_total_io_score(c) <<
" " << calculate_ignored_input_signals(c) <<
" "
923 << calculate_ctrl_score(c) <<
" " << calculate_ignored_output_signals(c) <<
"]" << std::endl;
925 std::cout <<
"Chose iteration " << best_iteration <<
" as best iteration." << std::endl;
928 for (
u32 iteration_idx = 0; iteration_idx < iteration_results.size(); iteration_idx++)
930 bool assign_to_iteration = create_block_lists ? (iteration_idx != best_iteration) : (iteration_idx == best_iteration);
931 if (assign_to_iteration)
933 iteration_assignments.at(iteration_idx).push_back(bc);
939 for (
u32 idx = 0; idx < iteration_assignments.size(); idx++)
941 std::cout <<
"Iteration Assignment " << idx <<
": " << std::endl;
942 for (
const auto& gate_vec : iteration_assignments.at(idx))
944 std::cout <<
"\t" << (*gate_vec.begin())->get_id() <<
" - " << (*gate_vec.begin())->get_name() << std::endl;
948 return iteration_assignments;
This file contains the enumeration and constants for the candidate types used in the module identific...
Result< BooleanFunction > substitute_module_pins(const std::vector< Module * > &modules) const
bool set_data(const std::string &category, const std::string &key, const std::string &data_type, const std::string &value, const bool log_with_info_level=false)
bool contains_gate(Gate *gate, bool recursive=false) const
Module * get_top_module() const
Module * create_module(const u32 module_id, const std::string &name, Module *parent, const std::vector< Gate * > &gates={})
Represents a base candidate in the module identification process.
Represents a verified candidate for module identification.
std::vector< Net * > m_control_signals
std::vector< Net * > m_total_input_nets
std::vector< std::vector< Net * > > m_operands
#define log_error(channel,...)
#define log_info(channel,...)
#define log_warning(channel,...)
VerifiedCandidate post_processing(const std::vector< VerifiedCandidate > &verified_candidates, const Netlist *nl, const std::vector< std::vector< Gate * >> &dana_cache)
Performs post-processing on a set of verified candidates to identify the best candidate for module id...
@ counter
Counter operation.
T replace(const T &str, const T &search, const T &replace)
bool is_subset(const T1 &subset, const T2 &superset)
std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
std::string enum_to_string(T e)
This file contains the structures and functions related to module identification results.
This file contains helper functions for module identification in the HAL framework.
This file contains the function to perform post-processing on verified candidates to identify the bes...
The result of a module identification run containing the candidates.
std::map< u32, std::vector< Gate * > > get_candidate_gates() const
Get a map of the candidate IDs to the gates contained inside the candidate.
std::map< u32, VerifiedCandidate > get_candidates() const
Get a map of the candidate IDs to the candidates.
hal::Result< Result > merge(const Result &other, const std::vector< std::vector< Gate * >> ®isters) const
Merges two results by combining the found verified candidates.
std::set< Gate * > get_all_gates() const
Get all gates contained in any of the candidates.
std::map< u32, std::vector< Gate * > > get_verified_candidate_gates() const
Get a map of the candidate IDs to the gates contained inside the verified candidates.
std::set< Gate * > get_all_verified_gates() const
Get all gates contained in any of the verified candidates.
static std::vector< std::vector< std::set< Gate * > > > assign_base_candidates_to_iterations(const std::vector< Result > &iteration_results, const bool create_block_lists=false)
For different runs of the plugin figure out in which iteration the plugin found the highest quality r...
Netlist * get_netlist() const
Get the netlist on which module identification has been performed.
hal::Result< std::monostate > create_modules_in_netlist()
Creates a HAL module for each candidate of the result.
Result(Netlist *nl, const std::vector< std::pair< BaseCandidate, VerifiedCandidate >> &result, const std::string &timing_stats_json="")
Constructor for Result.
hal::Result< std::vector< Gate * > > get_candidate_gates_by_id(const u32 id) const
Get the gates of the candidate with the corresponding ID.
std::string get_timing_stats() const
Get the collected timing information formatted as a JSON string.
hal::Result< VerifiedCandidate > get_candidate_by_id(const u32 id) const
Returns the candidate with the corresponding ID.
std::map< u32, VerifiedCandidate > get_verified_candidates() const
Get a map of the candidate IDs to the verified candidates.