Move repack code

This commit is contained in:
Miodrag Milanovic 2025-07-08 09:59:58 +02:00
parent bf0fa39ba9
commit f8aab41b8b
5 changed files with 112 additions and 106 deletions

View File

@ -179,112 +179,16 @@ bool GateMateImpl::getClusterPlacement(ClusterId cluster, BelId root_bel,
return getChildPlacement(root_cell, root_loc, placement); return getChildPlacement(root_cell, root_loc, placement);
} }
void GateMateImpl::rename_param(CellInfo *cell, IdString name, IdString new_name, int width)
{
if (cell->params.count(name)) {
cell->params[new_name] = Property(int_or_default(cell->params, name, 0), width);
cell->unsetParam(name);
}
}
void GateMateImpl::prePlace() { assign_cell_info(); } void GateMateImpl::prePlace() { assign_cell_info(); }
void GateMateImpl::postPlace() void GateMateImpl::postPlace() { repack(); }
void GateMateImpl::preRoute()
{ {
ctx->assignArchInfo(); ctx->assignArchInfo();
std::vector<IdString> delete_cells; route_clock();
for (auto &cell : ctx->cells) {
if (cell.second->type.in(id_CPE_L2T4)) {
Loc l = ctx->getBelLocation(cell.second->bel);
if (l.z == CPE_LT_L_Z) {
if (!cell.second->params.count(id_INIT_L20))
cell.second->params[id_INIT_L20] = Property(0b1100, 4);
}
cell.second->params[id_L2T4_UPPER] = Property((l.z == CPE_LT_U_Z) ? 1 : 0, 1);
} else if (cell.second->type.in(id_CPE_LT_L)) {
BelId bel = cell.second->bel;
PlaceStrength strength = cell.second->belStrength;
uint8_t func = int_or_default(cell.second->params, id_C_FUNCTION, 0);
Loc loc = ctx->getBelLocation(bel);
loc.z = CPE_LT_FULL_Z;
ctx->unbindBel(bel);
ctx->bindBel(ctx->getBelByLocation(loc), cell.second.get(), strength);
cell.second->renamePort(id_IN1, id_IN5);
cell.second->renamePort(id_IN2, id_IN6);
cell.second->renamePort(id_IN3, id_IN7);
cell.second->renamePort(id_IN4, id_IN8);
cell.second->renamePort(id_OUT, id_OUT1);
cell.second->renamePort(id_CPOUT, id_CPOUT1);
if (!cell.second->params.count(id_INIT_L20))
cell.second->params[id_INIT_L20] = Property(0b1100, 4);
rename_param(cell.second.get(), id_INIT_L00, id_INIT_L02, 4);
rename_param(cell.second.get(), id_INIT_L01, id_INIT_L03, 4);
rename_param(cell.second.get(), id_INIT_L10, id_INIT_L11, 4);
switch (func) {
case C_ADDF:
cell.second->type = id_CPE_ADDF;
break;
case C_ADDF2:
cell.second->type = id_CPE_ADDF2;
break;
case C_MULT:
cell.second->type = id_CPE_MULT;
break;
case C_MX4:
cell.second->type = id_CPE_MX4;
break;
case C_EN_CIN:
log_error("EN_CIN should be using L2T4.\n");
break;
case C_CONCAT:
cell.second->type = id_CPE_CONCAT;
break;
case C_ADDCIN:
log_error("ADDCIN should be using L2T4.\n");
break;
default:
break;
}
loc.z = CPE_LT_U_Z;
CellInfo *upper = ctx->getBoundBelCell(ctx->getBelByLocation(loc));
if (upper->params.count(id_INIT_L00))
cell.second->params[id_INIT_L00] = Property(int_or_default(upper->params, id_INIT_L00, 0), 4);
if (upper->params.count(id_INIT_L01))
cell.second->params[id_INIT_L01] = Property(int_or_default(upper->params, id_INIT_L01, 0), 4);
if (upper->params.count(id_INIT_L10))
cell.second->params[id_INIT_L10] = Property(int_or_default(upper->params, id_INIT_L10, 0), 4);
if (upper->params.count(id_C_I1))
cell.second->params[id_C_I1] = Property(int_or_default(upper->params, id_C_I1, 0), 1);
if (upper->params.count(id_C_I2))
cell.second->params[id_C_I2] = Property(int_or_default(upper->params, id_C_I2, 0), 1);
upper->movePortTo(id_IN1, cell.second.get(), id_IN1);
upper->movePortTo(id_IN2, cell.second.get(), id_IN2);
upper->movePortTo(id_IN3, cell.second.get(), id_IN3);
upper->movePortTo(id_IN4, cell.second.get(), id_IN4);
upper->movePortTo(id_OUT, cell.second.get(), id_OUT2);
upper->movePortTo(id_CPOUT, cell.second.get(), id_CPOUT2);
}
// Mark for deletion
else if (cell.second->type.in(id_CPE_LT_U, id_CPE_DUMMY)) {
delete_cells.push_back(cell.second->name);
}
}
for (auto pcell : delete_cells) {
for (auto &port : ctx->cells[pcell]->ports) {
ctx->cells[pcell]->disconnectPort(port.first);
}
ctx->unbindBel(ctx->cells[pcell]->bel);
ctx->cells.erase(pcell);
}
delete_cells.clear();
ctx->assignArchInfo();
} }
void GateMateImpl::preRoute() { route_clock(); }
void GateMateImpl::postRoute() void GateMateImpl::postRoute()
{ {
ctx->assignArchInfo(); ctx->assignArchInfo();

View File

@ -63,7 +63,6 @@ struct GateMateImpl : HimbaechelAPI
bool isPipInverting(PipId pip) const override; bool isPipInverting(PipId pip) const override;
const GateMateTileExtraDataPOD *tile_extra_data(int tile) const; const GateMateTileExtraDataPOD *tile_extra_data(int tile) const;
void rename_param(CellInfo *cell, IdString name, IdString new_name, int width);
std::set<IdString> available_pads; std::set<IdString> available_pads;
std::map<BelId, const PadInfoPOD *> bel_to_pad; std::map<BelId, const PadInfoPOD *> bel_to_pad;
@ -83,6 +82,7 @@ struct GateMateImpl : HimbaechelAPI
void assign_cell_info(); void assign_cell_info();
void route_clock(); void route_clock();
void repack();
const GateMateBelExtraDataPOD *bel_extra_data(BelId bel) const; const GateMateBelExtraDataPOD *bel_extra_data(BelId bel) const;

View File

@ -26,12 +26,14 @@
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
void GateMatePacker::flush_cells() void GateMatePacker::flush_cells(bool unbind)
{ {
for (auto pcell : packed_cells) { for (auto pcell : packed_cells) {
for (auto &port : ctx->cells[pcell]->ports) { for (auto &port : ctx->cells[pcell]->ports) {
ctx->cells[pcell]->disconnectPort(port.first); ctx->cells[pcell]->disconnectPort(port.first);
} }
if (unbind)
ctx->unbindBel(ctx->cells[pcell]->bel);
ctx->cells.erase(pcell); ctx->cells.erase(pcell);
} }
packed_cells.clear(); packed_cells.clear();
@ -347,6 +349,98 @@ void GateMatePacker::cleanup()
} while (count != 0); } while (count != 0);
} }
void GateMatePacker::rename_param(CellInfo *cell, IdString name, IdString new_name, int width)
{
if (cell->params.count(name)) {
cell->params[new_name] = Property(int_or_default(cell->params, name, 0), width);
cell->unsetParam(name);
}
}
void GateMatePacker::repack()
{
for (auto &cell : ctx->cells) {
if (cell.second->type.in(id_CPE_L2T4)) {
Loc l = ctx->getBelLocation(cell.second->bel);
if (l.z == CPE_LT_L_Z) {
if (!cell.second->params.count(id_INIT_L20))
cell.second->params[id_INIT_L20] = Property(LUT_D1, 4);
}
cell.second->params[id_L2T4_UPPER] = Property((l.z == CPE_LT_U_Z) ? 1 : 0, 1);
} else if (cell.second->type.in(id_CPE_LT_L)) {
BelId bel = cell.second->bel;
PlaceStrength strength = cell.second->belStrength;
uint8_t func = int_or_default(cell.second->params, id_C_FUNCTION, 0);
Loc loc = ctx->getBelLocation(bel);
loc.z = CPE_LT_FULL_Z;
ctx->unbindBel(bel);
ctx->bindBel(ctx->getBelByLocation(loc), cell.second.get(), strength);
cell.second->renamePort(id_IN1, id_IN5);
cell.second->renamePort(id_IN2, id_IN6);
cell.second->renamePort(id_IN3, id_IN7);
cell.second->renamePort(id_IN4, id_IN8);
cell.second->renamePort(id_OUT, id_OUT1);
cell.second->renamePort(id_CPOUT, id_CPOUT1);
if (!cell.second->params.count(id_INIT_L20))
cell.second->params[id_INIT_L20] = Property(LUT_D1, 4);
rename_param(cell.second.get(), id_INIT_L00, id_INIT_L02, 4);
rename_param(cell.second.get(), id_INIT_L01, id_INIT_L03, 4);
rename_param(cell.second.get(), id_INIT_L10, id_INIT_L11, 4);
switch (func) {
case C_ADDF:
cell.second->type = id_CPE_ADDF;
break;
case C_ADDF2:
cell.second->type = id_CPE_ADDF2;
break;
case C_MULT:
cell.second->type = id_CPE_MULT;
break;
case C_MX4:
cell.second->type = id_CPE_MX4;
break;
case C_EN_CIN:
log_error("EN_CIN should be using L2T4.\n");
break;
case C_CONCAT:
cell.second->type = id_CPE_CONCAT;
break;
case C_ADDCIN:
log_error("ADDCIN should be using L2T4.\n");
break;
default:
break;
}
loc.z = CPE_LT_U_Z;
CellInfo *upper = ctx->getBoundBelCell(ctx->getBelByLocation(loc));
if (upper->params.count(id_INIT_L00))
cell.second->params[id_INIT_L00] = Property(int_or_default(upper->params, id_INIT_L00, 0), 4);
if (upper->params.count(id_INIT_L01))
cell.second->params[id_INIT_L01] = Property(int_or_default(upper->params, id_INIT_L01, 0), 4);
if (upper->params.count(id_INIT_L10))
cell.second->params[id_INIT_L10] = Property(int_or_default(upper->params, id_INIT_L10, 0), 4);
if (upper->params.count(id_C_I1))
cell.second->params[id_C_I1] = Property(int_or_default(upper->params, id_C_I1, 0), 1);
if (upper->params.count(id_C_I2))
cell.second->params[id_C_I2] = Property(int_or_default(upper->params, id_C_I2, 0), 1);
upper->movePortTo(id_IN1, cell.second.get(), id_IN1);
upper->movePortTo(id_IN2, cell.second.get(), id_IN2);
upper->movePortTo(id_IN3, cell.second.get(), id_IN3);
upper->movePortTo(id_IN4, cell.second.get(), id_IN4);
upper->movePortTo(id_OUT, cell.second.get(), id_OUT2);
upper->movePortTo(id_CPOUT, cell.second.get(), id_CPOUT2);
}
// Mark for deletion
else if (cell.second->type.in(id_CPE_LT_U, id_CPE_DUMMY)) {
packed_cells.insert(cell.second->name);
}
}
flush_cells(true);
}
void GateMateImpl::pack() void GateMateImpl::pack()
{ {
const ArchArgs &args = ctx->args; const ArchArgs &args = ctx->args;
@ -373,4 +467,10 @@ void GateMateImpl::pack()
packer.remove_clocking(); packer.remove_clocking();
} }
void GateMateImpl::repack()
{
GateMatePacker packer(ctx, this);
packer.repack();
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -67,8 +67,10 @@ struct GateMatePacker
void remove_not_used(); void remove_not_used();
void cleanup(); void cleanup();
void repack();
private: private:
void rename_param(CellInfo *cell, IdString name, IdString new_name, int width);
void dff_to_cpe(CellInfo *dff); void dff_to_cpe(CellInfo *dff);
void insert_bufg(CellInfo *cell, IdString port); void insert_bufg(CellInfo *cell, IdString port);
void disconnect_if_gnd(CellInfo *cell, IdString input); void disconnect_if_gnd(CellInfo *cell, IdString input);
@ -93,7 +95,7 @@ struct GateMatePacker
bool is_gpio_valid_dff(CellInfo *dff); bool is_gpio_valid_dff(CellInfo *dff);
// Cell creating // Cell creating
CellInfo *create_cell_ptr(IdString type, IdString name); CellInfo *create_cell_ptr(IdString type, IdString name);
void flush_cells(); void flush_cells(bool unbind = false);
void pack_ram_cell(CellInfo &ci, CellInfo *cell, int num, bool is_split); void pack_ram_cell(CellInfo &ci, CellInfo *cell, int num, bool is_split);
void copy_constraint(NetInfo *in_net, NetInfo *out_net); void copy_constraint(NetInfo *in_net, NetInfo *out_net);

View File

@ -157,9 +157,9 @@ void GateMatePacker::pack_cpe()
ci.renamePort(id_I3, id_IN4); ci.renamePort(id_I3, id_IN4);
ci.renamePort(id_O, id_OUT); ci.renamePort(id_O, id_OUT);
uarch->rename_param(&ci, id_INIT_L02, id_INIT_L00, 4); rename_param(&ci, id_INIT_L02, id_INIT_L00, 4);
uarch->rename_param(&ci, id_INIT_L03, id_INIT_L01, 4); rename_param(&ci, id_INIT_L03, id_INIT_L01, 4);
uarch->rename_param(&ci, id_INIT_L11, id_INIT_L10, 4); rename_param(&ci, id_INIT_L11, id_INIT_L10, 4);
ci.cluster = ci.name; ci.cluster = ci.name;
ci.constr_abs_z = true; ci.constr_abs_z = true;
ci.constr_z = CPE_LT_L_Z; ci.constr_z = CPE_LT_L_Z;