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);
}
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::postPlace()
void GateMateImpl::postPlace() { repack(); }
void GateMateImpl::preRoute()
{
ctx->assignArchInfo();
std::vector<IdString> delete_cells;
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();
route_clock();
}
void GateMateImpl::preRoute() { route_clock(); }
void GateMateImpl::postRoute()
{
ctx->assignArchInfo();

View File

@ -63,7 +63,6 @@ struct GateMateImpl : HimbaechelAPI
bool isPipInverting(PipId pip) const override;
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::map<BelId, const PadInfoPOD *> bel_to_pad;
@ -83,6 +82,7 @@ struct GateMateImpl : HimbaechelAPI
void assign_cell_info();
void route_clock();
void repack();
const GateMateBelExtraDataPOD *bel_extra_data(BelId bel) const;

View File

@ -26,12 +26,14 @@
NEXTPNR_NAMESPACE_BEGIN
void GateMatePacker::flush_cells()
void GateMatePacker::flush_cells(bool unbind)
{
for (auto pcell : packed_cells) {
for (auto &port : ctx->cells[pcell]->ports) {
ctx->cells[pcell]->disconnectPort(port.first);
}
if (unbind)
ctx->unbindBel(ctx->cells[pcell]->bel);
ctx->cells.erase(pcell);
}
packed_cells.clear();
@ -347,6 +349,98 @@ void GateMatePacker::cleanup()
} 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()
{
const ArchArgs &args = ctx->args;
@ -373,4 +467,10 @@ void GateMateImpl::pack()
packer.remove_clocking();
}
void GateMateImpl::repack()
{
GateMatePacker packer(ctx, this);
packer.repack();
}
NEXTPNR_NAMESPACE_END

View File

@ -67,8 +67,10 @@ struct GateMatePacker
void remove_not_used();
void cleanup();
void repack();
private:
void rename_param(CellInfo *cell, IdString name, IdString new_name, int width);
void dff_to_cpe(CellInfo *dff);
void insert_bufg(CellInfo *cell, IdString port);
void disconnect_if_gnd(CellInfo *cell, IdString input);
@ -93,7 +95,7 @@ struct GateMatePacker
bool is_gpio_valid_dff(CellInfo *dff);
// Cell creating
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 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_O, id_OUT);
uarch->rename_param(&ci, id_INIT_L02, id_INIT_L00, 4);
uarch->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_L02, id_INIT_L00, 4);
rename_param(&ci, id_INIT_L03, id_INIT_L01, 4);
rename_param(&ci, id_INIT_L11, id_INIT_L10, 4);
ci.cluster = ci.name;
ci.constr_abs_z = true;
ci.constr_z = CPE_LT_L_Z;