From e6450a179bb87bfafcd05d2937ef327703bb17ba Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 9 Jan 2025 14:27:21 +0100 Subject: [PATCH] Added MX2 and MX4 support --- himbaechel/uarch/gatemate/constids.inc | 10 +++++++ himbaechel/uarch/gatemate/gatemate.cc | 32 +++++++++++++++++++++ himbaechel/uarch/gatemate/gatemate.h | 6 ++++ himbaechel/uarch/gatemate/pack.cc | 39 ++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/himbaechel/uarch/gatemate/constids.inc b/himbaechel/uarch/gatemate/constids.inc index 226fa34f..a5bc0be2 100644 --- a/himbaechel/uarch/gatemate/constids.inc +++ b/himbaechel/uarch/gatemate/constids.inc @@ -119,3 +119,13 @@ X(2D_IN) X(CC_BUFG) X(BUFG) + +X(CC_MX2) +X(CC_MX4) +X(FUNCTION) +X(D0) +X(D1) +X(D2) +X(D3) +X(S0) +X(S1) diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index 3ce01300..d69a864e 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -149,6 +149,38 @@ void GateMateImpl::postRoute() } } +void GateMateImpl::postPlace() +{ + log_break(); + log_info("Limiting routing...\n"); + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (ci.type == id_CPE) { + if (!ci.params.count(id_FUNCTION)) continue; + uint8_t func = int_or_default(ci.params, id_FUNCTION, 0); + if (func!=4) continue; // Skip all that are not MUX + for (int i = 1; i <= 4; i++) { + IdString port = ctx->idf("IN%d", i); + NetInfo *net = ci.getPort(port); + if (!net) + continue; + WireId dwire = ctx->getBelPinWire(ci.bel, port); + for (PipId pip : ctx->getPipsUphill(dwire)) { + const auto extra_data = *reinterpret_cast( + chip_pip_info(ctx->chip_info, pip).extra_data.get()); + if (!extra_data.name) + continue; + if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_CPE_INV)) { + blocked_pips.emplace(pip); + } + } + } + } + } + ctx->assignArchInfo(); +} + + void GateMateImpl::setupArchContext() { const ArchArgs &args = ctx->args; diff --git a/himbaechel/uarch/gatemate/gatemate.h b/himbaechel/uarch/gatemate/gatemate.h index ed4a8c4f..cc91598e 100644 --- a/himbaechel/uarch/gatemate/gatemate.h +++ b/himbaechel/uarch/gatemate/gatemate.h @@ -40,6 +40,7 @@ struct GateMateImpl : HimbaechelAPI void pack() override; + void postPlace() override; void postRoute() override; bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override; @@ -50,6 +51,9 @@ struct GateMateImpl : HimbaechelAPI void write_bitstream(const std::string &device, const std::string &filename); bool read_bitstream(const std::string &device, const std::string &filename); + bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip) == 0; } + bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); }; + void parse_ccf(const std::string &filename); IdString getBelBucketForCellType(IdString cell_type) const; @@ -59,6 +63,8 @@ struct GateMateImpl : HimbaechelAPI const auto &extra_data = *reinterpret_cast(chip_pip_info(ctx->chip_info, pip).extra_data.get()); return extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_INVERT); } + + pool blocked_pips; }; NEXTPNR_NAMESPACE_END diff --git a/himbaechel/uarch/gatemate/pack.cc b/himbaechel/uarch/gatemate/pack.cc index 34cc8794..8f16616c 100644 --- a/himbaechel/uarch/gatemate/pack.cc +++ b/himbaechel/uarch/gatemate/pack.cc @@ -316,6 +316,45 @@ void GateMatePacker::pack_cpe() ci.type = id_CPE; } + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (!ci.type.in(id_CC_MX2, id_CC_MX4)) + continue; + if (ci.type == id_CC_MX2) { + ci.renamePort(id_S0, id_IN6); + ci.renamePort(id_D0, id_IN1); + ci.renamePort(id_D1, id_IN2); + ci.renamePort(id_Y, id_OUT1); + + ci.params[id_FUNCTION] = Property(0b100, 3); + ci.params[id_INIT_L02] = Property(0b1100, 4); // IN6 + ci.params[id_INIT_L10] = Property(0b0011, 4); + ci.params[id_INIT_L11] = Property(0b0011, 4); + ci.params[id_INIT_L20] = Property(0b0011, 4); + ci.params[id_O1] = Property(0b11, 2); + ci.type = id_CPE; + } else { + ci.renamePort(id_D0, id_IN1); + ci.renamePort(id_D1, id_IN2); + ci.renamePort(id_D2, id_IN3); + ci.renamePort(id_D3, id_IN4); + + ci.renamePort(id_S0, id_IN6); + ci.renamePort(id_S1, id_IN8); + ci.renamePort(id_Y, id_OUT1); + + ci.params[id_FUNCTION] = Property(0b100, 3); + ci.params[id_INIT_L02] = Property(0b1100, 4); // IN6 + ci.params[id_INIT_L03] = Property(0b1100, 4); // IN8 + + ci.params[id_INIT_L10] = Property(0b1111, 4); + ci.params[id_INIT_L11] = Property(0b0011, 4); + ci.params[id_INIT_L20] = Property(0b1100, 4); + ci.params[id_O1] = Property(0b11, 2); + ci.type = id_CPE; + } + } + for (auto &cell : ctx->cells) { CellInfo &ci = *cell.second; if (!ci.type.in(id_CC_DFF))