Merge pull request #730 from YosysHQ/gatecat/dcc-routehtru
nexus: Fix some 17k reliability issues
This commit is contained in:
commit
167867ff7c
@ -171,6 +171,19 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
|
|
||||||
BaseArch::init_cell_types();
|
BaseArch::init_cell_types();
|
||||||
BaseArch::init_bel_buckets();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
16
nexus/arch.h
16
nexus/arch.h
@ -918,6 +918,8 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
// inverse of the above for name->object mapping
|
// inverse of the above for name->object mapping
|
||||||
dict<IdString, int> id_to_x, id_to_y;
|
dict<IdString, int> id_to_x, id_to_y;
|
||||||
|
|
||||||
|
pool<PipId> disabled_pips;
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
std::string getChipName() const override;
|
std::string getChipName() const override;
|
||||||
@ -976,6 +978,20 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
return tileStatus[bel.tile].boundcells[bel.index] == nullptr;
|
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
|
CellInfo *getBoundBelCell(BelId bel) const override
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
|
@ -227,9 +227,8 @@ struct NexusFasmWriter
|
|||||||
blank();
|
blank();
|
||||||
}
|
}
|
||||||
// Find the CIBMUX output for a signal
|
// 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())
|
if (cursor == WireId())
|
||||||
return WireId();
|
return WireId();
|
||||||
for (int i = 0; i < 10; i++) {
|
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
|
// Handle CIB muxes - these must be set such that floating pins really are floating to VCC and not connected
|
||||||
// to another CIB signal
|
// to another CIB signal
|
||||||
if ((pin_style & PINBIT_CIBMUX) && port.second.net == nullptr) {
|
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()) {
|
if (cibmuxout != WireId()) {
|
||||||
write_comment(stringf("CIBMUX for unused pin %s", ctx->nameOf(port.first)));
|
write_comment(stringf("CIBMUX for unused pin %s", ctx->nameOf(port.first)));
|
||||||
bool found = false;
|
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
|
// Write config for an OXIDE_COMB cell
|
||||||
void write_comb(const CellInfo *cell)
|
void write_comb(const CellInfo *cell)
|
||||||
{
|
{
|
||||||
@ -846,6 +874,8 @@ struct NexusFasmWriter
|
|||||||
write_dphy(ci);
|
write_dphy(ci);
|
||||||
blank();
|
blank();
|
||||||
}
|
}
|
||||||
|
// Handle DCC route-throughs
|
||||||
|
write_dcc_thru();
|
||||||
// Write config for unused bels
|
// Write config for unused bels
|
||||||
write_unused();
|
write_unused();
|
||||||
// Write bank config
|
// Write bank config
|
||||||
|
Loading…
Reference in New Issue
Block a user