Adding constraint satisfaction checks for debugging

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-08-03 16:59:45 +02:00
parent fd2174149c
commit dc4ab55b27
3 changed files with 18 additions and 9 deletions

View File

@ -281,7 +281,7 @@ struct CellInfo : ArchCellInfo
std::unordered_map<IdString, IdString> pins; std::unordered_map<IdString, IdString> pins;
// placement constraints // placement constraints
CellInfo *constr_parent; CellInfo *constr_parent = nullptr;
std::vector<CellInfo *> constr_children; std::vector<CellInfo *> constr_children;
const int UNCONSTR = INT_MIN; const int UNCONSTR = INT_MIN;
int constr_x = UNCONSTR; // this.x - parent.x int constr_x = UNCONSTR; // this.x - parent.x

View File

@ -438,13 +438,17 @@ class ConstraintLegaliseWorker
} }
} }
for (auto rippedCell : rippedCells) { for (auto rippedCell : rippedCells) {
bool res = place_single_cell(ctx, rippedCell, STRENGTH_WEAK); bool res = place_single_cell(ctx, rippedCell, true);
if (!res) { if (!res) {
log_error("failed to place cell '%s' after relative constraint legalisation\n", log_error("failed to place cell '%s' after relative constraint legalisation\n",
rippedCell->name.c_str(ctx)); rippedCell->name.c_str(ctx));
return false; return false;
} }
} }
for (auto cell : sorted(ctx->cells))
if (get_constraints_distance(ctx, cell.second) != 0)
log_error("constraint satisfaction check failed for cell '%s' at Bel '%s'\n", cell.first.c_str(ctx),
ctx->getBelName(cell.second->bel).c_str(ctx));
return true; return true;
} }
}; };

View File

@ -40,11 +40,12 @@
#include "place_common.h" #include "place_common.h"
#include "timing.h" #include "timing.h"
#include "util.h" #include "util.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
class SAPlacer class SAPlacer
{ {
public: public:
SAPlacer(Context *ctx) : ctx(ctx) SAPlacer(Context *ctx) : ctx(ctx)
{ {
int num_bel_types = 0; int num_bel_types = 0;
@ -59,11 +60,11 @@ class SAPlacer
type_idx = bel_types.at(type); type_idx = bel_types.at(type);
} }
if (int(fast_bels.size()) < type_idx + 1) if (int(fast_bels.size()) < type_idx + 1)
fast_bels.resize(type_idx + 1); fast_bels.resize(type_idx + 1);
if (int(fast_bels.at(type_idx).size()) < (loc.x + 1)) if (int(fast_bels.at(type_idx).size()) < (loc.x + 1))
fast_bels.at(type_idx).resize(loc.x + 1); fast_bels.at(type_idx).resize(loc.x + 1);
if (int(fast_bels.at(type_idx).at(loc.x).size()) < (loc.y + 1)) if (int(fast_bels.at(type_idx).at(loc.x).size()) < (loc.y + 1))
fast_bels.at(type_idx).at(loc.x).resize(loc.y + 1); fast_bels.at(type_idx).at(loc.x).resize(loc.y + 1);
max_x = std::max(max_x, loc.x); max_x = std::max(max_x, loc.x);
max_y = std::max(max_y, loc.y); max_y = std::max(max_y, loc.y);
fast_bels.at(type_idx).at(loc.x).at(loc.y).push_back(bel); fast_bels.at(type_idx).at(loc.x).at(loc.y).push_back(bel);
@ -272,12 +273,16 @@ class SAPlacer
} }
} }
} }
for (auto cell : sorted(ctx->cells))
if (get_constraints_distance(ctx, cell.second) != 0)
log_error("constraint satisfaction check failed for cell '%s' at Bel '%s'\n", cell.first.c_str(ctx),
ctx->getBelName(cell.second->bel).c_str(ctx));
timing_analysis(ctx, true /* print_fmax */); timing_analysis(ctx, true /* print_fmax */);
ctx->unlock(); ctx->unlock();
return true; return true;
} }
private: private:
// Initial random placement // Initial random placement
void place_initial(CellInfo *cell) void place_initial(CellInfo *cell)
{ {
@ -286,7 +291,7 @@ class SAPlacer
while (!all_placed) { while (!all_placed) {
BelId best_bel = BelId(); BelId best_bel = BelId();
uint64_t best_score = std::numeric_limits<uint64_t>::max(), uint64_t best_score = std::numeric_limits<uint64_t>::max(),
best_ripup_score = std::numeric_limits<uint64_t>::max(); best_ripup_score = std::numeric_limits<uint64_t>::max();
CellInfo *ripup_target = nullptr; CellInfo *ripup_target = nullptr;
BelId ripup_bel = BelId(); BelId ripup_bel = BelId();
if (cell->bel != BelId()) { if (cell->bel != BelId()) {
@ -397,7 +402,7 @@ class SAPlacer
metrics.at(new_wl.first) = new_wl.second; metrics.at(new_wl.first) = new_wl.second;
return true; return true;
swap_fail: swap_fail:
ctx->bindBel(oldBel, cell->name, STRENGTH_WEAK); ctx->bindBel(oldBel, cell->name, STRENGTH_WEAK);
if (other != IdString()) { if (other != IdString()) {
ctx->bindBel(newBel, other, STRENGTH_WEAK); ctx->bindBel(newBel, other, STRENGTH_WEAK);