Added topological sorting to techmap

This commit is contained in:
Clifford Wolf 2014-07-27 16:19:24 +02:00
parent 0c86d6106c
commit 5da343b7de
2 changed files with 54 additions and 21 deletions

View File

@ -46,7 +46,7 @@ struct TopoSort
database[right].insert(left); database[right].insert(left);
} }
void sort_worker(T n, std::set<T> &marked_cells, std::set<T> &active_cells, std::vector<T> active_stack) void sort_worker(const T &n, std::set<T> &marked_cells, std::set<T> &active_cells, std::vector<T> &active_stack)
{ {
if (active_cells.count(n)) { if (active_cells.count(n)) {
found_loops = false; found_loops = false;
@ -96,6 +96,7 @@ struct TopoSort
for (auto &it : database) for (auto &it : database)
sort_worker(it.first, marked_cells, active_cells, active_stack); sort_worker(it.first, marked_cells, active_cells, active_stack);
log_assert(SIZE(sorted) == SIZE(database));
return !found_loops; return !found_loops;
} }
}; };

View File

@ -20,6 +20,7 @@
#include "kernel/compatibility.h" #include "kernel/compatibility.h"
#include "kernel/register.h" #include "kernel/register.h"
#include "kernel/sigtools.h" #include "kernel/sigtools.h"
#include "kernel/toposort.h"
#include "kernel/log.h" #include "kernel/log.h"
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -221,25 +222,55 @@ struct TechmapWorker
bool log_continue = false; bool log_continue = false;
bool did_something = false; bool did_something = false;
std::vector<std::string> cell_names;
SigMap sigmap(module); SigMap sigmap(module);
for (auto &cell_it : module->cells_)
cell_names.push_back(cell_it.first);
for (auto &cell_name : cell_names) TopoSort<RTLIL::Cell*> cells;
std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit;
std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
for (auto cell : module->cells())
{ {
if (module->cells_.count(cell_name) == 0)
continue;
RTLIL::Cell *cell = module->cells_[cell_name];
if (!design->selected(module, cell) || handled_cells.count(cell) > 0) if (!design->selected(module, cell) || handled_cells.count(cell) > 0)
continue; continue;
if (celltypeMap.count(cell->type) == 0) if (celltypeMap.count(cell->type) == 0)
continue; continue;
for (auto &conn : cell->connections())
{
RTLIL::SigSpec sig = sigmap(conn.second);
sig.remove_const();
if (SIZE(sig) == 0)
continue;
for (auto &tpl_name : celltypeMap.at(cell->type)) {
RTLIL::Module *tpl = map->modules_[tpl_name];
RTLIL::Wire *port = tpl->wire(conn.first);
if (port && port->port_input)
cell_to_inbit[cell].insert(sig.begin(), sig.end());
if (port && port->port_output)
for (auto &bit : sig)
outbit_to_cell[bit].insert(cell);
}
}
cells.node(cell);
}
for (auto &it_right : cell_to_inbit)
for (auto &it_sigbit : it_right.second)
for (auto &it_left : outbit_to_cell[it_sigbit])
cells.edge(it_left, it_right.first);
cells.sort();
for (auto cell : cells.sorted)
{
log_assert(handled_cells.count(cell) == 0);
log_assert(cell == module->cell(cell->name));
for (auto &tpl_name : celltypeMap.at(cell->type)) for (auto &tpl_name : celltypeMap.at(cell->type))
{ {
std::string derived_name = tpl_name; std::string derived_name = tpl_name;
@ -610,18 +641,19 @@ struct TechmapPass : public Pass {
celltypeMap[it.first].insert(it.first); celltypeMap[it.first].insert(it.first);
} }
for (auto module : design->modules()) {
bool did_something = true; bool did_something = true;
std::set<RTLIL::Cell*> handled_cells; std::set<RTLIL::Cell*> handled_cells;
while (did_something) { while (did_something) {
did_something = false; did_something = false;
for (auto &mod_it : design->modules_) if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false))
if (worker.techmap_module(design, mod_it.second, map, handled_cells, celltypeMap, false))
did_something = true; did_something = true;
if (did_something) if (did_something)
design->check(); module->check();
if (max_iter > 0 && --max_iter == 0) if (max_iter > 0 && --max_iter == 0)
break; break;
} }
}
log("No more expansions possible.\n"); log("No more expansions possible.\n");
delete map; delete map;