22 namespace pre_processing
31 const std::unordered_map<u32, std::unordered_set<u32>>& connections;
32 std::vector<std::vector<u32>> stages;
37 for (
auto& ctx : directional_stages)
39 log_info(
"dataflow",
"directional register stages: {}", ctx.name);
41 std::unordered_set<u32> unassigned_gates;
44 unassigned_gates.insert(
g->get_id());
51 std::unordered_map<u32, u32> stage_index_of_gate;
53 for (
const auto& sequential_gate : netlist_abstr.
target_gates)
58 auto current = sequential_gate->get_id();
60 std::unordered_set<u32> next_stages;
62 if (!ctx.connections.at(current).empty())
64 for (
auto suc : ctx.connections.at(current))
66 if (
auto it = stage_index_of_gate.find(suc); it != stage_index_of_gate.end())
68 next_stages.insert(it->second);
73 if (next_stages.empty())
75 ctx.stages.emplace_back(ctx.connections.at(current).begin(), ctx.connections.at(current).end());
76 auto new_stage_id = ctx.stages.size() - 1;
77 for (
auto g : ctx.connections.at(current))
79 stage_index_of_gate[
g] = new_stage_id;
84 if (next_stages.size() > 1)
86 auto it = next_stages.begin();
87 auto merge_stage_index = *it;
89 for (; it != next_stages.end(); it = next_stages.erase(it))
91 auto& stage_to_merge = ctx.stages[*it];
92 for (
auto g : stage_to_merge)
94 stage_index_of_gate[
g] = merge_stage_index;
96 ctx.stages[merge_stage_index].insert(ctx.stages[merge_stage_index].end(), stage_to_merge.begin(), stage_to_merge.end());
97 stage_to_merge.clear();
102 if (next_stages.size() == 1)
104 auto stage_index = *(next_stages.begin());
105 auto& connected_gates = ctx.connections.at(current);
106 ctx.stages[stage_index].insert(ctx.stages[stage_index].end(), connected_gates.begin(), connected_gates.end());
107 for (
auto g : connected_gates)
109 stage_index_of_gate[
g] = stage_index;
113 for (
auto g : ctx.connections.at(current))
115 if (
auto it = unassigned_gates.find(
g); it != unassigned_gates.end())
117 unassigned_gates.erase(it);
122 progress_bar.
clear();
126 ctx.stages.erase(std::remove_if(ctx.stages.begin(), ctx.stages.end(), [](
auto& stage) { return stage.empty(); }), ctx.stages.end());
130 for (
u32 i = 0; i < ctx.stages.size(); ++i)
132 std::sort(ctx.stages[i].begin(), ctx.stages[i].end());
133 ctx.stages[i].erase(std::unique(ctx.stages[i].begin(), ctx.stages[i].end()), ctx.stages[i].end());
139 u32 stages_to_split = ctx.stages.size();
140 for (
u32 i = 0; i < stages_to_split; ++i)
145 std::unordered_map<u32, std::vector<u32>> move_out_reasons;
146 for (
auto g : ctx.stages[i])
148 for (
auto next : ctx.connections.at(
g))
152 if (std::binary_search(ctx.stages[i].begin(), ctx.stages[i].end(), next) && ctx.connections.at(next).find(
g) == ctx.connections.at(next).end())
154 move_out_reasons[next].push_back(
g);
160 for (
auto it = move_out_reasons.begin(); it != move_out_reasons.end(); ++it)
162 std::sort(it->second.begin(), it->second.end());
163 it->second.erase(std::unique(it->second.begin(), it->second.end()), it->second.end());
166 auto remaining = ctx.stages[i];
167 bool first_iteration =
true;
168 while (!remaining.empty())
170 std::vector<u32> keep;
171 for (
auto g : remaining)
173 if (move_out_reasons[
g].empty())
179 if (keep.empty() || keep.size() == remaining.size())
181 if (!first_iteration)
183 ctx.stages.push_back(remaining);
188 std::sort(keep.begin(), keep.end());
191 ctx.stages[i] = keep;
195 ctx.stages.push_back(keep);
199 std::vector<u32> diff;
200 std::set_difference(remaining.begin(), remaining.end(), keep.begin(), keep.end(), std::back_inserter(diff));
201 remaining = std::move(diff);
204 for (
auto r : remaining)
206 auto& reasons = move_out_reasons[r];
207 std::vector<u32> diff;
208 std::set_difference(reasons.begin(), reasons.end(), keep.begin(), keep.end(), std::back_inserter(diff));
209 reasons = std::move(diff);
211 first_iteration =
false;
215 progress_bar.
clear();
218 for (
const auto&
g : unassigned_gates)
220 ctx.stages.push_back({
g});
225 log_info(
"dataflow",
"merging directional stages...");
230 for (
u32 i = 0; i < 2; ++i)
232 std::sort(directional_stages[i].stages.begin(), directional_stages[i].stages.end(), [](
auto& a,
auto& b) { return a.size() < b.size(); });
236 for (
u32 i = 0; i < 2; ++i)
238 for (
const auto& stage : directional_stages[i].stages)
241 progress_bar.
print_progress(cnt / (directional_stages[0].stages.size() + directional_stages[1].stages.size()));
242 for (
auto it = directional_stages[1 - i].stages.begin(); it != directional_stages[1 - i].stages.end();)
244 auto& other_stage = *it;
245 if (stage.size() < other_stage.size())
250 if (std::includes(stage.begin(), stage.end(), other_stage.begin(), other_stage.end()))
252 it = directional_stages[1 - i].stages.erase(it);
262 progress_bar.
clear();
265 std::vector<std::vector<u32>> final_stages;
268 log_info(
"dataflow",
"sorting gates into final stages...");
271 final_stages.reserve(directional_stages[0].stages.size() + directional_stages[1].stages.size());
272 for (
u32 i = 0; i < 2; ++i)
274 final_stages.insert(final_stages.end(), directional_stages[i].stages.begin(), directional_stages[i].stages.end());
278 for (
u32 s = 0; s < final_stages.size(); ++s)
280 for (
auto g : final_stages[s])
288 log_info(
"dataflow",
"spreading multi-stages...");
295 std::vector<std::unordered_set<u32>> spread_stages;
296 std::set<std::vector<u32>> seen;
301 if (stages.size() > 1)
304 auto stages_vec = std::vector<u32>(stages.begin(), stages.end());
307 if (seen.find(stages_vec) != seen.end())
311 seen.insert(stages_vec);
314 auto it = std::find_if(spread_stages.begin(), spread_stages.end(), [&](
auto& group) {
315 return std::any_of(stages_vec.begin(), stages_vec.end(), [&](auto id) { return group.find(id) != group.end(); });
318 if (it != spread_stages.end())
321 it->insert(stages.begin(), stages.end());
326 spread_stages.emplace_back(stages.begin(), stages.end());
333 progress_bar.clear();
334 progress_bar.reset();
337 for (
const auto& combine : spread_stages)
341 for (
auto stage_id : combine)
343 for (
auto gate_id : final_stages[stage_id])
349 progress_bar.clear();
352 log_info(
"dataflow",
"found {} stages", final_stages.size());
void print_progress(float progress, const std::string &message="")
#define log_info(channel,...)
void identify_register_stages(NetlistAbstraction &netlist_abstr)
This file contains the struct that holds all information on the netlist abstraction used for dataflow...
The abstraction of the netlist that only contains gates of a specified type, e.g.,...
std::unordered_map< u32, std::unordered_set< u32 > > gate_to_predecessors
std::unordered_map< u32, std::unordered_set< u32 > > gate_to_register_stages
std::unordered_map< u32, std::unordered_set< u32 > > gate_to_successors
std::vector< Gate * > target_gates
#define measure_block_time(X)