diff --git a/ice40/arch.cc b/ice40/arch.cc index ce45b051..78d4c29c 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -168,6 +168,9 @@ Arch::Arch(ArchArgs args) : args(args) wire_to_net.resize(chip_info->num_wires); pip_to_net.resize(chip_info->num_pips); switches_locked.resize(chip_info->num_switches); + + // Initialise regularly used IDStrings for performance + id_glb_buf_out = id("GLOBAL_BUFFER_OUTPUT"); } // ----------------------------------------------------------------------- @@ -501,4 +504,11 @@ bool Arch::isClockPort(const CellInfo *cell, IdString port) const return false; } +bool Arch::isGlobalNet(const NetInfo *net) const +{ + if (net == nullptr) + return false; + return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out; +} + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 07c2582b..a6b70a69 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -800,6 +800,10 @@ struct Arch : BaseCtx IdString getPortClock(const CellInfo *cell, IdString port) const; // Return true if a port is a clock bool isClockPort(const CellInfo *cell, IdString port) const; + // Return true if a port is a net + bool isGlobalNet(const NetInfo *net) const; + + IdString id_glb_buf_out; }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 60fa928e..7b79e031 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -58,11 +58,11 @@ bool PlaceValidityChecker::logicCellsCompatible( clk = get_net_or_empty(cell, id_clk); sr = get_net_or_empty(cell, id_sr); - if (!is_global_net(ctx, cen) && cen != nullptr) + if (!ctx->isGlobalNet(cen) && cen != nullptr) locals_count++; - if (!is_global_net(ctx, clk) && clk != nullptr) + if (!ctx->isGlobalNet(clk) && clk != nullptr) locals_count++; - if (!is_global_net(ctx, sr) && sr != nullptr) + if (!ctx->isGlobalNet(sr) && sr != nullptr) locals_count++; if (bool_or_default(cell->params, id_neg_clk)) { @@ -140,7 +140,8 @@ bool PlaceValidityChecker::isValidBelForCell(CellInfo *cell, BelId bel) } else if (cell->type == id_sb_gb) { bool is_reset = false, is_cen = false; assert(cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net != nullptr); - for (auto user : cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net->users) { + for (auto user : + cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net->users) { if (is_reset_port(ctx, user)) is_reset = true; if (is_enable_port(ctx, user)) diff --git a/ice40/cells.cc b/ice40/cells.cc index 056c33f8..f34b7511 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -36,8 +36,8 @@ CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name) static int auto_idx = 0; CellInfo *new_cell = new CellInfo(); if (name.empty()) { - new_cell->name = ctx->id( "$nextpnr_" + type.str(ctx) + "_" + - std::to_string(auto_idx++)); + new_cell->name = ctx->id("$nextpnr_" + type.str(ctx) + "_" + + std::to_string(auto_idx++)); } else { new_cell->name = ctx->id(name); } @@ -269,10 +269,4 @@ bool is_enable_port(const Context *ctx, const PortRef &port) return false; } -bool is_global_net(const Context *ctx, const NetInfo *net) -{ - return bool( - net_driven_by(ctx, net, is_gbuf, ctx->id("GLOBAL_BUFFER_OUTPUT"))); -} - NEXTPNR_NAMESPACE_END diff --git a/ice40/cells.h b/ice40/cells.h index 3e5f6ebd..29331445 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -117,9 +117,6 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, // Convert a nextpnr IO buffer to a SB_IO void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio); -// Return true if a net is a global net -bool is_global_net(const Context *ctx, const NetInfo *net); - // Return true if a port is a clock port bool is_clock_port(const Context *ctx, const PortRef &port); diff --git a/ice40/pack.cc b/ice40/pack.cc index 868b0fd8..e6be502f 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -131,8 +131,9 @@ static void pack_carries(Context *ctx) CellInfo *ci = cell.second; if (is_carry(ctx, ci)) { packed_cells.insert(cell.first); - CellInfo *carry_ci_lc = net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, - is_lc, ctx->id("I3"), false); + CellInfo *carry_ci_lc = + net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc, + ctx->id("I3"), false); if (!ci->ports.at(ctx->id("I0")).net) log_error("SB_CARRY '%s' has disconnected port I0\n", cell.first.c_str(ctx)); @@ -227,7 +228,8 @@ static void pack_ram(Context *ctx) newname.substr(bpos + 1, (newname.size() - bpos) - 2); } - replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed, ctx->id(newname)); + replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed, + ctx->id(newname)); } } } @@ -268,14 +270,16 @@ static void pack_constants(Context *ctx) { log_info("Packing constants..\n"); - CellInfo *gnd_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND"); + CellInfo *gnd_cell = + create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND"); gnd_cell->params[ctx->id("LUT_INIT")] = "0"; NetInfo *gnd_net = new NetInfo; gnd_net->name = ctx->id("$PACKER_GND_NET"); gnd_net->driver.cell = gnd_cell; gnd_net->driver.port = ctx->id("O"); - CellInfo *vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); + CellInfo *vcc_cell = + create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); vcc_cell->params[ctx->id("LUT_INIT")] = "1"; NetInfo *vcc_net = new NetInfo; vcc_net->name = ctx->id("$PACKER_VCC_NET"); @@ -336,12 +340,14 @@ static void pack_io(Context *ctx) CellInfo *sb = nullptr; if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) { - sb = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net, is_sb_io, - ctx->id("PACKAGE_PIN"), true, ci); + sb = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net, + is_sb_io, ctx->id("PACKAGE_PIN"), true, + ci); } else if (ci->type == ctx->id("$nextpnr_obuf")) { - sb = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net, is_sb_io, - ctx->id("PACKAGE_PIN"), true, ci); + sb = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net, + is_sb_io, ctx->id("PACKAGE_PIN"), true, + ci); } if (sb != nullptr) { // Trivial case, SB_IO used. Just destroy the net and the @@ -416,7 +422,7 @@ static void promote_globals(Context *ctx) std::map clock_count, reset_count, cen_count; for (auto net : sorted(ctx->nets)) { NetInfo *ni = net.second; - if (ni->driver.cell != nullptr && !is_global_net(ctx, ni)) { + if (ni->driver.cell != nullptr && !ctx->isGlobalNet(ni)) { clock_count[net.first] = 0; reset_count[net.first] = 0; cen_count[net.first] = 0; @@ -503,7 +509,8 @@ static void pack_intosc(Context *ctx) replace_port(ci, ctx->id("CLKLFEN"), packed, ctx->id("CLKLFEN")); replace_port(ci, ctx->id("CLKLFPU"), packed, ctx->id("CLKLFPU")); if (bool_or_default(ci->attrs, ctx->id("ROUTE_THROUGH_FABRIC"))) { - replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF_FABRIC")); + replace_port(ci, ctx->id("CLKLF"), packed, + ctx->id("CLKLF_FABRIC")); } else { replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF")); }