Implement GCK limitations

This commit is contained in:
Miodrag Milanovic 2024-06-27 10:40:13 +02:00
parent e1837b781b
commit 9baf87e2a6
5 changed files with 56 additions and 20 deletions

View File

@ -20,7 +20,15 @@ NPNR_PACKED_STRUCT(struct NGUltraPipExtraDataPOD {
}); });
NPNR_PACKED_STRUCT(struct NGUltraBelExtraDataPOD { int32_t flags; }); NPNR_PACKED_STRUCT(struct NGUltraBelExtraDataPOD { int32_t flags; });
struct GckConfig {
explicit GckConfig(BelId belid) { bel = belid; si1 = IdString(); si2 = IdString(); used = false; }
BelId bel;
IdString si1;
IdString si2;
bool used;
};
enum TILETypeZ enum TILETypeZ
{ {
BEL_LUT_Z = 0, BEL_LUT_Z = 0,

View File

@ -52,6 +52,8 @@ void NgUltraImpl::init_database(Arch *arch)
void NgUltraImpl::init(Context *ctx) void NgUltraImpl::init(Context *ctx)
{ {
HimbaechelAPI::init(ctx); HimbaechelAPI::init(ctx);
for (int i=1;i<=8;i++)
gck_per_lobe[i].reserve(20);
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) == id_IOM) { if (ctx->getBelType(bel) == id_IOM) {
std::set<IdString> ckg; std::set<IdString> ckg;
@ -81,8 +83,10 @@ void NgUltraImpl::init(Context *ctx)
global_capable_bels.emplace(bel,id_P19RI); global_capable_bels.emplace(bel,id_P19RI);
} }
} else if (ctx->getBelType(bel) == id_GCK) { } else if (ctx->getBelType(bel) == id_GCK) {
int lobe = ctx->getBelName(bel)[1].c_str(ctx)[1] - '0'; std::string name = ctx->getBelName(bel)[1].c_str(ctx);
gck_per_lobe[lobe].emplace(bel); int lobe = name[1] - '0';
int num = atoi(name.substr(4,2).c_str());
gck_per_lobe[lobe].insert(gck_per_lobe[lobe].begin()+num-1, GckConfig(bel));
} }
locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel); locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel);
} }

View File

@ -71,7 +71,7 @@ public:
dict<std::string, std::string> bank_voltage; dict<std::string, std::string> bank_voltage;
dict<BelId,IdString> global_capable_bels; dict<BelId,IdString> global_capable_bels;
dict<std::string,BelId> locations; dict<std::string,BelId> locations;
dict<int,pool<BelId>> gck_per_lobe; dict<int,std::vector<GckConfig>> gck_per_lobe;
pool<PipId> blocked_pips; pool<PipId> blocked_pips;
dict<IdString, std::pair<IdString,IdString>> bank_to_ckg; dict<IdString, std::pair<IdString,IdString>> bank_to_ckg;

View File

