ecp5: Fix placement of ECLKBRIDGECS
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
5cf0ed5ede
commit
58b7cb920f
52
ecp5/pack.cc
52
ecp5/pack.cc
@ -2353,6 +2353,7 @@ class Ecp5Packer
|
|||||||
for (auto cell : sorted(ctx->cells)) {
|
for (auto cell : sorted(ctx->cells)) {
|
||||||
CellInfo *ci = cell.second;
|
CellInfo *ci = cell.second;
|
||||||
if (ci->type == id_ECLKBRIDGECS) {
|
if (ci->type == id_ECLKBRIDGECS) {
|
||||||
|
Loc loc;
|
||||||
NetInfo *i0 = get_net_or_empty(ci, id_CLK0), *i1 = get_net_or_empty(ci, id_CLK1),
|
NetInfo *i0 = get_net_or_empty(ci, id_CLK0), *i1 = get_net_or_empty(ci, id_CLK1),
|
||||||
*o = get_net_or_empty(ci, id_ECSOUT);
|
*o = get_net_or_empty(ci, id_ECSOUT);
|
||||||
for (NetInfo *input : {i0, i1}) {
|
for (NetInfo *input : {i0, i1}) {
|
||||||
@ -2366,24 +2367,53 @@ class Ecp5Packer
|
|||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
if (ctx->getBelType(bel) != id_ECLKBRIDGECS)
|
if (ctx->getBelType(bel) != id_ECLKBRIDGECS)
|
||||||
continue;
|
continue;
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
loc = ctx->getBelLocation(bel);
|
||||||
if (loc.x == user_loc.x) {
|
if (loc.x == user_loc.x) {
|
||||||
ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx);
|
ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx);
|
||||||
if (o != nullptr)
|
|
||||||
for (auto user2 : o->users) {
|
|
||||||
// Set side hint to ensure edge clock choice is routeable
|
|
||||||
if (user2.cell->type == id_ECLKSYNCB && user2.port == id_ECLKI) {
|
|
||||||
NetInfo *synco = get_net_or_empty(user2.cell, id_ECLKO);
|
|
||||||
if (synco != nullptr)
|
|
||||||
bridge_side_hint[synco] = (loc.x > 1) ? 0 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto eclkbridge_done;
|
goto eclkbridge_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (input->driver.cell != nullptr) {
|
||||||
|
CellInfo *drv = input->driver.cell;
|
||||||
|
if (!drv->attrs.count(ctx->id("BEL")))
|
||||||
|
continue;
|
||||||
|
Loc drv_loc = ctx->getBelLocation(
|
||||||
|
ctx->getBelByName(ctx->id(drv->attrs.at(ctx->id("BEL")).as_string())));
|
||||||
|
BelId closest;
|
||||||
|
int closest_x = -1; // aim for same side of chip
|
||||||
|
for (auto bel : ctx->getBels()) {
|
||||||
|
if (ctx->getBelType(bel) != id_ECLKBRIDGECS)
|
||||||
|
continue;
|
||||||
|
loc = ctx->getBelLocation(bel);
|
||||||
|
if (closest_x == -1 || std::abs(loc.x - drv_loc.x) < std::abs(closest_x - drv_loc.x)) {
|
||||||
|
closest_x = loc.x;
|
||||||
|
closest = bel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NPNR_ASSERT(closest != BelId());
|
||||||
|
loc = ctx->getBelLocation(closest);
|
||||||
|
ci->attrs[ctx->id("BEL")] = ctx->getBelName(closest).str(ctx);
|
||||||
|
goto eclkbridge_done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If all else fails, place randomly
|
||||||
|
for (auto bel : ctx->getBels()) {
|
||||||
|
if (ctx->getBelType(bel) != id_ECLKBRIDGECS)
|
||||||
|
continue;
|
||||||
|
loc = ctx->getBelLocation(bel);
|
||||||
|
ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx);
|
||||||
}
|
}
|
||||||
eclkbridge_done:
|
eclkbridge_done:
|
||||||
|
if (o != nullptr)
|
||||||
|
for (auto user2 : o->users) {
|
||||||
|
// Set side hint to ensure edge clock choice is routeable
|
||||||
|
if (user2.cell->type == id_ECLKSYNCB && user2.port == id_ECLKI) {
|
||||||
|
NetInfo *synco = get_net_or_empty(user2.cell, id_ECLKO);
|
||||||
|
if (synco != nullptr)
|
||||||
|
bridge_side_hint[synco] = (loc.x > 1) ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2659,12 +2689,12 @@ class Ecp5Packer
|
|||||||
prepack_checks();
|
prepack_checks();
|
||||||
pack_io();
|
pack_io();
|
||||||
pack_dqsbuf();
|
pack_dqsbuf();
|
||||||
|
preplace_plls();
|
||||||
pack_iologic();
|
pack_iologic();
|
||||||
pack_ebr();
|
pack_ebr();
|
||||||
pack_dsps();
|
pack_dsps();
|
||||||
pack_dcus();
|
pack_dcus();
|
||||||
pack_misc();
|
pack_misc();
|
||||||
preplace_plls();
|
|
||||||
pack_constants();
|
pack_constants();
|
||||||
pack_dram();
|
pack_dram();
|
||||||
pack_carries();
|
pack_carries();
|
||||||
|
Loading…
Reference in New Issue
Block a user