diff options
author | David Shah <dave@ds0.me> | 2019-08-27 13:14:41 +0100 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2019-08-27 13:14:41 +0100 |
commit | 78f86ce67afebe20d6a152ac53cf0f8ff16132a7 (patch) | |
tree | c63c7d250c160471738a0e909c1a9337c7a92669 | |
parent | ccd9ca2a30374341207a975cfd1de172b9a59480 (diff) | |
download | nextpnr-78f86ce67afebe20d6a152ac53cf0f8ff16132a7.tar.gz nextpnr-78f86ce67afebe20d6a152ac53cf0f8ff16132a7.tar.bz2 nextpnr-78f86ce67afebe20d6a152ac53cf0f8ff16132a7.zip |
ecp5: Add GSR/SGSR support
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r-- | ecp5/arch.cc | 8 | ||||
-rw-r--r-- | ecp5/arch.h | 4 | ||||
-rw-r--r-- | ecp5/bitstream.cc | 2 | ||||
-rw-r--r-- | ecp5/pack.cc | 11 |
4 files changed, 22 insertions, 3 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 01a4346f..a2936688 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -440,7 +440,10 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const auto est_location = [&](WireId w) -> std::pair<int, int> { const auto &wire = locInfo(w)->wire_data[w.index]; - if (wire.num_bel_pins > 0) { + if (w == gsrclk_wire) { + auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin())); + return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y)); + } else if (wire.num_bel_pins > 0) { return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x, w.location.y + wire.bel_pins[0].rel_bel_loc.y); } else if (wire.num_downhill > 0) { @@ -711,7 +714,8 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort std::string fn = fromPort.str(this), tn = toPort.str(this); if (fn.size() > 1 && (fn.front() == 'A' || fn.front() == 'B') && std::isdigit(fn.at(1))) { if (tn.size() > 1 && tn.front() == 'P' && std::isdigit(tn.at(1))) - return getDelayFromTimingDatabase(id_MULT18X18D_REGS_NONE, id(std::string("") + fn.front()), id_P, delay); + return getDelayFromTimingDatabase(id_MULT18X18D_REGS_NONE, id(std::string("") + fn.front()), id_P, + delay); } return false; } else if (cell->type == id_IOLOGIC || cell->type == id_SIOLOGIC) { diff --git a/ecp5/arch.h b/ecp5/arch.h index cee071e7..e85d9c43 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -1044,6 +1044,10 @@ struct Arch : BaseCtx IdString id_clkmux, id_lsrmux; IdString id_srmode, id_mode; + // Special case for delay estimates due to its physical location + // being far from the logical location of its primitive + WireId gsrclk_wire; + mutable std::unordered_map<DelayKey, std::pair<bool, DelayInfo>> celldelay_cache; static const std::string defaultPlacer; diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index 1e0dcadc..cac11867 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -1277,7 +1277,7 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex cc.tiles[ctx->getTileByType("EFB3_PICB1")].add_enum("CCLK.MODE", "USRMCLK"); } else if (ci->type == id_GSR) { cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum( - "GSR.GSRMODE", str_or_default(ci->params, ctx->id("MODE"), "ACTIVE_HIGH")); + "GSR.GSRMODE", str_or_default(ci->params, ctx->id("MODE"), "ACTIVE_LOW")); cc.tiles[ctx->getTileByType("VIQ_BUF")].add_enum("GSR.SYNCMODE", str_or_default(ci->params, ctx->id("SYNCMODE"), "ASYNC")); } else if (ci->type == id_JTAGG) { diff --git a/ecp5/pack.cc b/ecp5/pack.cc index 7cf9df78..e610dfe5 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -1411,6 +1411,17 @@ class Ecp5Packer rename_port(ctx, ci, ctx->id("USRMCLKI"), id_PADDO); rename_port(ctx, ci, ctx->id("USRMCLKTS"), id_PADDT); rename_port(ctx, ci, ctx->id("USRMCLKO"), id_PADDI); + } else if (ci->type == id_GSR || ci->type == ctx->id("SGSR")) { + ci->params[ctx->id("MODE")] = std::string("ACTIVE_LOW"); + ci->params[ctx->id("SYNCMODE")] = + ci->type == ctx->id("SGSR") ? std::string("SYNC") : std::string("ASYNC"); + ci->type = id_GSR; + for (BelId bel : ctx->getBels()) { + if (ctx->getBelType(bel) != id_GSR) + continue; + ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx); + ctx->gsrclk_wire = ctx->getBelPinWire(bel, id_CLK); + } } } } |