Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nexus: Promote CE/LSR globals #696

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nexus/arch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions nexus/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,10 @@ enum CellPinStyle

PINDEF_MASK = 0x30,

PINGLB_CLK = 0x100, // pin is a 'clock' for global purposes
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
Expand All @@ -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
Expand Down Expand Up @@ -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;

// -------------------------------------------------

Expand Down
4 changes: 4 additions & 0 deletions nexus/arch_place.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
4 changes: 4 additions & 0 deletions nexus/global.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 19 additions & 2 deletions nexus/pack.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -863,26 +865,41 @@ 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++) {
NetInfo *net = ctx->nets.at(clk_fanout.at(i).second).get();
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
Expand Down