From e8a1b51eec2bb8596cd43a1740d9fa4447cc89d2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 10 May 2024 11:58:31 +0200 Subject: [PATCH] Block certain pips depending of DDFR mode --- himbaechel/uarch/ng-ultra/ng_ultra.h | 4 ++++ himbaechel/uarch/ng-ultra/pack.cc | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.h b/himbaechel/uarch/ng-ultra/ng_ultra.h index fe67040c..728491f2 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.h +++ b/himbaechel/uarch/ng-ultra/ng_ultra.h @@ -59,6 +59,8 @@ struct NgUltraImpl : HimbaechelAPI delay_t estimateDelay(WireId src, WireId dst) const override; delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override; + bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip)==0; } + bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); }; public: IdString tile_name_id(int tile) const; std::string tile_name(int tile) const; @@ -67,6 +69,8 @@ public: dict bank_voltage; dict global_capable_bels; + pool blocked_pips; + private: void write_bitstream_json(const std::string &filename); void route_clocks(); diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index a722a712..8769f1bb 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -475,6 +475,7 @@ void NgUltraPacker::pack_iobs(void) NetInfo *o_net = cell->getPort(id_O); if (o_net) { CellInfo *iod = net_only_drives(ctx, o_net, is_dfr, id_I, true); + bool bfr_mode = false; if (!iod) { if (cell->type==id_IOTP) ddrf_as_bfr++; else dfr_as_bfr++; iod = create_cell_ptr((cell->type==id_IOTP) ? id_DDFR : id_DFR, ctx->id(cell->name.str(ctx) + "$iod_id")); @@ -487,11 +488,28 @@ void NgUltraPacker::pack_iobs(void) iod->setParam(ctx->id("data_inv"), Property(0, 1)); iod->connectPort(id_I, new_in); cell->connectPort(id_O,new_in); + bfr_mode = true; } else log_error("TODO handle DFR"); Loc cd_loc = cell->getLocation(); cd_loc.z += 1; BelId bel = ctx->getBelByLocation(cd_loc); ctx->bindBel(bel, iod, PlaceStrength::STRENGTH_LOCKED); + + // Depending of DDFR mode we must use one of dedicated routes (ITCs) + if (iod->type==id_DDFR) { + WireId dwire = ctx->getBelPinWire(bel, id_O); + for (PipId pip : ctx->getPipsDownhill(dwire)) { + const auto &pip_data = chip_pip_info(ctx->chip_info, pip); + const auto &extra_data = *reinterpret_cast(pip_data.extra_data.get()); + if (!extra_data.name) continue; + if (extra_data.type != PipExtra::PIP_EXTRA_MUX) continue; + if (bfr_mode && extra_data.input == 2) { + uarch->blocked_pips.emplace(pip); + } else if (!bfr_mode && extra_data.input == 1) { + uarch->blocked_pips.emplace(pip); + } + } + } } } if (dfr_as_bfr)