Skip to content

Commit 68e4d18

Browse files
committed
nexus: Promote CE/LSR globals
Signed-off-by: gatecat <[email protected]>
1 parent 01b51fb commit 68e4d18

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

nexus/arch.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ Arch::Arch(ArchArgs args) : args(args)
178178
// some tweaks to accomodate properly
179179
if (getBelType(bel) != id_DCC)
180180
continue;
181+
disabled_bels.insert(bel);
181182
WireId w = getBelPinWire(bel, id_CLKI);
182183
for (auto pip : getPipsUphill(w))
183184
disabled_pips.insert(pip);

nexus/arch.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,10 @@ enum CellPinStyle
785785

786786
PINDEF_MASK = 0x30,
787787

788-
PINGLB_CLK = 0x100, // pin is a 'clock' for global purposes
788+
PINGLB_CLK = 0x100, // pin is a 'clock' for global purposes
789+
PINGLB_CE_LSR = 0x200, // pin is CE/LSR for global purposes
789790

790-
PINGLB_MASK = 0x100,
791+
PINGLB_MASK = 0x300,
791792

792793
PINBIT_GATED = 0x1000, // pin must be enabled in bitstream if used
793794
PINBIT_1 = 0x2000, // pin has an explicit bit that must be set if tied to 1
@@ -796,8 +797,8 @@ enum CellPinStyle
796797
PINSTYLE_NONE = 0x0000, // default
797798
PINSTYLE_CIB = 0x4012, // 'CIB' signal, floats high but explicitly zeroed if not used
798799
PINSTYLE_CLK = 0x0107, // CLK type signal, invertible and defaults to disconnected
799-
PINSTYLE_CE = 0x0027, // CE type signal, invertible and defaults to enabled
800-
PINSTYLE_LSR = 0x0017, // LSR type signal, invertible and defaults to not reset
800+
PINSTYLE_CE = 0x0227, // CE type signal, invertible and defaults to enabled
801+
PINSTYLE_LSR = 0x0217, // LSR type signal, invertible and defaults to not reset
801802
PINSTYLE_DEDI = 0x0000, // dedicated signals, leave alone
802803
PINSTYLE_PU = 0x4022, // signals that float high and default high
803804
PINSTYLE_PU_NONCIB = 0x0022, // signals that float high and default high
@@ -920,6 +921,7 @@ struct Arch : BaseArch<ArchRanges>
920921
dict<IdString, int> id_to_x, id_to_y;
921922

922923
pool<PipId> disabled_pips;
924+
pool<BelId> disabled_bels;
923925

924926
// -------------------------------------------------
925927

nexus/arch_place.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ bool Arch::isBelLocationValid(BelId bel) const
105105
else
106106
return nexus_logic_tile_valid(*lts);
107107
} else {
108+
if (getBelType(bel) == id_DCC) {
109+
if (getBoundBelCell(bel) != nullptr && disabled_bels.count(bel))
110+
return false;
111+
}
108112
return true;
109113
}
110114
}

nexus/global.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ struct NexusGlobalRouter
107107
while (!visit.empty() && (iter++ < iter_limit)) {
108108
WireId cursor = visit.front();
109109
visit.pop();
110+
if (ctx->getBoundWireNet(cursor) == net) {
111+
src = cursor;
112+
break;
113+
}
110114
// Search uphill pips
111115
for (PipId pip : ctx->getPipsUphill(cursor)) {
112116
// Skip pip if unavailable, and not because it's already used for this net

nexus/pack.cc

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,9 @@ struct NexusPacker
852852
void promote_globals()
853853
{
854854
std::vector<std::pair<int, IdString>> clk_fanout;
855-
int available_globals = 16;
855+
std::vector<std::pair<int, IdString>> ce_lsr_fanout;
856+
// TODO: if we are more cunning about placement, the real limits are 16 per device half and 8 per row segment
857+
int available_globals = 8;
856858
for (auto &net : ctx->nets) {
857859
NetInfo *ni = net.second.get();
858860
// Skip undriven nets; and nets that are already global
@@ -863,26 +865,41 @@ struct NexusPacker
863865
continue;
864866
}
865867
// Count the number of clock ports
866-
int clk_count = 0;
868+
int clk_count = 0, ce_lsr_count = 0;
867869
for (const auto &usr : ni->users) {
868870
auto port_style = ctx->get_cell_pin_style(usr.cell, usr.port);
869871
if (port_style & PINGLB_CLK)
870872
++clk_count;
873+
if (port_style & PINGLB_CE_LSR)
874+
++ce_lsr_count;
871875
}
872876
if (clk_count > 0)
873877
clk_fanout.emplace_back(clk_count, ni->name);
878+
if (ce_lsr_count > 150)
879+
ce_lsr_fanout.emplace_back(ce_lsr_count, ni->name);
874880
}
875881
if (available_globals <= 0)
876882
return;
877883
// Sort clocks by max fanout
878884
std::sort(clk_fanout.begin(), clk_fanout.end(), std::greater<std::pair<int, IdString>>());
885+
std::sort(ce_lsr_fanout.begin(), ce_lsr_fanout.end(), std::greater<std::pair<int, IdString>>());
886+
879887
log_info("Promoting globals...\n");
880888
// Promote the N highest fanout clocks
881889
for (size_t i = 0; i < std::min<size_t>(clk_fanout.size(), available_globals); i++) {
882890
NetInfo *net = ctx->nets.at(clk_fanout.at(i).second).get();
883891
log_info(" promoting clock net '%s'\n", ctx->nameOf(net));
884892
insert_buffer(net, id_DCC, "glb_clk", id_CLKI, id_CLKO, [](const PortRef &port) { return true; });
885893
}
894+
// Limit to 1 LSR/CE to avoid routeability issues
895+
int available_ce_lsr_globals = std::min<int>(available_globals, 1);
896+
for (size_t i = 0; i < std::min<size_t>(ce_lsr_fanout.size(), available_ce_lsr_globals); i++) {
897+
NetInfo *net = ctx->nets.at(ce_lsr_fanout.at(i).second).get();
898+
log_info(" promoting CE/LSR net '%s'\n", ctx->nameOf(net));
899+
insert_buffer(net, id_DCC, "glb_ce_lsr", id_CLKI, id_CLKO, [this](const PortRef &port) {
900+
return ctx->get_cell_pin_style(port.cell, port.port) & PINGLB_CE_LSR;
901+
});
902+
}
886903
}
887904

888905
// Place certain global cells

0 commit comments

Comments
 (0)