diff --git a/common/kernel/arch_api.h b/common/kernel/arch_api.h index 4eb6f4dde5..c7cb7f87e7 100644 --- a/common/kernel/arch_api.h +++ b/common/kernel/arch_api.h @@ -102,6 +102,7 @@ template struct ArchAPI : BaseCtx virtual WireId getPipDstWire(PipId pip) const = 0; virtual DelayQuad getPipDelay(PipId pip) const = 0; virtual Loc getPipLocation(PipId pip) const = 0; + virtual bool isPipInverting(PipId pip) const = 0; // Group methods virtual GroupId getGroupByName(IdStringList name) const = 0; virtual IdStringList getGroupName(GroupId group) const = 0; diff --git a/common/kernel/base_arch.h b/common/kernel/base_arch.h index 96f1d804c8..db02dc42fb 100644 --- a/common/kernel/base_arch.h +++ b/common/kernel/base_arch.h @@ -288,6 +288,7 @@ template struct BaseArch : ArchAPI } virtual WireId getConflictingPipWire(PipId /*pip*/) const override { return WireId(); } virtual NetInfo *getConflictingPipNet(PipId pip) const override { return getBoundPipNet(pip); } + virtual bool isPipInverting(PipId /*pip*/) const override { return false; } // Group methods virtual GroupId getGroupByName(IdStringList /*name*/) const override { return GroupId(); }; diff --git a/docs/archapi.md b/docs/archapi.md index 9918a895e7..9166db113f 100644 --- a/docs/archapi.md +++ b/docs/archapi.md @@ -417,6 +417,12 @@ pip is already bound to that net. *BaseArch default: returns `getBoundPipNet(pip) == nullptr || getBoundPipNet(pip) == net`* +### bool isPipInverting(PipId pip) const + +Returns true if the given pip inverts the net passing through it. + +*BaseArch default: returns `false`* + ### NetInfo \*getBoundPipNet(PipId pip) const Return the net this pip is bound to. diff --git a/himbaechel/arch.cc b/himbaechel/arch.cc index dccf285e29..fd449905b6 100644 --- a/himbaechel/arch.cc +++ b/himbaechel/arch.cc @@ -285,24 +285,33 @@ IdStringList Arch::getWireName(WireId wire) const PipId Arch::getPipByName(IdStringList name) const { - NPNR_ASSERT(name.size() == 3); - int tile = tile_name2idx.at(name[0]); + NPNR_ASSERT(name.size() == 3 || (name.size() == 4 && name[3] == id("INV"))); + const int tile = tile_name2idx.at(name[0]); const auto &tdata = chip_tile_info(chip_info, tile); for (int pip = 0; pip < tdata.pips.ssize(); pip++) { if (IdString(tdata.wires[tdata.pips[pip].dst_wire].name) == name[1] && - IdString(tdata.wires[tdata.pips[pip].src_wire].name) == name[2]) - return PipId(tile, pip); + IdString(tdata.wires[tdata.pips[pip].src_wire].name) == name[2]) { + + const auto tmp_pip = PipId(tile, pip); + if ((name.size() == 3 && !isPipInverting(tmp_pip)) || + (name.size() == 4 && isPipInverting(tmp_pip))) { + return tmp_pip; + } + } } return PipId(); } IdStringList Arch::getPipName(PipId pip) const { - auto &tdata = chip_tile_info(chip_info, pip.tile); - auto &pdata = tdata.pips[pip.index]; - return IdStringList::concat(tile_name.at(pip.tile), + const auto &tdata = chip_tile_info(chip_info, pip.tile); + const auto &pdata = tdata.pips[pip.index]; + const auto name = IdStringList::concat(tile_name.at(pip.tile), IdStringList::concat(IdString(tdata.wires[pdata.dst_wire].name), IdString(tdata.wires[pdata.src_wire].name))); + if (isPipInverting(pip)) + return IdStringList::concat(name, id("INV")); + return name; } IdString Arch::getPipType(PipId pip) const { return IdString(); } diff --git a/himbaechel/arch.h b/himbaechel/arch.h index 29f5cb8d50..d4a1f60ce0 100644 --- a/himbaechel/arch.h +++ b/himbaechel/arch.h @@ -662,6 +662,9 @@ struct Arch : BaseArch uarch->notifyPipChange(pip, nullptr); BaseArch::unbindPip(pip); } + bool isPipInverting(PipId pip) const override { + return uarch->isPipInverting(pip); + } // ------------------------------------------------- diff --git a/himbaechel/himbaechel_api.h b/himbaechel/himbaechel_api.h index 4f6f210130..2b49271320 100644 --- a/himbaechel/himbaechel_api.h +++ b/himbaechel/himbaechel_api.h @@ -89,6 +89,7 @@ struct HimbaechelAPI virtual bool checkWireAvail(WireId wire) const { return true; } virtual bool checkPipAvail(PipId pip) const { return true; } virtual bool checkPipAvailForNet(PipId pip, const NetInfo *net) const { return checkPipAvail(pip); }; + virtual bool isPipInverting(PipId pip) const { return false; } // --- Route lookahead --- virtual delay_t estimateDelay(WireId src, WireId dst) const;