placer1: Consider regions during placement

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2018-12-13 14:27:33 +00:00
parent ade72de02f
commit ae33ff397f
3 changed files with 38 additions and 16 deletions

View File

@ -529,4 +529,12 @@ int get_constraints_distance(const Context *ctx, const CellInfo *cell)
return dist;
}
bool check_cell_bel_region(const CellInfo *cell, BelId bel)
{
if (cell->region != nullptr && cell->region->constr_bels && !cell->region->bels.count(bel))
return false;
else
return true;
}
NEXTPNR_NAMESPACE_END

View File

@ -49,6 +49,10 @@ bool legalise_relative_constraints(Context *ctx);
// Get the total distance from satisfied constraints for a cell
int get_constraints_distance(const Context *ctx, const CellInfo *cell);
// Check that a Bel is within the region for a cell
bool check_cell_bel_region(const CellInfo *cell, BelId bel);
NEXTPNR_NAMESPACE_END
#endif

View File

@ -44,7 +44,6 @@
#include "timing.h"
#include "util.h"
namespace std {
template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t>>
{
@ -120,7 +119,8 @@ class SAPlacer
build_port_index();
}
~SAPlacer() {
~SAPlacer()
{
for (auto &net : ctx->nets)
net.second->udata = old_udata[net.second->udata];
}
@ -301,7 +301,8 @@ class SAPlacer
autoplaced.clear();
chain_basis.clear();
for (auto cell : sorted(ctx->cells)) {
if (cell.second->belStrength <= STRENGTH_STRONG && cell.second->constr_parent == nullptr && !cell.second->constr_children.empty())
if (cell.second->belStrength <= STRENGTH_STRONG && cell.second->constr_parent == nullptr &&
!cell.second->constr_children.empty())
chain_basis.push_back(cell.second);
else if (cell.second->belStrength < STRENGTH_STRONG)
autoplaced.push_back(cell.second);
@ -484,12 +485,14 @@ class SAPlacer
return false;
}
inline bool is_constrained(CellInfo *cell) {
inline bool is_constrained(CellInfo *cell)
{
return cell->constr_parent != nullptr || !cell->constr_children.empty();
}
// Swap the Bel of a cell with another, return the original location
BelId swap_cell_bels(CellInfo *cell, BelId newBel) {
BelId swap_cell_bels(CellInfo *cell, BelId newBel)
{
BelId oldBel = cell->bel;
CellInfo *bound = ctx->getBoundBelCell(newBel);
if (bound != nullptr)
@ -502,7 +505,8 @@ class SAPlacer
}
// Discover the relative positions of all cells in a chain
void discover_chain(Loc baseLoc, CellInfo *cell, std::vector<std::pair<CellInfo*, Loc>> &cell_rel) {
void discover_chain(Loc baseLoc, CellInfo *cell, std::vector<std::pair<CellInfo *, Loc>> &cell_rel)
{
Loc cellLoc = ctx->getBelLocation(cell->bel);
Loc rel{cellLoc.x - baseLoc.x, cellLoc.y - baseLoc.y, cellLoc.z};
cell_rel.emplace_back(std::make_pair(cell, rel));
@ -511,7 +515,8 @@ class SAPlacer
}
// Attempt to swap a chain with a non-chain
bool try_swap_chain(CellInfo *cell, BelId newBase) {
bool try_swap_chain(CellInfo *cell, BelId newBase)
{
std::vector<std::pair<CellInfo *, Loc>> cell_rel;
std::unordered_set<IdString> cells;
std::vector<std::pair<CellInfo *, BelId>> moves_made;
@ -538,7 +543,8 @@ class SAPlacer
CellInfo *bound = ctx->getBoundBelCell(targetBel);
// We don't consider swapping chains with other chains, at least for the time being - unless it is
// part of this chain
if (bound != nullptr && !cells.count(bound->name) && (bound->belStrength >= STRENGTH_STRONG || is_constrained(bound)))
if (bound != nullptr && !cells.count(bound->name) &&
(bound->belStrength >= STRENGTH_STRONG || is_constrained(bound)))
return false;
dest_bels.emplace_back(std::make_pair(cr.first, targetBel));
}
@ -550,12 +556,14 @@ class SAPlacer
moves_made.emplace_back(std::make_pair(db.first, oldBel));
}
for (const auto &mm : moves_made) {
if (!ctx->isBelLocationValid(mm.first->bel))
if (!ctx->isBelLocationValid(mm.first->bel) || !check_cell_bel_region(mm.first, mm.first->bel))
goto swap_fail;
if (!ctx->isBelLocationValid(mm.second))
goto swap_fail;
add_move_cell(moveChange, mm.first, mm.second);
CellInfo *bound = ctx->getBoundBelCell(mm.second);
if (bound && !check_cell_bel_region(bound, bound->bel))
goto swap_fail;
add_move_cell(moveChange, mm.first, mm.second);
if (bound != nullptr)
add_move_cell(moveChange, bound, mm.first->bel);
}
@ -605,6 +613,8 @@ swap_fail:
if (loc.z != force_z)
continue;
}
if (!check_cell_bel_region(cell, bel))
continue;
if (locked_bels.find(bel) != locked_bels.end())
continue;
return bel;