diff options
Diffstat (limited to 'nexus/arch.h')
-rw-r--r-- | nexus/arch.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/nexus/arch.h b/nexus/arch.h index deb9b6db..3e718e78 100644 --- a/nexus/arch.h +++ b/nexus/arch.h @@ -86,6 +86,9 @@ NPNR_PACKED_STRUCT(struct LocWireInfoPOD { enum PipFlags { PIP_FIXED_CONN = 0x8000, + PIP_LUT_PERM = 0x4000, + PIP_ZERO_RR_COST = 0x2000, + PIP_DRMUX_C = 0x1000, }; NPNR_PACKED_STRUCT(struct PipInfoPOD { @@ -979,10 +982,38 @@ struct Arch : BaseArch<ArchRanges> return tileStatus[bel.tile].boundcells[bel.index] == nullptr; } + bool is_pseudo_pip_disabled(PipId pip) const + { + const auto &data = pip_data(pip); + if (data.flags & PIP_LUT_PERM) { + int lut_idx = (data.flags >> 8) & 0xF; + int from_pin = (data.flags >> 4) & 0xF; + int to_pin = (data.flags >> 0) & 0xF; + auto &ts = tileStatus.at(pip.tile); + if (!ts.lts) + return false; + const CellInfo *lut = ts.lts->cells[((lut_idx / 2) << 3) | (BEL_LUT0 + (lut_idx % 2))]; + if (lut) { + if (lut->lutInfo.is_memory) + return true; + if (lut->lutInfo.is_carry && (from_pin == 3 || to_pin == 3)) + return true; // Upper pin is special for carries + } + if (lut_idx == 4 || lut_idx == 5) { + const CellInfo *ramw = ts.lts->cells[((lut_idx / 2) << 3) | BEL_RAMW]; + if (ramw) + return true; // Don't permute RAM write address + } + } + return false; + } + bool checkPipAvail(PipId pip) const override { if (disabled_pips.count(pip)) return false; + if (is_pseudo_pip_disabled(pip)) + return false; return BaseArch::checkPipAvail(pip); } @@ -990,6 +1021,8 @@ struct Arch : BaseArch<ArchRanges> { if (disabled_pips.count(pip)) return false; + if (is_pseudo_pip_disabled(pip)) + return false; return BaseArch::checkPipAvailForNet(pip, net); } |