Fix small isses and code formatting

Signed-off-by: Maciej Dudek <mdudek@antmicro.com>
This commit is contained in:
Maciej Dudek 2021-09-27 16:16:33 +02:00
parent 439ae9609b
commit ea489f6d93
5 changed files with 150 additions and 148 deletions

View File

@ -731,11 +731,11 @@ class SAPlacer
return true; return true;
swap_fail: swap_fail:
#if CHAIN_DEBUG #if CHAIN_DEBUG
log_info("Swap failed\n"); log_info("Swap failed\n");
#endif #endif
for (auto cell_pair : moved_cells) { for (auto cell_pair : moved_cells) {
CellInfo *cell = ctx->cells.at(cell_pair.first).get(); CellInfo *cell = ctx->cells.at(cell_pair.first).get();
if (cell->bel != BelId()){ if (cell->bel != BelId()) {
#if CHAIN_DEBUG #if CHAIN_DEBUG
log_info("%d unbind %s\n", __LINE__, ctx->nameOfBel(cell->bel)); log_info("%d unbind %s\n", __LINE__, ctx->nameOfBel(cell->bel));
#endif #endif

View File

@ -899,10 +899,10 @@ struct Arch : ArchAPI<ArchRanges>
ArcBounds getClusterBounds(ClusterId cluster) const override; ArcBounds getClusterBounds(ClusterId cluster) const override;
Loc getClusterOffset(const CellInfo *cell) const override; Loc getClusterOffset(const CellInfo *cell) const override;
bool isClusterStrict(const CellInfo *cell) const override; bool isClusterStrict(const CellInfo *cell) const override;
bool normal_cluster_placement(const Context *, const Cluster &, const ClusterPOD &,CellInfo*, bool normal_cluster_placement(const Context *, const Cluster &, const ClusterPOD &, CellInfo *, BelId,
BelId, std::vector<std::pair<CellInfo *, BelId>> &) const; std::vector<std::pair<CellInfo *, BelId>> &) const;
bool macro_cluster_placement(const Context *, const Cluster &, const ClusterPOD &,CellInfo*, bool macro_cluster_placement(const Context *, const Cluster &, const ClusterPOD &, CellInfo *, BelId,
BelId, std::vector<std::pair<CellInfo *, BelId>> &) const; std::vector<std::pair<CellInfo *, BelId>> &) const;
bool getClusterPlacement(ClusterId cluster, BelId root_bel, bool getClusterPlacement(ClusterId cluster, BelId root_bel,
std::vector<std::pair<CellInfo *, BelId>> &placement) const override; std::vector<std::pair<CellInfo *, BelId>> &placement) const override;

View File

@ -189,9 +189,9 @@ CellInfo *Arch::getClusterRootCell(ClusterId cluster) const
return clusters.at(cluster).root; return clusters.at(cluster).root;
} }
bool Arch::normal_cluster_placement( bool Arch::normal_cluster_placement(const Context *ctx, const Cluster &packed_cluster, const ClusterPOD &cluster_data,
const Context *ctx, const Cluster &packed_cluster, const ClusterPOD &cluster_data, CellInfo *root_cell, BelId root_bel,
CellInfo *root_cell, BelId root_bel, std::vector<std::pair<CellInfo *, BelId>> &placement) const std::vector<std::pair<CellInfo *, BelId>> &placement) const
{ {
BelId next_bel; BelId next_bel;
@ -278,34 +278,33 @@ bool Arch::normal_cluster_placement(
static dict<int32_t, dict<IdString, BelId>> tileAndBelNameToBelIdCache; static dict<int32_t, dict<IdString, BelId>> tileAndBelNameToBelIdCache;
BelId check_and_return(int32_t tile, IdString name){ BelId check_and_return(int32_t tile, IdString name)
if(tileAndBelNameToBelIdCache.count(tile) {
&& tileAndBelNameToBelIdCache[tile].count(name)) if (tileAndBelNameToBelIdCache.count(tile) && tileAndBelNameToBelIdCache[tile].count(name))
return tileAndBelNameToBelIdCache[tile][name]; return tileAndBelNameToBelIdCache[tile][name];
else else
return BelId(); return BelId();
} }
void add_to_cache(int32_t tile, IdString name, BelId t){ void add_to_cache(int32_t tile, IdString name, BelId t) { tileAndBelNameToBelIdCache[tile][name] = t; }
tileAndBelNameToBelIdCache[tile][name] = t;
}
bool find_site_idx(const Context *ctx, const ClusterPOD &cluster, BelId root_bel, uint32_t &idx){ bool find_site_idx(const Context *ctx, const ClusterPOD &cluster, BelId root_bel, uint32_t &idx)
{
bool found = false; bool found = false;
const auto &site_inst = ctx->get_site_inst(root_bel); const auto &site_inst = ctx->get_site_inst(root_bel);
IdString site_type(site_inst.site_type); IdString site_type(site_inst.site_type);
if (ctx->debug){ if (ctx->debug) {
log_info("%s\n", ctx->get_site_name(root_bel)); log_info("%s\n", ctx->get_site_name(root_bel));
log_info("Root_bel site_type: %s\n", site_type.c_str(ctx)); log_info("Root_bel site_type: %s\n", site_type.c_str(ctx));
log_info("Allowed site_types:\n"); log_info("Allowed site_types:\n");
} }
for(const auto &site : cluster.physical_placements){ for (const auto &site : cluster.physical_placements) {
IdString name(site.site_type); IdString name(site.site_type);
if(ctx->debug) if (ctx->debug)
log_info("\t%s\n", name.c_str(ctx)); log_info("\t%s\n", name.c_str(ctx));
if (name == site_type){ if (name == site_type) {
found = true; found = true;
break; break;
} }
@ -314,22 +313,23 @@ bool find_site_idx(const Context *ctx, const ClusterPOD &cluster, BelId root_bel
return found; return found;
} }
bool find_placement_idx(const Context *ctx, const ClusterPOD &cluster, bool find_placement_idx(const Context *ctx, const ClusterPOD &cluster, BelId root_bel, uint32_t idx,
BelId root_bel, uint32_t idx, uint32_t &placement_idx){ uint32_t &placement_idx)
{
bool found = false; bool found = false;
const auto &bel_data = bel_info(ctx->chip_info, root_bel); const auto &bel_data = bel_info(ctx->chip_info, root_bel);
IdString root_bel_name(bel_data.name); IdString root_bel_name(bel_data.name);
if(ctx->debug){ if (ctx->debug) {
log_info("Root_bel name: %s\n", root_bel_name.c_str(ctx)); log_info("Root_bel name: %s\n", root_bel_name.c_str(ctx));
log_info("Allowed root_bels:\n"); log_info("Allowed root_bels:\n");
} }
for(const auto &place : cluster.physical_placements[idx].places){ for (const auto &place : cluster.physical_placements[idx].places) {
for (const auto bel : place.bels){ for (const auto bel : place.bels) {
IdString name(bel); IdString name(bel);
if(ctx->debug) if (ctx->debug)
log_info("\t%s\n",name.c_str(ctx)); log_info("\t%s\n", name.c_str(ctx));
if(name == root_bel_name){ if (name == root_bel_name) {
found = true; found = true;
break; break;
} }
@ -341,26 +341,27 @@ bool find_placement_idx(const Context *ctx, const ClusterPOD &cluster,
return found; return found;
} }
dict<uint32_t, BelId> idx_bel_mapping(const Context *ctx, BelId root_bel, dict<uint32_t, BelId> idx_bel_mapping(const Context *ctx, BelId root_bel, const ClusterPOD &cluster, uint32_t idx,
const ClusterPOD &cluster, uint32_t idx, uint32_t placement_idx){ uint32_t placement_idx)
{
dict<uint32_t, BelId> idx_bel_map; dict<uint32_t, BelId> idx_bel_map;
auto root_bel_full_name = ctx->getBelName(root_bel); auto root_bel_full_name = ctx->getBelName(root_bel);
uint32_t t_idx = 0; uint32_t t_idx = 0;
if(ctx->debug) if (ctx->debug)
log_info("Used bels:\n"); log_info("Used bels:\n");
for(const auto &bel : cluster.physical_placements[idx].places[placement_idx].bels){ for (const auto &bel : cluster.physical_placements[idx].places[placement_idx].bels) {
IdString s_bel(bel); IdString s_bel(bel);
BelId t = check_and_return(root_bel.tile, s_bel); BelId t = check_and_return(root_bel.tile, s_bel);
IdStringList cpy(root_bel_full_name.size()); IdStringList cpy(root_bel_full_name.size());
if (t == BelId()){ if (t == BelId()) {
for(uint32_t j = 0; j < root_bel_full_name.size(); j++) for (uint32_t j = 0; j < root_bel_full_name.size(); j++)
cpy.ids[j] = root_bel_full_name[j]; cpy.ids[j] = root_bel_full_name[j];
cpy.ids[1] = s_bel; cpy.ids[root_bel_full_name.size() - 1] = s_bel;
t = ctx->getBelByName(cpy); t = ctx->getBelByName(cpy);
add_to_cache(root_bel.tile, s_bel, t); add_to_cache(root_bel.tile, s_bel, t);
} }
if(ctx->debug){ if (ctx->debug) {
for(uint32_t j = 0; j < root_bel_full_name.size(); j++) for (uint32_t j = 0; j < root_bel_full_name.size(); j++)
cpy.ids[j] = root_bel_full_name[j]; cpy.ids[j] = root_bel_full_name[j];
cpy.ids[1] = s_bel; cpy.ids[1] = s_bel;
for (auto str : cpy) for (auto str : cpy)
@ -372,14 +373,14 @@ dict<uint32_t, BelId> idx_bel_mapping(const Context *ctx, BelId root_bel,
return idx_bel_map; return idx_bel_map;
} }
bool Arch::macro_cluster_placement( bool Arch::macro_cluster_placement(const Context *ctx, const Cluster &packed_cluster, const ClusterPOD &cluster_data,
const Context *ctx, const Cluster &packed_cluster, const ClusterPOD &cluster_data, CellInfo *root_cell, BelId root_bel,
CellInfo *root_cell, BelId root_bel, std::vector<std::pair<CellInfo *, BelId>> &placement) const std::vector<std::pair<CellInfo *, BelId>> &placement) const
{ {
// Check root_bel site_type // Check root_bel site_type
const auto &cluster = cluster_info(chip_info, packed_cluster.index); const auto &cluster = cluster_info(chip_info, packed_cluster.index);
uint32_t idx = 0; uint32_t idx = 0;
if(!find_site_idx(ctx, cluster, root_bel, idx)) if (!find_site_idx(ctx, cluster, root_bel, idx))
return false; return false;
// Check if root_bel name // Check if root_bel name
@ -390,7 +391,7 @@ bool Arch::macro_cluster_placement(
// Map cells to bels // Map cells to bels
dict<uint32_t, BelId> idx_bel_map = idx_bel_mapping(ctx, root_bel, cluster, idx, placement_idx); dict<uint32_t, BelId> idx_bel_map = idx_bel_mapping(ctx, root_bel, cluster, idx, placement_idx);
for(auto idx_bel : idx_bel_map){ for (auto idx_bel : idx_bel_map) {
placement.emplace_back(packed_cluster.cluster_nodes[idx_bel.first], idx_bel.second); placement.emplace_back(packed_cluster.cluster_nodes[idx_bel.first], idx_bel.second);
} }
@ -409,11 +410,9 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel,
if (!ctx->isValidBelForCellType(root_cell->type, root_bel)) if (!ctx->isValidBelForCellType(root_cell->type, root_bel))
return false; return false;
if (!cluster_data.from_macro) if (!cluster_data.from_macro)
return normal_cluster_placement(ctx, packed_cluster, cluster_data, root_cell, return normal_cluster_placement(ctx, packed_cluster, cluster_data, root_cell, root_bel, placement);
root_bel, placement); else {
else{ bool temp = macro_cluster_placement(ctx, packed_cluster, cluster_data, root_cell, root_bel, placement);
bool temp = macro_cluster_placement(ctx, packed_cluster, cluster_data, root_cell,
root_bel, placement);
return temp; return temp;
} }
} }
@ -506,34 +505,39 @@ static bool check_cluster_cells_compatibility(CellInfo *old_cell, CellInfo *new_
return true; return true;
} }
bool reduce(uint32_t x, uint32_t y, const ClusterPOD *cluster, dict<uint32_t, pool<CellInfo *, hash_ptr_ops>> &domain, Context *ctx){ bool reduce(uint32_t x, uint32_t y, const ClusterPOD *cluster, dict<uint32_t, pool<CellInfo *, hash_ptr_ops>> &domain,
Context *ctx)
{
// Reduce X domain by removing values, which don't satisfy binary constraint with values from Y domain.
bool change = false; bool change = false;
std::vector<CellInfo *> remove_cell; std::vector<CellInfo *> remove_cell;
uint32_t counter = 0; uint32_t counter = 0;
for (const auto &connection : cluster->connection_graph[x].connections){ for (const auto &connection : cluster->connection_graph[x].connections) {
if(connection.target_idx == y) if (connection.target_idx == y)
break; break;
counter ++; counter++;
} }
for (const auto &x_cell : domain[x]){ for (const auto &x_cell : domain[x]) {
bool found = false; bool found = false;
for (const auto &y_cell : domain[y]){ for (const auto &y_cell : domain[y]) {
found = true; found = true;
for (const auto edge : cluster->connection_graph[x].connections[counter].edges){ for (const auto edge : cluster->connection_graph[x].connections[counter].edges) {
if (!x_cell->ports.count(IdString(edge.cell_pin)) || !y_cell->ports.count(IdString(edge.other_cell_pin))){ if (!x_cell->ports.count(IdString(edge.cell_pin)) ||
!y_cell->ports.count(IdString(edge.other_cell_pin))) {
found = false; found = false;
break; break;
} }
const auto x_net = x_cell->ports[IdString(edge.cell_pin)].net; const auto x_net = x_cell->ports[IdString(edge.cell_pin)].net;
const auto y_net = y_cell->ports[IdString(edge.other_cell_pin)].net; const auto y_net = y_cell->ports[IdString(edge.other_cell_pin)].net;
if (x_net != y_net){ if (x_net != y_net) {
found = false; found = false;
break; break;
} }
bool x_driver = x_net->driver.cell == x_cell; bool x_driver = x_net->driver.cell == x_cell;
bool y_driver = y_net->driver.cell == y_cell; bool y_driver = y_net->driver.cell == y_cell;
if ((edge.dir != 0 || !y_driver) && (edge.dir != 1 || !x_driver) && (edge.dir != 2 || y_driver || x_driver)){ if ((edge.dir != 0 || !y_driver) && (edge.dir != 1 || !x_driver) &&
(edge.dir != 2 || y_driver || x_driver)) {
found = false; found = false;
break; break;
} }
@ -545,7 +549,7 @@ bool reduce(uint32_t x, uint32_t y, const ClusterPOD *cluster, dict<uint32_t, po
remove_cell.push_back(x_cell); remove_cell.push_back(x_cell);
} }
for (const auto &cell : remove_cell){ for (const auto &cell : remove_cell) {
domain[x].erase(cell); domain[x].erase(cell);
change = true; change = true;
} }
@ -553,16 +557,17 @@ bool reduce(uint32_t x, uint32_t y, const ClusterPOD *cluster, dict<uint32_t, po
return change; return change;
} }
void binary_constraint_check(const ClusterPOD *cluster, void binary_constraint_check(const ClusterPOD *cluster, std::queue<std::pair<uint32_t, uint32_t>> &workqueue,
std::queue<std::pair<uint32_t, uint32_t>> &workqueue, dict<uint32_t, pool<CellInfo *, hash_ptr_ops>> &idx_to_cells, Context *ctx)
dict<uint32_t, pool<CellInfo *, hash_ptr_ops>> &idx_to_cells, Context *ctx){ {
while (!workqueue.empty()){ while (!workqueue.empty()) {
std::pair<uint32_t, uint32_t> arc = workqueue.front(); std::pair<uint32_t, uint32_t> arc = workqueue.front();
workqueue.pop(); workqueue.pop();
uint32_t x,y; uint32_t x, y;
x = arc.first; y = arc.second; x = arc.first;
if (reduce(x, y, cluster, idx_to_cells, ctx)){ y = arc.second;
for (const auto &node : cluster->connection_graph){ if (reduce(x, y, cluster, idx_to_cells, ctx)) {
for (const auto &node : cluster->connection_graph) {
if (node.idx != arc.first) if (node.idx != arc.first)
for (const auto &connection : node.connections) for (const auto &connection : node.connections)
if (connection.target_idx == arc.first) if (connection.target_idx == arc.first)
@ -572,34 +577,35 @@ void binary_constraint_check(const ClusterPOD *cluster,
} }
} }
bool back_solver(const ClusterPOD *cluster, bool back_solver(const ClusterPOD *cluster, dict<uint32_t, pool<CellInfo *, hash_ptr_ops>> &idx_to_cells, Context *ctx)
dict<uint32_t, pool<CellInfo *, hash_ptr_ops>> &idx_to_cells, Context *ctx){ {
dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx; dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx;
for (const auto &arc : idx_to_cells) for (const auto &arc : idx_to_cells)
for (const auto &cell : arc.second) for (const auto &cell : arc.second)
possible_idx[cell].insert(arc.first); possible_idx[cell].insert(arc.first);
std::queue<uint32_t> prep; std::queue<uint32_t> prep;
for (const auto &arc : idx_to_cells){ for (const auto &arc : idx_to_cells) {
if (arc.second.size() == 0) if (arc.second.size() == 0)
return false; return false;
if (arc.second.size()>1){ if (arc.second.size() > 1) {
for (const auto &cell : arc.second){ for (const auto &cell : arc.second) {
auto copy_idx_to_cells(idx_to_cells); auto copy_idx_to_cells(idx_to_cells);
copy_idx_to_cells[arc.first].clear(); copy_idx_to_cells[arc.first].clear();
for (uint32_t idx : possible_idx[cell]){ for (uint32_t idx : possible_idx[cell]) {
copy_idx_to_cells[idx].erase(cell); copy_idx_to_cells[idx].erase(cell);
prep.push(idx); prep.push(idx);
} }
copy_idx_to_cells[arc.first].insert(cell); copy_idx_to_cells[arc.first].insert(cell);
std::queue<std::pair<uint32_t, uint32_t>> workqueue; std::queue<std::pair<uint32_t, uint32_t>> workqueue;
while(!prep.empty()){ while (!prep.empty()) {
uint32_t idx = prep.front(); prep.pop(); uint32_t idx = prep.front();
prep.pop();
for (const auto &connection : cluster->connection_graph[idx].connections) for (const auto &connection : cluster->connection_graph[idx].connections)
if (arc.first != connection.target_idx) if (arc.first != connection.target_idx)
workqueue.push(std::pair<uint32_t, uint32_t>(arc.first, connection.target_idx)); workqueue.push(std::pair<uint32_t, uint32_t>(arc.first, connection.target_idx));
} }
binary_constraint_check(cluster, workqueue, copy_idx_to_cells, ctx); binary_constraint_check(cluster, workqueue, copy_idx_to_cells, ctx);
if (back_solver(cluster, copy_idx_to_cells, ctx)){ if (back_solver(cluster, copy_idx_to_cells, ctx)) {
idx_to_cells = std::move(copy_idx_to_cells); idx_to_cells = std::move(copy_idx_to_cells);
return true; return true;
} }
@ -609,7 +615,7 @@ bool back_solver(const ClusterPOD *cluster,
return true; return true;
} }
void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index) void Arch::prepare_macro_cluster(const ClusterPOD *cluster, uint32_t index)
{ {
Context *ctx = getCtx(); Context *ctx = getCtx();
IdString cluster_name(cluster->name); IdString cluster_name(cluster->name);
@ -620,45 +626,48 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
// Find cluster roots for each macro only ones // Find cluster roots for each macro only ones
dict<IdString, CellInfo *> roots; dict<IdString, CellInfo *> roots;
for (auto &cell : cells){ for (auto &cell : cells) {
CellInfo *ci = cell.second.get(); CellInfo *ci = cell.second.get();
if(ci->macro_parent == IdString()) if (ci->macro_parent == IdString())
continue; continue;
if(ci->cluster != ClusterId()) if (ci->cluster != ClusterId())
continue; continue;
if (!cluster_cell_types.count(ci->type)) if (!cluster_cell_types.count(ci->type))
continue; continue;
if(roots.count(ci->macro_parent)) if (roots.count(ci->macro_parent))
continue; continue;
// Simple check based on cell type counting // Simple check based on cell type counting
dict<IdString, uint32_t> cells_in_macro, counter; dict<IdString, uint32_t> cells_in_macro, counter;
// cells_in_macro stores cell_types used in tested cluster and
// cell_types that are in macro_to_cells[ci->macro_parent]
pool<IdString> cell_types; pool<IdString> cell_types;
for (auto &cell_type : cluster->required_cells){ for (auto &cell_type : cluster->required_cells) {
cells_in_macro[IdString(cell_type.name)] = cell_type.count; cells_in_macro[IdString(cell_type.name)] = cell_type.count;
cell_types.insert(IdString(cell_type.name)); cell_types.insert(IdString(cell_type.name));
} }
for (auto &node_cell : macro_to_cells[ci->macro_parent]){ for (auto &node_cell : macro_to_cells[ci->macro_parent]) {
auto cell_type = node_cell->type; auto cell_type = node_cell->type;
if(!counter.count(cell_type))
counter[cell_type] = 0;
counter[cell_type]++; counter[cell_type]++;
cell_types.insert(cell_type); cell_types.insert(cell_type);
} }
bool failed = false; bool failed = false;
for(auto cell_type : cell_types){ for (auto cell_type : cell_types) {
if(ctx->verbose && cells_in_macro.count(cell_type)) if (ctx->verbose && cells_in_macro.count(cell_type))
log_info("Required: %s %d\n", cell_type.c_str(ctx), cells_in_macro[cell_type]); log_info("Required: %s %d\n", cell_type.c_str(ctx), cells_in_macro[cell_type]);
if(ctx->verbose && cells_in_macro.count(cell_type)) if (ctx->verbose && cells_in_macro.count(cell_type))
log_info("Have: %s %d\n", cell_type.c_str(ctx), counter[cell_type]); log_info("Have: %s %d\n", cell_type.c_str(ctx), counter[cell_type]);
if(!cells_in_macro.count(cell_type) || !counter.count(cell_type) || cells_in_macro[cell_type] != counter[cell_type]) if (!cells_in_macro.count(cell_type) || !counter.count(cell_type) ||
cells_in_macro[cell_type] != counter[cell_type])
failed = true; failed = true;
if(failed && ctx->verbose) if (failed && ctx->verbose)
log_info("Cell count stage failed, for sure not this cluster\n"); log_info("Cell count stage failed, for sure not this cluster\n");
if(failed) if (failed)
break; break;
} }
if(failed){ if (failed) {
roots[ci->macro_parent] = nullptr; roots[ci->macro_parent] = nullptr;
continue; continue;
} }
@ -669,42 +678,41 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
for (auto &cell : macro_to_cells[ci->macro_parent]) for (auto &cell : macro_to_cells[ci->macro_parent])
for (auto &node : cluster->connection_graph) for (auto &node : cluster->connection_graph)
if (IdString(node.cell_type) == cell->type) if (IdString(node.cell_type) == cell->type)
if (node.idx != 0 && cell->name != ci->name || if (node.idx != 0 && cell->name != ci->name || node.idx == 0 && cell->name == ci->name) {
node.idx == 0 && cell->name == ci->name ){
idx_to_cells[node.idx].insert(cell); idx_to_cells[node.idx].insert(cell);
} }
for (auto &arc : idx_to_cells){ for (auto &arc : idx_to_cells) {
std::vector<CellInfo *> remove_cell; std::vector<CellInfo *> remove_cell;
pool<IdString> used_ports; pool<IdString> used_ports;
for (const auto &port : cluster->connection_graph[arc.first].used_ports) for (const auto &port : cluster->connection_graph[arc.first].used_ports)
used_ports.insert(IdString(port.name)); used_ports.insert(IdString(port.name));
for (const auto &cell : arc.second){ for (const auto &cell : arc.second) {
uint32_t count = 0; uint32_t count = 0;
for (const auto &port : cell->ports){ for (const auto &port : cell->ports) {
if (!used_ports.count(port.first)){ if (!used_ports.count(port.first)) {
remove_cell.push_back(cell); remove_cell.push_back(cell);
break; break;
} }
count++; count++;
} }
if (count != used_ports.size()){ if (count != used_ports.size()) {
remove_cell.push_back(cell); remove_cell.push_back(cell);
break; break;
} }
} }
for (const auto &cell : remove_cell){ for (const auto &cell : remove_cell) {
arc.second.erase(cell); arc.second.erase(cell);
} }
} }
if (ctx->debug){ if (ctx->debug) {
log_info("After mono constraints are applied\n"); log_info("After mono constraints are applied\n");
dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx; dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx;
for (const auto &arc : idx_to_cells) for (const auto &arc : idx_to_cells)
for (const auto &cell : arc.second) for (const auto &cell : arc.second)
possible_idx[cell].insert(arc.first); possible_idx[cell].insert(arc.first);
for (const auto arc : possible_idx){ for (const auto arc : possible_idx) {
log_info("Possible idx %s:\n", arc.first->name.c_str(ctx)); log_info("Possible idx %s:\n", arc.first->name.c_str(ctx));
for (const auto idx : arc.second) for (const auto idx : arc.second)
log_info(" - %d\n", idx); log_info(" - %d\n", idx);
@ -714,11 +722,11 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
std::queue<std::pair<uint32_t, uint32_t>> workqueue; std::queue<std::pair<uint32_t, uint32_t>> workqueue;
for (const auto &arc : idx_to_cells) for (const auto &arc : idx_to_cells)
for (const auto &connection : cluster->connection_graph[arc.first].connections) for (const auto &connection : cluster->connection_graph[arc.first].connections)
workqueue.push(std::pair<uint32_t, uint32_t>(arc.first, connection.target_idx)); workqueue.emplace(arc.first, connection.target_idx);
binary_constraint_check(cluster, workqueue, idx_to_cells, ctx); binary_constraint_check(cluster, workqueue, idx_to_cells, ctx);
for (const auto &arc : idx_to_cells){ for (const auto &arc : idx_to_cells) {
if (arc.second.size() == 0){ if (arc.second.size() == 0) {
if (ctx->debug) if (ctx->debug)
log_info("AC-3 failed\n"); log_info("AC-3 failed\n");
failed = true; failed = true;
@ -728,14 +736,14 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
if (failed) if (failed)
continue; continue;
if (ctx->debug){ if (ctx->debug) {
log_info("After AC-3\n"); log_info("After AC-3\n");
dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx; dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx;
for (const auto &arc : idx_to_cells) for (const auto &arc : idx_to_cells)
for (const auto &cell : arc.second) for (const auto &cell : arc.second)
possible_idx[cell].insert(arc.first); possible_idx[cell].insert(arc.first);
for (const auto arc : possible_idx){ for (const auto arc : possible_idx) {
log_info("Possible idx %s:\n", arc.first->name.c_str(ctx)); log_info("Possible idx %s:\n", arc.first->name.c_str(ctx));
for (const auto idx : arc.second) for (const auto idx : arc.second)
log_info(" - %d\n", idx); log_info(" - %d\n", idx);
@ -747,35 +755,36 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
// Keep assigning cells to indices that only map to single cell // Keep assigning cells to indices that only map to single cell
// Remove this cell from other mappings and recheck binary constraints // Remove this cell from other mappings and recheck binary constraints
// Fail if there is no cell for idx or cell has no idx assign // Fail if there is no cell for idx or cell has no idx assign
do{ do {
change = false; change = false;
dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx; dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx;
pool<uint32_t> changed_idxs; pool<uint32_t> changed_idxs;
for (const auto &arc : idx_to_cells){ for (const auto &arc : idx_to_cells) {
if (arc.second.size() == 0){ if (arc.second.size() == 0) {
failed = true; failed = true;
break; break;
} }
for (const auto &cell : arc.second) for (const auto &cell : arc.second)
possible_idx[cell].insert(arc.first); possible_idx[cell].insert(arc.first);
} }
if(failed) if (failed)
break; break;
for (auto &cell : macro_to_cells[ci->macro_parent]) for (auto &cell : macro_to_cells[ci->macro_parent])
if (possible_idx[cell].size() == 0){ if (possible_idx[cell].size() == 0) {
failed = true; failed = true;
break; break;
} }
if(failed) if (failed)
break; break;
for (const auto &arc : idx_to_cells){ for (const auto &arc : idx_to_cells) {
if (arc.second.size() == 1) if (arc.second.size() == 1)
for (const auto &idx : possible_idx[*arc.second.begin()]) for (const auto &idx : possible_idx[*arc.second.begin()])
if (idx != arc.first) if (idx != arc.first)
removequeue.push(std::pair<uint32_t, CellInfo*>(idx, *arc.second.begin())); removequeue.push(std::pair<uint32_t, CellInfo *>(idx, *arc.second.begin()));
} }
while(!removequeue.empty()){ while (!removequeue.empty()) {
auto t = removequeue.front(); removequeue.pop(); auto t = removequeue.front();
removequeue.pop();
uint32_t idx = t.first; uint32_t idx = t.first;
CellInfo *cell = t.second; CellInfo *cell = t.second;
idx_to_cells[idx].erase(cell); idx_to_cells[idx].erase(cell);
@ -787,20 +796,20 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
workqueue.push(std::pair<uint32_t, uint32_t>(idx, connection.target_idx)); workqueue.push(std::pair<uint32_t, uint32_t>(idx, connection.target_idx));
binary_constraint_check(cluster, workqueue, idx_to_cells, ctx); binary_constraint_check(cluster, workqueue, idx_to_cells, ctx);
}while(change); } while (change);
if(failed){ if (failed) {
if(ctx->debug) if (ctx->debug)
log_info("Single cell mapping failed\n"); log_info("Single cell mapping failed\n");
continue; continue;
} }
if (ctx->debug){ if (ctx->debug) {
log_info("After mapping indices with single cell\n"); log_info("After mapping indices with single cell\n");
dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx; dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx;
for (const auto &arc : idx_to_cells) for (const auto &arc : idx_to_cells)
for (const auto &cell : arc.second) for (const auto &cell : arc.second)
possible_idx[cell].insert(arc.first); possible_idx[cell].insert(arc.first);
for (const auto arc : possible_idx){ for (const auto arc : possible_idx) {
log_info("Possible idx %s:\n", arc.first->name.c_str(ctx)); log_info("Possible idx %s:\n", arc.first->name.c_str(ctx));
for (const auto idx : arc.second) for (const auto idx : arc.second)
log_info(" - %d\n", idx); log_info(" - %d\n", idx);
@ -810,19 +819,19 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
// Next step is to run solver with backtracing to solve for other idx<->cell mappings // Next step is to run solver with backtracing to solve for other idx<->cell mappings
if (ctx->debug) if (ctx->debug)
log_info("Back solver\n"); log_info("Back solver\n");
if(!back_solver(cluster, idx_to_cells, ctx)){ if (!back_solver(cluster, idx_to_cells, ctx)) {
if(ctx->debug) if (ctx->debug)
log_info("Back solver failed\n"); log_info("Back solver failed\n");
continue; continue;
} }
if (ctx->debug){ if (ctx->debug) {
log_info("Final mapping after back solver\n"); log_info("Final mapping after back solver\n");
dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx; dict<CellInfo *, pool<uint32_t>, hash_ptr_ops> possible_idx;
for (const auto &arc : idx_to_cells) for (const auto &arc : idx_to_cells)
for (const auto &cell : arc.second) for (const auto &cell : arc.second)
possible_idx[cell].insert(arc.first); possible_idx[cell].insert(arc.first);
for (const auto arc : possible_idx){ for (const auto arc : possible_idx) {
log_info("Possible idx %s:\n", arc.first->name.c_str(ctx)); log_info("Possible idx %s:\n", arc.first->name.c_str(ctx));
for (const auto idx : arc.second) for (const auto idx : arc.second)
log_info(" - %d\n", idx); log_info(" - %d\n", idx);
@ -832,9 +841,9 @@ void Arch::prepare_macro_cluster( const ClusterPOD *cluster, uint32_t index)
cluster_info.root = ci; cluster_info.root = ci;
cluster_info.index = index; cluster_info.index = index;
cluster_info.cluster_nodes.resize(idx_to_cells.size()); cluster_info.cluster_nodes.resize(idx_to_cells.size());
ci->cluster.set(ctx, ci->name.str(ctx)); ci->cluster = ci->name;
for (auto &arc : idx_to_cells){ for (auto &arc : idx_to_cells) {
CellInfo * sub_cell = arc.second.pop(); CellInfo *sub_cell = arc.second.pop();
if (ctx->verbose) if (ctx->verbose)
log_info("%d %s - %s\n", arc.first, sub_cell->name.c_str(ctx), sub_cell->type.c_str(ctx)); log_info("%d %s - %s\n", arc.first, sub_cell->name.c_str(ctx), sub_cell->type.c_str(ctx));
sub_cell->cluster = ci->cluster; sub_cell->cluster = ci->cluster;
@ -1040,24 +1049,23 @@ void Arch::pack_cluster()
dump_clusters(chip_info, ctx); dump_clusters(chip_info, ctx);
for (uint32_t i = 0; i < chip_info->clusters.size(); ++i) { for (uint32_t i = 0; i < chip_info->clusters.size(); ++i) {
if (!chip_info->clusters[i].from_macro){ if (!chip_info->clusters[i].from_macro) {
const auto &cluster = chip_info->clusters[i]; const auto &cluster = chip_info->clusters[i];
prepare_cluster(&cluster, i); prepare_cluster(&cluster, i);
} else if(chip_info->clusters[i].physical_placements.size() > 0) { } else if (chip_info->clusters[i].physical_placements.size() > 0) {
const auto &cluster = chip_info->clusters[i]; const auto &cluster = chip_info->clusters[i];
if(ctx->verbose){ if (ctx->verbose) {
log_info("%s\n", IdString(cluster.name).c_str(ctx));\ log_info("%s\n", IdString(cluster.name).c_str(ctx));
} }
prepare_macro_cluster(&cluster, i); prepare_macro_cluster(&cluster, i);
} } else {
else {
// No physical placement definitions found for given macro. // No physical placement definitions found for given macro.
// Use default place and route algorithm as routes connectiong // Use default place and route algorithm as routes connectiong
// cells will use global routing // cells will use global routing
const auto &cluster = chip_info->clusters[i]; const auto &cluster = chip_info->clusters[i];
if(ctx->verbose) if (ctx->verbose)
log_info("Out of site cluster from macro: %s\n", IdString(cluster.name).c_str(ctx)); log_info("Out of site cluster from macro: %s\n", IdString(cluster.name).c_str(ctx));
} }
} }

View File

@ -423,39 +423,35 @@ NPNR_PACKED_STRUCT(struct ChainablePortPOD {
int16_t avg_y_offset; int16_t avg_y_offset;
}); });
NPNR_PACKED_STRUCT(struct ClusterRequiredCellPOD{ NPNR_PACKED_STRUCT(struct ClusterRequiredCellPOD {
uint32_t name; uint32_t name;
uint32_t count; uint32_t count;
}); });
NPNR_PACKED_STRUCT(struct ClusterUsedPortPOD{ NPNR_PACKED_STRUCT(struct ClusterUsedPortPOD { uint32_t name; });
uint32_t name;
});
NPNR_PACKED_STRUCT(struct ClusterEdgePOD{ NPNR_PACKED_STRUCT(struct ClusterEdgePOD {
uint32_t dir; uint32_t dir;
uint32_t cell_pin; uint32_t cell_pin;
uint32_t other_cell_pin; uint32_t other_cell_pin;
uint32_t other_cell_type; uint32_t other_cell_type;
}); });
NPNR_PACKED_STRUCT(struct ClusterConnectionsPOD{ NPNR_PACKED_STRUCT(struct ClusterConnectionsPOD {
uint32_t target_idx; uint32_t target_idx;
RelSlice<ClusterEdgePOD> edges; RelSlice<ClusterEdgePOD> edges;
}); });
NPNR_PACKED_STRUCT(struct ClusterConnectionGraphPOD{ NPNR_PACKED_STRUCT(struct ClusterConnectionGraphPOD {
uint32_t idx; uint32_t idx;
uint32_t cell_type; uint32_t cell_type;
RelSlice<ClusterConnectionsPOD> connections; RelSlice<ClusterConnectionsPOD> connections;
RelSlice<ClusterUsedPortPOD> used_ports; RelSlice<ClusterUsedPortPOD> used_ports;
}); });
NPNR_PACKED_STRUCT(struct ClusterPhysicalPlacementEntryPOD{ NPNR_PACKED_STRUCT(struct ClusterPhysicalPlacementEntryPOD { RelSlice<uint32_t> bels; });
RelSlice<uint32_t> bels;
});
NPNR_PACKED_STRUCT(struct ClusterPhysicalPlacementsPOD{ NPNR_PACKED_STRUCT(struct ClusterPhysicalPlacementsPOD {
uint32_t site_type; uint32_t site_type;
RelSlice<ClusterPhysicalPlacementEntryPOD> places; RelSlice<ClusterPhysicalPlacementEntryPOD> places;
}); });

View File

@ -79,7 +79,6 @@ void Arch::expand_macros()
// Get the ultimate root of this macro expansion // Get the ultimate root of this macro expansion
IdString parent = (cell->macro_parent == IdString()) ? cell->name : cell->macro_parent; IdString parent = (cell->macro_parent == IdString()) ? cell->name : cell->macro_parent;
log_info("%s %s\n", cell->name.c_str(ctx), parent.c_str(ctx));
// Create child instances // Create child instances
for (const auto &inst : macro->cell_insts) { for (const auto &inst : macro->cell_insts) {
CellInfo *inst_cell = CellInfo *inst_cell =
@ -88,7 +87,6 @@ void Arch::expand_macros()
inst_cell->params[IdString(param.key)] = IdString(param.value).str(ctx); inst_cell->params[IdString(param.key)] = IdString(param.value).str(ctx);
} }
inst_cell->macro_parent = parent; inst_cell->macro_parent = parent;
log_info(" %s %s\n", inst_cell->name.c_str(ctx), inst_cell->type.c_str(ctx));
next_cells.push_back(inst_cell); next_cells.push_back(inst_cell);
} }
// Create and connect nets // Create and connect nets