aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/pack.cc
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2018-11-19 01:57:47 +0100
committerSylvain Munaut <tnt@246tNt.com>2018-11-19 18:20:20 +0100
commitbc9f2da470b96c4e2f65324a0da1ffe099b5e586 (patch)
tree7c05b3544a4ace9d69af28922751a5cd63d0d387 /ice40/pack.cc
parent325d46e284fd7944b99929c1482e641a1db53931 (diff)
downloadnextpnr-bc9f2da470b96c4e2f65324a0da1ffe099b5e586.tar.gz
nextpnr-bc9f2da470b96c4e2f65324a0da1ffe099b5e586.tar.bz2
nextpnr-bc9f2da470b96c4e2f65324a0da1ffe099b5e586.zip
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 <tnt@246tNt.com>
Diffstat (limited to 'ice40/pack.cc')
-rw-r--r--ice40/pack.cc29
1 files changed, 28 insertions, 1 deletions
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<CellInfo> 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<CellInfo> 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();