From 68abcb365a7e1c426d2ca96e2381892aa53e6192 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 13 Feb 2019 11:23:12 +0000 Subject: ecp5: Add ECLKSYNCB support Signed-off-by: David Shah --- ecp5/arch.cc | 4 ++++ ecp5/bitstream.cc | 7 +++++++ ecp5/pack.cc | 25 +++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) (limited to 'ecp5') diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 81f9682c..7de5c7aa 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -765,6 +765,10 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in return (cell->ports.at(port).type == PORT_OUT) ? TMG_STARTPOINT : TMG_ENDPOINT; } else if (cell->type == id_TRELLIS_ECLKBUF) { return (cell->ports.at(port).type == PORT_OUT) ? TMG_COMB_OUTPUT : TMG_COMB_INPUT; + } else if (cell->type == id_ECLKSYNCB) { + if (cell->ports.at(port).name == id_STOP) + return TMG_ENDPOINT; + return (cell->ports.at(port).type == PORT_OUT) ? TMG_COMB_OUTPUT : TMG_COMB_INPUT; } else { log_error("cell type '%s' is unsupported (instantiated as '%s')\n", cell->type.c_str(this), cell->name.c_str(this)); diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index 789957c6..c433a088 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -1221,6 +1221,13 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex tg.config.add_enum("DQS.DDRDEL", get_net_or_empty(ci, id_DDRDEL) != nullptr ? "DDRDEL" : "0"); tg.config.add_enum("DQS.GSR", str_or_default(ci->params, ctx->id("GSR"), "DISABLED")); cc.tilegroups.push_back(tg); + } else if (ci->type == id_ECLKSYNCB) { + Loc loc = ctx->getBelLocation(ci->bel); + bool r = loc.x > 5; + std::string eclksync = ctx->locInfo(bel)->bel_data[bel.index].name.get(); + std::string tile = ctx->getTileByType(std::string("ECLK_") + (r ? "R" : "L")); + if (get_net_or_empty(ci, id_STOP) != nullptr) + cc.tiles[tile].add_enum(eclksync + ".MODE", "ECLKSYNCB"); } else { NPNR_ASSERT_FALSE("unsupported cell type"); } diff --git a/ecp5/pack.cc b/ecp5/pack.cc index 17b0ea3b..b84d4d60 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -1958,11 +1958,32 @@ class Ecp5Packer continue; ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx); make_eclk(ci->ports.at(id_CLKI), ci, bel, eclk.first.first); - goto done; + goto clkdiv_done; } } } - done: + clkdiv_done: + continue; + } else if (ci->type == id_ECLKSYNCB) { + const NetInfo *eclko = net_or_nullptr(ci, id_ECLKO); + if (eclko == nullptr) + log_error("ECLKSYNCB '%s' has disconnected port ECLKO\n", ci->name.c_str(ctx)); + for (auto user : eclko->users) { + if (user.cell->type == id_TRELLIS_ECLKBUF) { + Loc eckbuf_loc = + ctx->getBelLocation(ctx->getBelByName(ctx->id(user.cell->attrs.at(ctx->id("BEL"))))); + for (auto bel : ctx->getBels()) { + if (ctx->getBelType(bel) != id_ECLKSYNCB) + continue; + Loc loc = ctx->getBelLocation(bel); + if (loc.x == eckbuf_loc.x && loc.y == eckbuf_loc.y && loc.z == eckbuf_loc.z - 2) { + ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx); + goto eclksync_done; + } + } + } + } + eclksync_done: continue; } } -- cgit v1.2.3