aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-06-17 08:53:54 +0100
committerGitHub <noreply@github.com>2021-06-17 08:53:54 +0100
commit167867ff7ce41a05f55ea4aae4370ef760b9ae0a (patch)
treed786085506cf724a9e8d1bc5d8ba74f39f756f3f
parentded32f33906e2547eec68d91715c0759290c6a1f (diff)
parent3d528adfdcf39b0a7fa2b319ce10f32343e4b795 (diff)
downloadnextpnr-167867ff7ce41a05f55ea4aae4370ef760b9ae0a.tar.gz
nextpnr-167867ff7ce41a05f55ea4aae4370ef760b9ae0a.tar.bz2
nextpnr-167867ff7ce41a05f55ea4aae4370ef760b9ae0a.zip
Merge pull request #730 from YosysHQ/gatecat/dcc-routehtru
nexus: Fix some 17k reliability issues
-rw-r--r--nexus/arch.cc13
-rw-r--r--nexus/arch.h16
-rw-r--r--nexus/fasm.cc36
3 files changed, 62 insertions, 3 deletions
diff --git a/nexus/arch.cc b/nexus/arch.cc
index d309c902..f3430968 100644
--- a/nexus/arch.cc
+++ b/nexus/arch.cc
@@ -171,6 +171,19 @@ Arch::Arch(ArchArgs args) : args(args)
BaseArch::init_cell_types();
BaseArch::init_bel_buckets();
+
+ if (device == "LIFCL-17") {
+ for (BelId bel : getBelsByTile(37, 10)) {
+ // These pips currently don't work, due to routing differences between the variants that the DB format needs
+ // some tweaks to accomodate properly
+ if (getBelType(bel) != id_DCC)
+ continue;
+ WireId w = getBelPinWire(bel, id_CLKI);
+ for (auto pip : getPipsUphill(w))
+ disabled_pips.insert(pip);
+ }
+ NPNR_ASSERT(disabled_pips.size() == 4);
+ }
}
// -----------------------------------------------------------------------
diff --git a/nexus/arch.h b/nexus/arch.h
index 51322f3e..8c330e47 100644
--- a/nexus/arch.h
+++ b/nexus/arch.h
@@ -918,6 +918,8 @@ struct Arch : BaseArch<ArchRanges>
// inverse of the above for name->object mapping
dict<IdString, int> id_to_x, id_to_y;
+ pool<PipId> disabled_pips;
+
// -------------------------------------------------
std::string getChipName() const override;
@@ -976,6 +978,20 @@ struct Arch : BaseArch<ArchRanges>
return tileStatus[bel.tile].boundcells[bel.index] == nullptr;
}
+ bool checkPipAvail(PipId pip) const override
+ {
+ if (disabled_pips.count(pip))
+ return false;
+ return BaseArch::checkPipAvail(pip);
+ }
+
+ bool checkPipAvailForNet(PipId pip, NetInfo *net) const override
+ {
+ if (disabled_pips.count(pip))
+ return false;
+ return BaseArch::checkPipAvailForNet(pip, net);
+ }
+
CellInfo *getBoundBelCell(BelId bel) const override
{
NPNR_ASSERT(bel != BelId());
diff --git a/nexus/fasm.cc b/nexus/fasm.cc
index db37458e..6715af47 100644
--- a/nexus/fasm.cc
+++ b/nexus/fasm.cc
@@ -227,9 +227,8 @@ struct NexusFasmWriter
blank();
}
// Find the CIBMUX output for a signal
- WireId find_cibmux(const CellInfo *cell, IdString pin)
+ WireId find_cibmux(WireId cursor)
{
- WireId cursor = ctx->getBelPinWire(cell->bel, pin);
if (cursor == WireId())
return WireId();
for (int i = 0; i < 10; i++) {
@@ -270,7 +269,7 @@ struct NexusFasmWriter
// Handle CIB muxes - these must be set such that floating pins really are floating to VCC and not connected
// to another CIB signal
if ((pin_style & PINBIT_CIBMUX) && port.second.net == nullptr) {
- WireId cibmuxout = find_cibmux(cell, port.first);
+ WireId cibmuxout = find_cibmux(ctx->getBelPinWire(cell->bel, port.first));
if (cibmuxout != WireId()) {
write_comment(stringf("CIBMUX for unused pin %s", ctx->nameOf(port.first)));
bool found = false;
@@ -287,6 +286,35 @@ struct NexusFasmWriter
}
}
+ // Handle route-through DCCs
+ void write_dcc_thru()
+ {
+ for (auto bel : ctx->getBels()) {
+ if (ctx->getBelType(bel) != id_DCC)
+ continue;
+ if (!ctx->checkBelAvail(bel))
+ continue;
+ WireId dst = ctx->getBelPinWire(bel, id_CLKO);
+ if (ctx->getBoundWireNet(dst) == nullptr)
+ continue;
+ // Set up the CIBMUX so CE is guaranteed to be tied high
+ WireId ce = ctx->getBelPinWire(bel, id_CE);
+ WireId cibmuxout = find_cibmux(ce);
+ NPNR_ASSERT(cibmuxout != WireId());
+
+ write_comment(stringf("CE CIBMUX for DCC route-thru %s", ctx->nameOfBel(bel)));
+ bool found = false;
+ for (PipId pip : ctx->getPipsUphill(cibmuxout)) {
+ if (ctx->checkPipAvail(pip) && ctx->checkWireAvail(ctx->getPipSrcWire(pip))) {
+ write_pip(pip);
+ found = true;
+ break;
+ }
+ }
+ NPNR_ASSERT(found);
+ }
+ }
+
// Write config for an OXIDE_COMB cell
void write_comb(const CellInfo *cell)
{
@@ -846,6 +874,8 @@ struct NexusFasmWriter
write_dphy(ci);
blank();
}
+ // Handle DCC route-throughs
+ write_dcc_thru();
// Write config for unused bels
write_unused();
// Write bank config