placer1: Consider regions during placement
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
ade72de02f
commit
ae33ff397f
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user