mirror of https://github.com/YosysHQ/nextpnr.git
Implement getBelValidityConflict for gatemate
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
9c6b106195
commit
cd1e403c0d
|
|
@ -1003,7 +1003,26 @@ class HeAPPlacer
|
||||||
}
|
}
|
||||||
// Provisionally bind the bel
|
// Provisionally bind the bel
|
||||||
ctx->bindBel(sz, ci, STRENGTH_WEAK);
|
ctx->bindBel(sz, ci, STRENGTH_WEAK);
|
||||||
|
// Handle legality-driven ripups
|
||||||
|
bool is_illegal = false;
|
||||||
|
CellInfo *conflict = nullptr;
|
||||||
|
BelId conflict_bel = BelId();
|
||||||
|
|
||||||
if (require_validity && !ctx->isBelLocationValid(sz)) {
|
if (require_validity && !ctx->isBelLocationValid(sz)) {
|
||||||
|
conflict = ctx->getBelValidityConflict(sz);
|
||||||
|
// Only rip up conflicts without constraints
|
||||||
|
if (!conflict || conflict->cluster != ClusterId() || conflict->belStrength > STRENGTH_WEAK) {
|
||||||
|
is_illegal = true;
|
||||||
|
conflict = nullptr; // so we don't add it back to remaining later
|
||||||
|
} else {
|
||||||
|
conflict_bel = conflict->bel;
|
||||||
|
ctx->unbindBel(conflict_bel);
|
||||||
|
// This is the contract for getBelValidityConflict that the ripup has to make the location valid
|
||||||
|
NPNR_ASSERT(ctx->isBelLocationValid(sz));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_illegal) {
|
||||||
// New location is not legal; unbind the cell (and rebind the cell we ripped up if
|
// New location is not legal; unbind the cell (and rebind the cell we ripped up if
|
||||||
// applicable)
|
// applicable)
|
||||||
ctx->unbindBel(sz);
|
ctx->unbindBel(sz);
|
||||||
|
|
@ -1012,6 +1031,8 @@ class HeAPPlacer
|
||||||
} else if (iter_at_radius < need_to_explore) {
|
} else if (iter_at_radius < need_to_explore) {
|
||||||
// It's legal, but we haven't tried enough locations yet
|
// It's legal, but we haven't tried enough locations yet
|
||||||
ctx->unbindBel(sz);
|
ctx->unbindBel(sz);
|
||||||
|
if (conflict != nullptr)
|
||||||
|
ctx->bindBel(conflict_bel, conflict, STRENGTH_WEAK);
|
||||||
if (bound != nullptr)
|
if (bound != nullptr)
|
||||||
ctx->bindBel(sz, bound, STRENGTH_WEAK);
|
ctx->bindBel(sz, bound, STRENGTH_WEAK);
|
||||||
int input_len = 0;
|
int input_len = 0;
|
||||||
|
|
@ -1040,6 +1061,10 @@ class HeAPPlacer
|
||||||
remaining.emplace(chain_size[bound->name] *
|
remaining.emplace(chain_size[bound->name] *
|
||||||
cfg.get_cell_legalisation_weight(ctx, bound),
|
cfg.get_cell_legalisation_weight(ctx, bound),
|
||||||
bound->name);
|
bound->name);
|
||||||
|
if (conflict != nullptr)
|
||||||
|
remaining.emplace(chain_size[conflict->name] *
|
||||||
|
cfg.get_cell_legalisation_weight(ctx, conflict),
|
||||||
|
conflict->name);
|
||||||
Loc loc = ctx->getBelLocation(sz);
|
Loc loc = ctx->getBelLocation(sz);
|
||||||
cell_locs[ci->name].x = loc.x;
|
cell_locs[ci->name].x = loc.x;
|
||||||
cell_locs[ci->name].y = loc.y;
|
cell_locs[ci->name].y = loc.y;
|
||||||
|
|
|
||||||
|
|
@ -688,6 +688,10 @@ struct Arch : BaseArch<ArchRanges>
|
||||||
{
|
{
|
||||||
return uarch->isBelLocationValid(bel, explain_invalid);
|
return uarch->isBelLocationValid(bel, explain_invalid);
|
||||||
}
|
}
|
||||||
|
CellInfo *getBelValidityConflict(BelId bel) const override
|
||||||
|
{
|
||||||
|
return uarch->getBelValidityConflict(bel);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ struct HimbaechelAPI
|
||||||
virtual BelBucketId getBelBucketForCellType(IdString cell_type) const;
|
virtual BelBucketId getBelBucketForCellType(IdString cell_type) const;
|
||||||
virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const;
|
virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const;
|
||||||
virtual bool isBelLocationValid(BelId bel, bool explain_invalid = false) const { return true; }
|
virtual bool isBelLocationValid(BelId bel, bool explain_invalid = false) const { return true; }
|
||||||
|
virtual CellInfo *getBelValidityConflict(BelId bel) const { return nullptr; }
|
||||||
|
|
||||||
// --- Wire and pip functions ---
|
// --- Wire and pip functions ---
|
||||||
// Called when a wire/pip is placed/unplaced (with net=nullptr for a unbind)
|
// Called when a wire/pip is placed/unplaced (with net=nullptr for a unbind)
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,28 @@ bool GateMateImpl::isBelLocationValid(BelId bel, bool explain_invalid) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CellInfo *GateMateImpl::getBelValidityConflict(BelId bel) const
|
||||||
|
{
|
||||||
|
if (ctx->getBelBucketForBel(bel) == id_RAM_HALF) {
|
||||||
|
CellInfo *cell = ctx->getBoundBelCell(bel);
|
||||||
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
|
CellInfo *adj_half =
|
||||||
|
ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.z == RAM_HALF_L_Z ? loc.y - 8 : loc.y + 8,
|
||||||
|
loc.z == RAM_HALF_L_Z ? RAM_HALF_U_Z : RAM_HALF_L_Z)));
|
||||||
|
if (adj_half) {
|
||||||
|
const auto &half_data = fast_cell_info.at(cell->flat_index);
|
||||||
|
if (half_data.used) {
|
||||||
|
const auto &adj_data = fast_cell_info.at(adj_half->flat_index);
|
||||||
|
if (adj_data.used) {
|
||||||
|
if (adj_data.config != half_data.config)
|
||||||
|
return adj_half;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Loc GateMateImpl::getRelativeConstraint(Loc &root_loc, IdString id) const
|
Loc GateMateImpl::getRelativeConstraint(Loc &root_loc, IdString id) const
|
||||||
{
|
{
|
||||||
Loc child_loc;
|
Loc child_loc;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ struct GateMateImpl : HimbaechelAPI
|
||||||
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
|
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
|
||||||
|
|
||||||
bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override;
|
bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override;
|
||||||
|
CellInfo *getBelValidityConflict(BelId bel) const override;
|
||||||
|
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override;
|
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override;
|
||||||
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override;
|
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue