26 namespace pre_processing
30 void identify_all_target_gates(
const dataflow::Configuration& config, NetlistAbstraction& netlist_abstr)
32 log_info(
"dataflow",
"identifying target gates");
33 netlist_abstr.target_gates = netlist_abstr.nl->get_gates([config](
auto g) {
return config.gate_types.find(
g->get_type()) != config.gate_types.end(); });
34 std::sort(netlist_abstr.target_gates.begin(), netlist_abstr.target_gates.end(), [](
const Gate* g1,
const Gate* g2) { return g1->get_id() < g2->get_id(); });
35 log_info(
"dataflow",
" #gates: {}", netlist_abstr.nl->get_gates().size());
36 log_info(
"dataflow",
" #target gates: {}", netlist_abstr.target_gates.size());
39 void identify_all_control_signals(
const dataflow::Configuration& config, NetlistAbstraction& netlist_abstr)
41 auto begin_time = std::chrono::high_resolution_clock::now();
42 log_info(
"dataflow",
"identifying control signals");
43 for (
auto sg : netlist_abstr.target_gates)
45 std::vector<u32> fingerprint;
46 auto id = sg->get_id();
48 for (
auto type : config.control_pin_types)
53 netlist_abstr.gate_to_control_signals[
id][
type].insert(
net->get_id());
54 fingerprint.push_back(
net->get_id());
58 netlist_abstr.gate_to_fingerprint[
id] = fingerprint;
64 void identify_known_groups(
const dataflow::Configuration& config, NetlistAbstraction& netlist_abstr, std::vector<std::vector<Gate*>>& known_target_groups)
67 for (
const auto& gates : config.known_gate_groups)
70 gates.begin(), gates.end(), [&netlist_abstr](
const Gate*
g) { return netlist_abstr.gate_to_fingerprint.find(g->get_id()) != netlist_abstr.gate_to_fingerprint.end(); }))
72 known_target_groups.push_back(gates);
77 "known group containing gate '{}' with ID {} contains gates that are not of the target gate type, known group will be ignored...",
78 gates.front()->get_name(),
79 gates.front()->get_id());
85 void identify_successors_predecessors(
const dataflow::Configuration& config, NetlistAbstraction& netlist_abstr)
87 log_info(
"dataflow",
"identifying successors and predecessors of sequential gates...");
88 measure_block_time(
"identifying successors and predecessors of sequential gates") ProgressPrinter progress_bar;
91 progress_bar.print_message_to_gui("dataflow: preprocessing …");
94 std::unordered_map<const Net*,
u32> net_to_group_index;
95 for (
u32 i = 0; i < config.known_net_groups.size(); i++)
97 const auto& net_group = config.known_net_groups.at(i);
98 if (net_group.size() < config.min_group_size)
103 for (
const auto*
net : net_group)
105 net_to_group_index[
net] = i;
110 std::unordered_map<const Net*, std::pair<std::unordered_set<Gate*>, std::unordered_set<u32>>> suc_cache;
111 std::unordered_map<const Net*, std::unordered_set<u32>> pred_cache;
112 for (
const auto& gate : netlist_abstr.target_gates)
115 progress_bar.print_progress_to_stderr(cnt / netlist_abstr.target_gates.size());
116 progress_bar.print_progress_to_gui();
119 if (netlist_abstr.gate_to_successors.find(gate->get_id()) == netlist_abstr.gate_to_successors.end())
121 netlist_abstr.gate_to_successors[gate->get_id()] = std::unordered_set<u32>();
123 if (netlist_abstr.gate_to_predecessors.find(gate->get_id()) == netlist_abstr.gate_to_predecessors.end())
125 netlist_abstr.gate_to_predecessors[gate->get_id()] = std::unordered_set<u32>();
127 if (netlist_abstr.gate_to_known_successor_groups.find(gate->get_id()) == netlist_abstr.gate_to_known_successor_groups.end())
129 netlist_abstr.gate_to_known_successor_groups[gate->get_id()] = std::unordered_set<u32>();
131 if (netlist_abstr.gate_to_known_predecessor_groups.find(gate->get_id()) == netlist_abstr.gate_to_known_predecessor_groups.end())
133 netlist_abstr.gate_to_known_predecessor_groups[gate->get_id()] = std::unordered_set<u32>();
136 const auto& start_fan_out_nets = gate->get_fan_out_nets();
137 std::vector<const Net*> stack(start_fan_out_nets.cbegin(), start_fan_out_nets.cend());
138 std::unordered_set<const Net*> visited;
139 std::vector<const Net*> previous;
140 while (!stack.empty())
142 const Net* current = stack.back();
144 if (!previous.empty() && current == previous.back())
152 visited.insert(current);
154 if (
const auto suc_cache_it = suc_cache.find(current); suc_cache_it != suc_cache.end())
156 auto& suc_cache_current = std::get<1>(*suc_cache_it);
157 const auto& suc_cached_gates = std::get<0>(suc_cache_current);
158 const auto& suc_cached_net_groups = std::get<1>(suc_cache_current);
161 for (
const auto*
n : previous)
163 auto& suc_cache_n = suc_cache[
n];
164 std::get<0>(suc_cache_n).insert(suc_cached_gates.cbegin(), suc_cached_gates.cend());
165 std::get<1>(suc_cache_n).insert(suc_cached_net_groups.cbegin(), suc_cached_net_groups.cend());
169 netlist_abstr.gate_to_known_successor_groups[gate->get_id()].insert(suc_cached_net_groups.cbegin(), suc_cached_net_groups.cend());
175 if (
const auto group_it = net_to_group_index.find(current); group_it != net_to_group_index.end())
177 std::get<1>(suc_cache[current]).insert(group_it->second);
178 for (
const auto*
n : previous)
180 std::get<1>(suc_cache[
n]).insert(group_it->second);
182 netlist_abstr.gate_to_known_successor_groups[gate->get_id()].insert(group_it->second);
186 for (
const auto* ep : current->get_destinations())
188 auto*
g = ep->get_gate();
189 if (config.gate_types.find(
g->get_type()) != config.gate_types.end())
192 auto& suc_cache_current = suc_cache[current];
193 std::get<0>(suc_cache_current).insert(
g);
194 for (
const auto*
n : previous)
196 std::get<0>(suc_cache[
n]).insert(
g);
202 for (
const auto*
n :
g->get_fan_out_nets())
204 if (visited.find(
n) == visited.end())
216 previous.push_back(current);
226 const auto& start_fan_in_nets = gate->get_fan_in_nets();
227 stack = std::vector<const Net*>(start_fan_in_nets.begin(), start_fan_in_nets.end());
230 while (!stack.empty())
232 const Net* current = stack.back();
234 if (!previous.empty() && current == previous.back())
242 visited.insert(current);
244 if (
const auto pred_cache_it = pred_cache.find(current); pred_cache_it != pred_cache.end())
246 auto& pred_cached_net_groups = std::get<1>(*pred_cache_it);
249 for (
const auto*
n : previous)
251 pred_cache[
n].insert(pred_cached_net_groups.cbegin(), pred_cached_net_groups.cend());
255 netlist_abstr.gate_to_known_predecessor_groups[gate->get_id()].insert(pred_cached_net_groups.cbegin(), pred_cached_net_groups.cend());
261 if (
const auto group_it = net_to_group_index.find(current); group_it != net_to_group_index.end())
263 pred_cache[current].insert(group_it->second);
264 for (
const auto*
n : previous)
266 pred_cache[
n].insert(group_it->second);
268 netlist_abstr.gate_to_known_predecessor_groups[gate->get_id()].insert(group_it->second);
272 for (
const auto* ep : current->get_sources())
274 auto*
g = ep->get_gate();
275 if (config.gate_types.find(
g->get_type()) == config.gate_types.end())
278 for (
const auto*
n :
g->get_fan_in_nets())
280 if (visited.find(
n) == visited.end())
292 previous.push_back(current);
303 std::unordered_set<Gate*> next_target_gates;
304 for (
const auto*
n : start_fan_out_nets)
306 if (
const auto it = suc_cache.find(
n); it != suc_cache.end())
308 const auto& cached_gates = std::get<0>(std::get<1>(*it));
309 next_target_gates.insert(cached_gates.cbegin(), cached_gates.cend());
313 for (
const auto& suc : next_target_gates)
315 netlist_abstr.gate_to_successors[gate->get_id()].insert(suc->get_id());
316 netlist_abstr.gate_to_predecessors[suc->get_id()].insert(gate->get_id());
319 progress_bar.clear();
325 log_info(
"dataflow",
"pre-processing netlist...");
328 std::vector<std::vector<Gate*>> known_target_groups;
329 std::vector<std::vector<Net*>> known_net_groups;
330 identify_all_target_gates(config, netlist_abstr);
331 identify_all_control_signals(config, netlist_abstr);
332 identify_known_groups(config, netlist_abstr, known_target_groups);
333 identify_successors_predecessors(config, netlist_abstr);
340 initial_grouping = std::make_shared<dataflow::Grouping>(netlist_abstr, known_target_groups);
342 return netlist_abstr;
This file contains the struct that holds all information on a dataflow analysis configuration.
#define log_info(channel,...)
#define log_warning(channel,...)
void identify_register_stages(NetlistAbstraction &netlist_abstr)
NetlistAbstraction run(const dataflow::Configuration &config, std::shared_ptr< dataflow::Grouping > &initial_grouping)
std::vector< Net * > get_nets_at_pins(Gate *gate, std::vector< GatePin * > pins)
This file contains the struct that holds all information on the netlist abstraction used for dataflow...
This file contains the class that holds all information of a dataflow analysis grouping.
Configuration of a dataflow analysis run.
bool enable_stages
Enable stage identification as part of dataflow analysis. Defaults to false.
Netlist * netlist
The netlist to be analyzed.
The abstraction of the netlist that only contains gates of a specified type, e.g.,...
#define measure_block_time(X)