From bc9f2da470b96c4e2f65324a0da1ffe099b5e586 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 19 Nov 2018 01:57:47 +0100 Subject: ice40: Introduce the concept of forPadIn SB_GB Those are cells that are created mainly to handle the various sources a global network can be driven from other than a user net. When the flag is set, this means the global network usually driven by this BEL is in fact driven by something else and so that SB_GB BEL and matching global network can't be used. This is also what gets used to set the extra bits during bitstream generation. Signed-off-by: Sylvain Munaut --- ice40/pack.cc | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'ice40/pack.cc') diff --git a/ice40/pack.cc b/ice40/pack.cc index d689fa69..cae6ab8c 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -381,6 +381,33 @@ static void pack_constants(Context *ctx) } } +static std::unique_ptr create_padin_gbuf(Context *ctx, CellInfo *cell, IdString port_name, + std::string gbuf_name) +{ + // Find the matching SB_GB BEL connected to the same global network + BelId gb_bel; + BelId bel = ctx->getBelByName(ctx->id(cell->attrs[ctx->id("BEL")])); + auto wire = ctx->getBelPinWire(bel, port_name); + for (auto src_bel : ctx->getWireBelPins(wire)) { + if (ctx->getBelType(src_bel.bel) == id_SB_GB && src_bel.pin == id_GLOBAL_BUFFER_OUTPUT) { + gb_bel = src_bel.bel; + break; + } + } + + NPNR_ASSERT(gb_bel != BelId()); + + // Create a SB_GB Cell and lock it there + std::unique_ptr gb = create_ice_cell(ctx, ctx->id("SB_GB"), gbuf_name); + gb->attrs[ctx->id("FOR_PAD_IN")] = "1"; + gb->attrs[ctx->id("BEL")] = ctx->getBelName(gb_bel).str(ctx); + + // Reconnect the net to that port for easier identification it's a global net + replace_port(cell, port_name, gb.get(), id_GLOBAL_BUFFER_OUTPUT); + + return gb; +} + static bool is_nextpnr_iob(Context *ctx, CellInfo *cell) { return cell->type == ctx->id("$nextpnr_ibuf") || cell->type == ctx->id("$nextpnr_obuf") || @@ -1003,13 +1030,13 @@ bool Arch::pack() try { log_break(); pack_constants(ctx); - promote_globals(ctx); pack_io(ctx); pack_lut_lutffs(ctx); pack_nonlut_ffs(ctx); pack_carries(ctx); pack_ram(ctx); pack_special(ctx); + promote_globals(ctx); ctx->assignArchInfo(); constrain_chains(ctx); ctx->assignArchInfo(); -- cgit v1.2.3