Add IOM insertion

This commit is contained in:
Miodrag Milanovic 2024-05-09 18:41:21 +02:00
parent f8680e413d
commit 3dedb11434
5 changed files with 91 additions and 0 deletions

View File

@ -84,6 +84,11 @@ CellInfo *NgUltraPacker::create_cell_ptr(IdString type, IdString name)
add_port("I2", PORT_IN);
add_port("O2", PORT_OUT);
add_port("CKF", PORT_IN);
} else if (type == id_IOM) {
add_port("P17RI", PORT_IN);
add_port("CKO1", PORT_OUT);
add_port("P19RI", PORT_IN);
add_port("CKO2", PORT_OUT);
}
return cell;
}

View File

@ -57,6 +57,12 @@ void NgUltraImpl::init(Context *ctx)
std::deque<BelId> wfgs;
IdString bank = tile_name_id(bel.tile);
iom_bels.emplace(bank,bel);
} else if (ctx->getBelType(bel) == id_IOTP) {
if (ctx->getBelName(bel)[1] == ctx->id("D08P_CLK.IOTP")) {
global_capable_bels.emplace(bel,id_P17RI);
} else if (ctx->getBelName(bel)[1] == ctx->id("D09P_CLK.IOTP")) {
global_capable_bels.emplace(bel,id_P19RI);
}
}
}
}

View File

@ -65,6 +65,7 @@ public:
dict<IdString,BelId> iom_bels;
dict<std::string, std::string> bank_voltage;
dict<BelId,IdString> global_capable_bels;
private:
void write_bitstream_json(const std::string &filename);

View File

@ -697,6 +697,82 @@ void NgUltraPacker::pack_cys(void)
flush_cells();
}
// There are 20 dedicated clock inputs capable of being routed using global network
// to be able to best route them, IOM needs to be used to propagate these clock signals
void NgUltraPacker::promote_globals()
{
std::vector<std::pair<int, IdString>> glb_fanout;
int available_globals = 20;
for (auto &net : ctx->nets) {
NetInfo *ni = net.second.get();
// Skip undriven nets; and nets that are already global
if (ni->driver.cell == nullptr)
continue;
if (ni->name.in(ctx->id("$PACKER_GND_NET"), ctx->id("$PACKER_VCC_NET")))
continue;
if (ni->driver.cell->type == id_IOM) {
continue;
}
if (ni->driver.cell->type == id_GCK) {
--available_globals;
continue;
}
if (!ni->driver.cell->type.in(id_DDFR)) {
continue;
}
Loc iotp_loc = ni->driver.cell->getLocation();
iotp_loc.z -= 1;
BelId bel = ctx->getBelByLocation(iotp_loc);
if (uarch->global_capable_bels.count(bel)==0)
continue;
// Count the number of clock ports
int glb_count = 0;
for (const auto &usr : ni->users) {
if (usr.cell->type == id_BEYOND_FE && usr.port == id_CK)
glb_count++;
}
if (glb_count > 0)
glb_fanout.emplace_back(glb_count, ni->name);
}
if (available_globals <= 0)
return;
// Sort clocks by max fanout
std::sort(glb_fanout.begin(), glb_fanout.end(), std::greater<std::pair<int, IdString>>());
log_info("Promoting globals...\n");
// Promote the N highest fanout clocks
for (size_t i = 0; i < std::min<size_t>(glb_fanout.size(), available_globals); i++) {
NetInfo *net = ctx->nets.at(glb_fanout.at(i).second).get();
log_info(" promoting clock net '%s'\n", ctx->nameOf(net));
Loc iotp_loc = net->driver.cell->getLocation();
iotp_loc.z -= 1;
BelId iotp_bel = ctx->getBelByLocation(iotp_loc);
IdString iob = uarch->tile_name_id(iotp_bel.tile);
BelId bel = uarch->iom_bels[iob];
CellInfo *iom = nullptr;
IdString port = uarch->global_capable_bels.at(iotp_bel);
if (!ctx->checkBelAvail(bel)) {
iom = ctx->getBoundBelCell(bel);
} else {
iom = create_cell_ptr(id_IOM, ctx->id(std::string(iob.c_str(ctx)) + "$iom"));
}
if (iom->getPort(port)) {
log_error("Port '%s' of IOM cell '%s' is already used.\n", port.c_str(ctx), iom->name.c_str(ctx));
}
CellInfo *input_pad = ctx->getBoundBelCell(iotp_bel);
NetInfo *iom_to_clk = ctx->createNet(ctx->id(std::string(net->name.c_str(ctx)) + "$iom"));
for (const auto &usr : net->users) {
if (usr.cell->type == id_BEYOND_FE && usr.port == id_CK) {
usr.cell->disconnectPort(id_CK);
usr.cell->connectPort(id_CK, iom_to_clk);
}
}
iom->connectPort(port, input_pad->getPort(id_O));
iom->connectPort((port==id_P17RI) ? id_CKO1 : id_CKO2, iom_to_clk);
ctx->bindBel(bel, iom, PlaceStrength::STRENGTH_LOCKED);
}
}
void NgUltraImpl::pack()
{
const ArchArgs &args = ctx->args;
@ -713,6 +789,7 @@ void NgUltraImpl::pack()
packer.pack_lut_dffs();
packer.pack_dffs();
packer.remove_constants();
packer.promote_globals();
}
void NgUltraImpl::route_clocks()

View File

@ -53,6 +53,8 @@ struct NgUltraPacker
void pack_iobs();
void pack_ioms();
void promote_globals();
private:
void set_lut_input_if_constant(CellInfo *cell, IdString input);
void lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table);