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; });
struct GckConfig {
explicit GckConfig(BelId belid) { bel = belid; si1 = IdString(); si2 = IdString(); used = false; }
BelId bel;
IdString si1;
IdString si2;
bool used;
};
enum TILETypeZ
{
BEL_LUT_Z = 0,

View File

@ -52,6 +52,8 @@ void NgUltraImpl::init_database(Arch *arch)
void NgUltraImpl::init(Context *ctx)
{
HimbaechelAPI::init(ctx);
for (int i=1;i<=8;i++)
gck_per_lobe[i].reserve(20);
for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) == id_IOM) {
std::set<IdString> ckg;
@ -81,8 +83,10 @@ void NgUltraImpl::init(Context *ctx)
global_capable_bels.emplace(bel,id_P19RI);
}
} else if (ctx->getBelType(bel) == id_GCK) {
int lobe = ctx->getBelName(bel)[1].c_str(ctx)[1] - '0';
gck_per_lobe[lobe].emplace(bel);
std::string name = ctx->getBelName(bel)[1].c_str(ctx);
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);
}

View File

@ -71,7 +71,7 @@ public:
dict<std::string, std::string> bank_voltage;
dict<BelId,IdString> global_capable_bels;
dict<std::string,BelId> locations;
dict<int,pool<BelId>> gck_per_lobe;
dict<int,std::vector<GckConfig>> gck_per_lobe;
pool<PipId> blocked_pips;
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);
if (!c_net)
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))
log_error("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_error("I port of IO primitive %s must be connected.\n", cell->name.c_str(ctx));
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_GND") && !cell->getPort(id_O)) {
log_warning("O port of IO primitive %s must be connected. Removing cell.\n", cell->name.c_str(ctx));
packed_cells.emplace(cell->name);
continue;
}
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);
@ -633,6 +642,7 @@ void NgUltraPacker::pack_iobs(void)
}
if (bfr_added)
log_info(" %6d DFRs/DDFRs used as BFR\n", bfr_added);
flush_cells();
}
void NgUltraPacker::pack_ioms(void)
@ -2035,6 +2045,27 @@ void NgUltraImpl::postPlace()
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()
{
// Unbind all GCKs that are inserted
@ -2115,11 +2146,7 @@ void NgUltraPacker::duplicate_gck()
NetInfo *si2 = driver->getPort(id_SI2);
NetInfo *cmd = driver->getPort(id_CMD);
for (auto &conn : connections) {
pool<BelId>& gck = uarch->gck_per_lobe[conn.first];
if (gck.size()==0)
log_error("No GCK left to promote global signal.\n");
BelId bel = gck.pop();
BelId bel = get_available_gck(conn.first, si1, si2);
CellInfo *gck_cell = nullptr;
if (cnt==0) {
gck_cell = driver;
@ -2218,11 +2245,7 @@ void NgUltraPacker::insert_bypass_gck()
}
}
for (auto &conn : connections) {
pool<BelId>& gck = uarch->gck_per_lobe[conn.first];
if (gck.size()==0)
log_error("No GCK left to promote global signal.\n");
BelId bel = gck.pop();
BelId bel = get_available_gck(conn.first, glb_net, nullptr);
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)));

View File

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