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;
92 std::unordered_map<const Net*,
u32> net_to_group_index;
93 for (
u32 i = 0; i < config.known_net_groups.size(); i++)
95 const auto& net_group = config.known_net_groups.at(i);
96 if (net_group.size() < config.min_group_size)
101 for (
const auto*
net : net_group)
103 net_to_group_index[
net] = i;
108 std::unordered_map<const Net*, std::pair<std::unordered_set<Gate*>, std::unordered_set<u32>>> suc_cache;
109 std::unordered_map<const Net*, std::unordered_set<u32>> pred_cache;
110 for (
const auto& gate : netlist_abstr.target_gates)
113 progress_bar.print_progress(cnt / netlist_abstr.target_gates.size());
116 if (netlist_abstr.gate_to_successors.find(gate->get_id()) == netlist_abstr.gate_to_successors.end())
118 netlist_abstr.gate_to_successors[gate->get_id()] = std::unordered_set<u32>();
120 if (netlist_abstr.gate_to_predecessors.find(gate->get_id()) == netlist_abstr.gate_to_predecessors.end())
122 netlist_abstr.gate_to_predecessors[gate->get_id()] = std::unordered_set<u32>();
124 if (netlist_abstr.gate_to_known_successor_groups.find(gate->get_id()) == netlist_abstr.gate_to_known_successor_groups.end())
126 netlist_abstr.gate_to_known_successor_groups[gate->get_id()] = std::unordered_set<u32>();
128 if (netlist_abstr.gate_to_known_predecessor_groups.find(gate->get_id()) == netlist_abstr.gate_to_known_predecessor_groups.end())
130 netlist_abstr.gate_to_known_predecessor_groups[gate->get_id()] = std::unordered_set<u32>();
133 const auto& start_fan_out_nets = gate->get_fan_out_nets();
134 std::vector<const Net*> stack(start_fan_out_nets.cbegin(), start_fan_out_nets.cend());
135 std::unordered_set<const Net*> visited;
136 std::vector<const Net*> previous;
137 while (!stack.empty())
139 const Net* current = stack.back();
141 if (!previous.empty() && current == previous.back())
149 visited.insert(current);
151 if (
const auto suc_cache_it = suc_cache.find(current); suc_cache_it != suc_cache.end())
153 auto& suc_cache_current = std::get<1>(*suc_cache_it);
154 const auto& suc_cached_gates = std::get<0>(suc_cache_current);
155 const auto& suc_cached_net_groups = std::get<1>(suc_cache_current);
158 for (
const auto*
n : previous)
160 auto& suc_cache_n = suc_cache[
n];
161 std::get<0>(suc_cache_n).insert(suc_cached_gates.cbegin(), suc_cached_gates.cend());
162 std::get<1>(suc_cache_n).insert(suc_cached_net_groups.cbegin(), suc_cached_net_groups.cend());
166 netlist_abstr.gate_to_known_successor_groups[gate->get_id()].insert(suc_cached_net_groups.cbegin(), suc_cached_net_groups.cend());
172 if (
const auto group_it = net_to_group_index.find(current); group_it != net_to_group_index.end())
174 std::get<1>(suc_cache[current]).insert(group_it->second);
175 for (
const auto*
n : previous)
177 std::get<1>(suc_cache[
n]).insert(group_it->second);
179 netlist_abstr.gate_to_known_successor_groups[gate->get_id()].insert(group_it->second);
183 for (
const auto* ep : current->get_destinations())
185 auto*
g = ep->get_gate();
186 if (config.gate_types.find(
g->get_type()) != config.gate_types.end())
189 auto& suc_cache_current = suc_cache[current];
190 std::get<0>(suc_cache_current).insert(
g);
191 for (
const auto*
n : previous)
193 std::get<0>(suc_cache[
n]).insert(
g);
199 for (
const auto*
n :
g->get_fan_out_nets())
201 if (visited.find(
n) == visited.end())
213 previous.push_back(current);
223 const auto& start_fan_in_nets = gate->get_fan_in_nets();
224 stack = std::vector<const Net*>(start_fan_in_nets.begin(), start_fan_in_nets.end());
227 while (!stack.empty())
229 const Net* current = stack.back();
231 if (!previous.empty() && current == previous.back())
239 visited.insert(current);
241 if (
const auto pred_cache_it = pred_cache.find(current); pred_cache_it != pred_cache.end())
243 auto& pred_cached_net_groups = std::get<1>(*pred_cache_it);
246 for (
const auto*
n : previous)
248 pred_cache[
n].insert(pred_cached_net_groups.cbegin(), pred_cached_net_groups.cend());
252 netlist_abstr.gate_to_known_predecessor_groups[gate->get_id()].insert(pred_cached_net_groups.cbegin(), pred_cached_net_groups.cend());
258 if (
const auto group_it = net_to_group_index.find(current); group_it != net_to_group_index.end())
260 pred_cache[current].insert(group_it->second);
261 for (
const auto*
n : previous)
263 pred_cache[
n].insert(group_it->second);
265 netlist_abstr.gate_to_known_predecessor_groups[gate->get_id()].insert(group_it->second);
269 for (
const auto* ep : current->get_sources())
271 auto*
g = ep->get_gate();
272 if (config.gate_types.find(
g->get_type()) == config.gate_types.end())
275 for (
const auto*
n :
g->get_fan_in_nets())
277 if (visited.find(
n) == visited.end())
289 previous.push_back(current);
300 std::unordered_set<Gate*> next_target_gates;
301 for (
const auto*
n : start_fan_out_nets)
303 if (
const auto it = suc_cache.find(
n); it != suc_cache.end())
305 const auto& cached_gates = std::get<0>(std::get<1>(*it));
306 next_target_gates.insert(cached_gates.cbegin(), cached_gates.cend());
310 for (
const auto& suc : next_target_gates)
312 netlist_abstr.gate_to_successors[gate->get_id()].insert(suc->get_id());
313 netlist_abstr.gate_to_predecessors[suc->get_id()].insert(gate->get_id());
316 progress_bar.clear();
322 log_info(
"dataflow",
"pre-processing netlist...");
325 std::vector<std::vector<Gate*>> known_target_groups;
326 std::vector<std::vector<Net*>> known_net_groups;
327 identify_all_target_gates(config, netlist_abstr);
328 identify_all_control_signals(config, netlist_abstr);
329 identify_known_groups(config, netlist_abstr, known_target_groups);
330 identify_successors_predecessors(config, netlist_abstr);
337 initial_grouping = std::make_shared<dataflow::Grouping>(netlist_abstr, known_target_groups);
339 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)