nexus: Promote CE/LSR globals
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
01b51fb715
commit
68e4d18339
@ -178,6 +178,7 @@ Arch::Arch(ArchArgs args) : args(args)
|
||||
// some tweaks to accomodate properly
|
||||
if (getBelType(bel) != id_DCC)
|
||||
continue;
|
||||
disabled_bels.insert(bel);
|
||||
WireId w = getBelPinWire(bel, id_CLKI);
|
||||
for (auto pip : getPipsUphill(w))
|
||||
disabled_pips.insert(pip);
|
||||
|
@ -786,8 +786,9 @@ enum CellPinStyle
|
||||
PINDEF_MASK = 0x30,
|
||||
|
||||
PINGLB_CLK = 0x100, // pin is a 'clock' for global purposes
|
||||
PINGLB_CE_LSR = 0x200, // pin is CE/LSR for global purposes
|
||||
|
||||
PINGLB_MASK = 0x100,
|
||||
PINGLB_MASK = 0x300,
|
||||
|
||||
PINBIT_GATED = 0x1000, // pin must be enabled in bitstream if used
|
||||
PINBIT_1 = 0x2000, // pin has an explicit bit that must be set if tied to 1
|
||||
@ -796,8 +797,8 @@ enum CellPinStyle
|
||||
PINSTYLE_NONE = 0x0000, // default
|
||||
PINSTYLE_CIB = 0x4012, // 'CIB' signal, floats high but explicitly zeroed if not used
|
||||
PINSTYLE_CLK = 0x0107, // CLK type signal, invertible and defaults to disconnected
|
||||
PINSTYLE_CE = 0x0027, // CE type signal, invertible and defaults to enabled
|
||||
PINSTYLE_LSR = 0x0017, // LSR type signal, invertible and defaults to not reset
|
||||
PINSTYLE_CE = 0x0227, // CE type signal, invertible and defaults to enabled
|
||||
PINSTYLE_LSR = 0x0217, // LSR type signal, invertible and defaults to not reset
|
||||
PINSTYLE_DEDI = 0x0000, // dedicated signals, leave alone
|
||||
PINSTYLE_PU = 0x4022, // signals that float high and default high
|
||||
PINSTYLE_PU_NONCIB = 0x0022, // signals that float high and default high
|
||||
@ -920,6 +921,7 @@ struct Arch : BaseArch<ArchRanges>
|
||||
dict<IdString, int> id_to_x, id_to_y;
|
||||
|
||||
pool<PipId> disabled_pips;
|
||||
pool<BelId> disabled_bels;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
|
@ -105,6 +105,10 @@ bool Arch::isBelLocationValid(BelId bel) const
|
||||
else
|
||||
return nexus_logic_tile_valid(*lts);
|
||||
} else {
|
||||
if (getBelType(bel) == id_DCC) {
|
||||
if (getBoundBelCell(bel) != nullptr && disabled_bels.count(bel))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,10 @@ struct NexusGlobalRouter
|
||||
while (!visit.empty() && (iter++ < iter_limit)) {
|
||||
WireId cursor = visit.front();
|
||||
visit.pop();
|
||||
if (ctx->getBoundWireNet(cursor) == net) {
|
||||
src = cursor;
|
||||
break;
|
||||
}
|
||||
// Search uphill pips
|
||||
for (PipId pip : ctx->getPipsUphill(cursor)) {
|
||||
// Skip pip if unavailable, and not because it's already used for this net
|
||||
|
@ -852,7 +852,9 @@ struct NexusPacker
|
||||
void promote_globals()
|
||||
{
|
||||
std::vector<std::pair<int, IdString>> clk_fanout;
|
||||
int available_globals = 16;
|
||||
std::vector<std::pair<int, IdString>> ce_lsr_fanout;
|
||||
// TODO: if we are more cunning about placement, the real limits are 16 per device half and 8 per row segment
|
||||
int available_globals = 8;
|
||||
for (auto &net : ctx->nets) {
|
||||
NetInfo *ni = net.second.get();
|
||||
// Skip undriven nets; and nets that are already global
|
||||
@ -863,19 +865,25 @@ struct NexusPacker
|
||||
continue;
|
||||
}
|
||||
// Count the number of clock ports
|
||||
int clk_count = 0;
|
||||
int clk_count = 0, ce_lsr_count = 0;
|
||||
for (const auto &usr : ni->users) {
|
||||
auto port_style = ctx->get_cell_pin_style(usr.cell, usr.port);
|
||||
if (port_style & PINGLB_CLK)
|
||||
++clk_count;
|
||||
if (port_style & PINGLB_CE_LSR)
|
||||
++ce_lsr_count;
|
||||
}
|
||||
if (clk_count > 0)
|
||||
clk_fanout.emplace_back(clk_count, ni->name);
|
||||
if (ce_lsr_count > 150)
|
||||
ce_lsr_fanout.emplace_back(ce_lsr_count, ni->name);
|
||||
}
|
||||
if (available_globals <= 0)
|
||||
return;
|
||||
// Sort clocks by max fanout
|
||||
std::sort(clk_fanout.begin(), clk_fanout.end(), std::greater<std::pair<int, IdString>>());
|
||||
std::sort(ce_lsr_fanout.begin(), ce_lsr_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>(clk_fanout.size(), available_globals); i++) {
|
||||
@ -883,6 +891,15 @@ struct NexusPacker
|
||||
log_info(" promoting clock net '%s'\n", ctx->nameOf(net));
|
||||
insert_buffer(net, id_DCC, "glb_clk", id_CLKI, id_CLKO, [](const PortRef &port) { return true; });
|
||||
}
|
||||
// Limit to 1 LSR/CE to avoid routeability issues
|
||||
int available_ce_lsr_globals = std::min<int>(available_globals, 1);
|
||||
for (size_t i = 0; i < std::min<size_t>(ce_lsr_fanout.size(), available_ce_lsr_globals); i++) {
|
||||
NetInfo *net = ctx->nets.at(ce_lsr_fanout.at(i).second).get();
|
||||
log_info(" promoting CE/LSR net '%s'\n", ctx->nameOf(net));
|
||||
insert_buffer(net, id_DCC, "glb_ce_lsr", id_CLKI, id_CLKO, [this](const PortRef &port) {
|
||||
return ctx->get_cell_pin_style(port.cell, port.port) & PINGLB_CE_LSR;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Place certain global cells
|
||||
|
Loading…
Reference in New Issue
Block a user