@ -527,12 +527,21 @@ void NgUltraPacker::pack_iobs(void)
NetInfo *c_net = cell->getPort(id_C); NetInfo *c_net = cell->getPort(id_C);
if (!c_net) if (!c_net)
log_error("C input of IO primitive %s must be connected.\n", cell->name.c_str(ctx)); log_error("C input of IO primitive %s must be connected.\n", cell->name.c_str(ctx));
if (c_net->name == ctx->id("$PACKER_GND") && !cell->getPort(id_O)) if (c_net->name == ctx->id("$PACKER_GND") && !cell->getPort(id_O)) {
log_error("O port of IO primitive %s must be connected.\n", cell->name.c_str(ctx)); log_warning("O port of IO primitive %s must be connected. Removing cell.\n", cell->name.c_str(ctx));
if (c_net->name == ctx->id("$PACKER_VCC") && !cell->getPort(id_I)) packed_cells.emplace(cell->name);
log_error("I port of IO primitive %s must be connected.\n", cell->name.c_str(ctx)); continue;
if (!cell->getPort(id_I) && !cell->getPort(id_O)) }
log_error("I or O port of IO primitive %s must be connected.\n", cell->name.c_str(ctx)); if (c_net->name == ctx->id("$PACKER_VCC") && !cell->getPort(id_I)) {
log_warning("I port of IO primitive %s must be connected. Removing cell.\n", cell->name.c_str(ctx));
packed_cells.emplace(cell->name);
continue;
}
if (!cell->getPort(id_I) && !cell->getPort(id_O)) {
log_warning("I or O port of IO primitive %s must be connected. Removing cell.\n", cell->name.c_str(ctx));
packed_cells.emplace(cell->name);
continue;
}
{ {
CellInfo *iod = net_driven_by(ctx, c_net, is_dfr, id_O); CellInfo *iod = net_driven_by(ctx, c_net, is_dfr, id_O);
@ -633,6 +642,7 @@ void NgUltraPacker::pack_iobs(void)
} }
if (bfr_added) if (bfr_added)
log_info(" %6d DFRs/DDFRs used as BFR\n", bfr_added); log_info(" %6d DFRs/DDFRs used as BFR\n", bfr_added);
flush_cells();
} }
void NgUltraPacker::pack_ioms(void) void NgUltraPacker::pack_ioms(void)
@ -2035,6 +2045,27 @@ void NgUltraImpl::postPlace()
ctx->assignArchInfo(); ctx->assignArchInfo();
} }
BelId NgUltraPacker::get_available_gck(int lobe, NetInfo *si1, NetInfo *si2)
{
auto &gcks = uarch->gck_per_lobe[lobe];
for(int i=0;i<20;i++) {
auto &g = gcks.at(i);
if (g.used) continue;
if (si1 && g.si1!=IdString() && g.si1!=si1->name) continue;
if (si2 && g.si2!=IdString() && g.si2!=si2->name) continue;
if (si1) g.si1 = si1->name;
if (si2) g.si2 = si2->name;
g.used = true;
if (i%2==0) {
// next GCK share inputs in reverse order
if (si2) gcks.at(i+1).si1 = si2->name;
if (si1) gcks.at(i+1).si2 = si1->name;
}
return g.bel;
}
log_error("No GCK left to promote global signal.\n");
return BelId();
}
void NgUltraPacker::duplicate_gck() void NgUltraPacker::duplicate_gck()
{ {
// Unbind all GCKs that are inserted // Unbind all GCKs that are inserted
@ -2115,11 +2146,7 @@ void NgUltraPacker::duplicate_gck()
NetInfo *si2 = driver->getPort(id_SI2); NetInfo *si2 = driver->getPort(id_SI2);
NetInfo *cmd = driver->getPort(id_CMD); NetInfo *cmd = driver->getPort(id_CMD);
for (auto &conn : connections) { for (auto &conn : connections) {
pool<BelId>& gck = uarch->gck_per_lobe[conn.first]; BelId bel = get_available_gck(conn.first, si1, si2);
if (gck.size()==0)
log_error("No GCK left to promote global signal.\n");
BelId bel = gck.pop();
CellInfo *gck_cell = nullptr; CellInfo *gck_cell = nullptr;
if (cnt==0) { if (cnt==0) {
gck_cell = driver; gck_cell = driver;
@ -2218,11 +2245,7 @@ void NgUltraPacker::insert_bypass_gck()
} }
} }
for (auto &conn : connections) { for (auto &conn : connections) {
pool<BelId>& gck = uarch->gck_per_lobe[conn.first]; BelId bel = get_available_gck(conn.first, glb_net, nullptr);
if (gck.size()==0)
log_error("No GCK left to promote global signal.\n");
BelId bel = gck.pop();
log_info(" Create GCK for lobe %d\n",conn.first); log_info(" Create GCK for lobe %d\n",conn.first);
CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->id(glb_net->name.str(ctx) + "$gck_"+ std::to_string(conn.first))); CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->id(glb_net->name.str(ctx) + "$gck_"+ std::to_string(conn.first)));

View File

@ -93,6 +93,7 @@ private:
void mandatory_param(CellInfo *cell, IdString param); void mandatory_param(CellInfo *cell, IdString param);
void disconnect_unused(CellInfo *cell, IdString port); void disconnect_unused(CellInfo *cell, IdString port);
void bind_attr_loc(CellInfo *cell, dict<IdString, Property> *attrs); void bind_attr_loc(CellInfo *cell, dict<IdString, Property> *attrs);
BelId get_available_gck(int lobe, NetInfo *si1, NetInfo *si2);
// General helper functions // General helper functions
void flush_cells(); void flush_cells();