23 namespace module_identification
27 std::set<Net*> in_nets;
31 for (
Net* n : g->get_fan_in_nets())
33 if (!(n->is_gnd_net()) && !(n->is_vcc_net()))
35 if (n->is_global_input_net())
41 if (n->get_num_of_sources() > 1)
43 log_error(
"module_identification",
"Found multi driven net {} with ID {}! This is not handled yet!", n->get_name(), n->get_id());
49 if (std::find(gates.begin(), gates.end(), s->get_gate()) == gates.end())
58 return {in_nets.begin(), in_nets.end()};
61 std::vector<Net*>
get_output_nets(
const std::vector<Gate*>& gates,
bool only_external_destinations)
63 std::set<Net*> out_nets;
67 for (
Net* n : g->get_fan_out_nets())
69 if (n->is_global_output_net())
77 if (only_external_destinations)
79 is_output_net = !n->get_destinations().empty();
80 for (
Endpoint* d : n->get_destinations())
82 if (std::find(gates.begin(), gates.end(), d->get_gate()) != gates.end())
84 is_output_net =
false;
92 is_output_net =
false;
93 for (
Endpoint* d : n->get_destinations())
95 if (std::find(gates.begin(), gates.end(), d->get_gate()) == gates.end())
110 return {out_nets.begin(), out_nets.end()};
115 std::set<u32> reg_indices;
118 const auto seq_inputs_res =
120 if (seq_inputs_res.is_error())
122 log_error(
"module_identification",
"{}", seq_inputs_res.get_error().get());
124 const auto seq_inputs = seq_inputs_res.get();
126 for (
const auto& si : seq_inputs)
128 for (
u32 reg_idx = 0; reg_idx < registers.size(); reg_idx++)
130 const auto& reg = registers.at(reg_idx);
131 if (std::find(reg.begin(), reg.end(), si) != reg.end())
133 reg_indices.insert(reg_idx);
144 std::set<u32> reg_indices;
146 for (
const auto& n : nets)
149 reg_indices.insert(neighbors.begin(), neighbors.end());
157 std::vector<std::vector<u32>> permutations(
const std::vector<u32>& initial)
159 std::vector<u32> p = initial;
160 std::vector<std::vector<u32>> result;
162 std::sort(p.begin(), p.end());
166 result.push_back({p.begin(), p.end()});
167 }
while (std::next_permutation(p.begin(), p.end()));
172 u32 calculate_permuation_score(
const std::vector<u32>& permutation,
const std::vector<std::set<u32>>& neighboring_regs,
const std::vector<std::set<u32>>& new_neighboring_regs)
175 u32 non_over_lapping = 0;
176 for (
u32 op_idx = 0; op_idx < permutation.size(); op_idx++)
178 const u32 new_op_idx = permutation.at(op_idx);
180 std::vector<u32> intersection;
181 std::set_intersection(neighboring_regs.at(op_idx).begin(),
182 neighboring_regs.at(op_idx).end(),
183 new_neighboring_regs.at(new_op_idx).begin(),
184 new_neighboring_regs.at(new_op_idx).end(),
185 std::back_inserter(intersection));
187 non_over_lapping += new_neighboring_regs.at(new_op_idx).size() - intersection.size();
190 return non_over_lapping;
194 std::vector<std::vector<Net*>>
reorder_commutative_operands(
const std::vector<std::vector<Net*>>& operands,
const std::vector<std::vector<Gate*>>& registers,
const u32 permute_start_index)
196 if (operands.size() > 6)
198 log_warning(
"module_identification",
"reconstruction of 6+ commutative operands not yet supported and might take some time");
201 std::vector<std::vector<Net*>> corrected_operands;
204 std::vector<u32> op_indices(operands.size());
205 std::iota(op_indices.begin(), op_indices.end(), 0);
206 auto all_permutations = permutations(op_indices);
208 std::vector<std::set<u32>> neighboring_regs(operands.size(), std::set<u32>{});
209 for (
u32 net_idx = 0; net_idx < operands.front().
size(); net_idx++)
211 std::vector<u32> best_permutation;
214 std::vector<std::set<u32>> new_neighboring_regs;
215 for (
u32 op_idx = 0; op_idx < operands.size(); op_idx++)
220 if (net_idx < permute_start_index)
222 best_permutation = op_indices;
227 std::sort(all_permutations.begin(), all_permutations.end(), [&neighboring_regs, &new_neighboring_regs](
const auto& p1,
const auto& p2) {
228 return calculate_permuation_score(p1, neighboring_regs, new_neighboring_regs) < calculate_permuation_score(p2, neighboring_regs, new_neighboring_regs);
231 best_permutation = all_permutations.front();
234 for (
u32 op_idx = 0; op_idx < best_permutation.size(); op_idx++)
236 const u32 new_op_idx = best_permutation.at(op_idx);
238 Net* new_net = operands.at(new_op_idx).at(net_idx);
240 if (op_idx >= corrected_operands.size())
242 corrected_operands.push_back({});
244 corrected_operands.at(op_idx).push_back(new_net);
247 for (
u32 op_idx = 0; op_idx < operands.size(); op_idx++)
249 neighboring_regs.at(op_idx).insert(new_neighboring_regs.at(op_idx).begin(), new_neighboring_regs.at(op_idx).end());
253 return corrected_operands;
Netlist * get_netlist() const
Result< std::set< Gate * > > get_next_matching_gates(const Net *net, bool successors, const std::function< bool(const Gate *)> &target_gate_filter, bool continue_on_match=false, const std::function< bool(const Endpoint *, u32 current_depth)> &exit_endpoint_filter=nullptr, const std::function< bool(const Endpoint *, u32 current_depth)> &entry_endpoint_filter=nullptr) const
#define log_error(channel,...)
#define log_warning(channel,...)
std::set< u32 > find_neighboring_registers(const Net *n, const std::vector< std::vector< Gate * >> ®isters)
Find neighboring registers connected to a given net.
std::vector< std::vector< Net * > > reorder_commutative_operands(const std::vector< std::vector< Net * >> &operands, const std::vector< std::vector< Gate * >> ®isters, const u32 permute_start_index=0)
Reorder commutative operands based on a permutation cache.
std::vector< Net * > get_input_nets(const std::vector< Gate * > &gates)
Get input nets from a list of gates.
std::vector< Net * > get_output_nets(const std::vector< Gate * > &gates, bool only_external_destinations=true)
Get output nets from a list of gates.
This file contains all functions related to the HAL plugin API.