aboutsummaryrefslogtreecommitdiffstats
path: root/nexus/arch.h
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-09-22 16:30:50 +0100
committergatecat <gatecat@ds0.me>2021-09-24 15:26:16 +0100
commit502fcff76554ecc10e47d7889cfcb60b41443105 (patch)
tree63825037aa3c1f30c3198305f9b6415134b6ab9b /nexus/arch.h
parentd9a71083e1a081f89e1aa4c357bc3b828eea6709 (diff)
downloadnextpnr-502fcff76554ecc10e47d7889cfcb60b41443105.tar.gz
nextpnr-502fcff76554ecc10e47d7889cfcb60b41443105.tar.bz2
nextpnr-502fcff76554ecc10e47d7889cfcb60b41443105.zip
nexus: LUT permutation support
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'nexus/arch.h')
-rw-r--r--nexus/arch.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/nexus/arch.h b/nexus/arch.h
index deb9b6db..300c3760 100644
--- a/nexus/arch.h
+++ b/nexus/arch.h
@@ -86,6 +86,7 @@ NPNR_PACKED_STRUCT(struct LocWireInfoPOD {
enum PipFlags
{
PIP_FIXED_CONN = 0x8000,
+ PIP_LUT_PERM = 0x4000,
};
NPNR_PACKED_STRUCT(struct PipInfoPOD {
@@ -979,10 +980,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 +1019,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);
}