From ecc19c2c083f7e3ed7da95557731ded803d2cb1d Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 2 Jun 2021 10:01:36 +0100 Subject: Using hashlib in arches Signed-off-by: gatecat --- common/base_arch.h | 12 ++--- common/hashlib.h | 9 ++++ ecp5/arch.h | 26 +++------- ecp5/bitstream.cc | 4 +- ecp5/cells.cc | 2 +- ecp5/cells.h | 2 +- ecp5/globals.cc | 14 +++--- ecp5/lpf.cc | 5 +- ecp5/pack.cc | 29 ++++++------ fpga_interchange/arch.cc | 19 ++------ fpga_interchange/arch.h | 22 ++++----- fpga_interchange/arch_pack_io.cc | 26 +++++----- fpga_interchange/archdefs.h | 7 ++- fpga_interchange/cell_parameters.h | 3 +- fpga_interchange/cost_map.cc | 2 +- fpga_interchange/cost_map.h | 5 +- fpga_interchange/dedicated_interconnect.cc | 6 +-- fpga_interchange/dedicated_interconnect.h | 36 ++------------ fpga_interchange/fpga_interchange.cpp | 54 ++++++++------------- fpga_interchange/globals.cc | 2 +- fpga_interchange/lookahead.cc | 76 ++++++++++++++---------------- fpga_interchange/lookahead.h | 7 ++- fpga_interchange/luts.cc | 14 +++--- fpga_interchange/luts.h | 23 ++++----- fpga_interchange/pseudo_pip_model.cc | 8 ++-- fpga_interchange/pseudo_pip_model.h | 33 +++---------- fpga_interchange/site_arch.cc | 2 +- fpga_interchange/site_arch.h | 46 ++++-------------- fpga_interchange/site_router.cc | 24 ++++------ fpga_interchange/site_router.h | 5 +- fpga_interchange/site_routing_cache.cc | 2 +- fpga_interchange/site_routing_cache.h | 39 ++++++--------- fpga_interchange/type_wire.cc | 5 +- fpga_interchange/type_wire.h | 36 +++----------- generic/arch.h | 39 +++++---------- generic/archdefs.h | 5 +- generic/cells.cc | 2 +- generic/cells.h | 2 +- generic/pack.cc | 9 ++-- gowin/arch.h | 37 +++++---------- gowin/cells.cc | 2 +- gowin/cells.h | 2 +- gowin/pack.cc | 9 ++-- ice40/arch.h | 10 ++-- ice40/bitstream.cc | 8 ++-- ice40/cells.cc | 2 +- ice40/cells.h | 2 +- ice40/chains.cc | 2 +- ice40/pack.cc | 19 ++++---- machxo2/arch.h | 4 +- machxo2/cells.cc | 2 +- machxo2/cells.h | 2 +- machxo2/pack.cc | 9 ++-- mistral/arch.h | 29 ++++++------ mistral/archdefs.h | 2 +- mistral/lab.cc | 4 +- mistral/pins.cc | 2 +- mistral/qsf.cc | 2 +- nexus/arch.h | 12 ++--- nexus/archdefs.h | 3 +- nexus/fasm.cc | 10 ++-- nexus/global.cc | 2 +- nexus/io.cc | 2 +- nexus/pack.cc | 63 ++++++++++++------------- nexus/pdc.cc | 2 +- nexus/pins.cc | 2 +- 66 files changed, 358 insertions(+), 549 deletions(-) diff --git a/common/base_arch.h b/common/base_arch.h index fbafee99..c7d9f380 100644 --- a/common/base_arch.h +++ b/common/base_arch.h @@ -441,23 +441,23 @@ template struct BaseArch : ArchAPI // -------------------------------------------------------------- // These structures are used to provide default implementations of bel/wire/pip binding. Arches might want to - // replace them with their own, for example to use faster access structures than unordered_map. Arches might also + // replace them with their own, for example to use faster access structures than dict. Arches might also // want to add extra checks around these functions - std::unordered_map base_bel2cell; - std::unordered_map base_wire2net; - std::unordered_map base_pip2net; + dict base_bel2cell; + dict base_wire2net; + dict base_pip2net; // For the default cell/bel bucket implementations std::vector cell_types; std::vector bel_buckets; - std::unordered_map> bucket_bels; + dict> bucket_bels; // Arches that want to use the default cell types and bel buckets *must* call these functions in their constructor bool cell_types_initialised = false; bool bel_buckets_initialised = false; void init_cell_types() { - std::unordered_set bel_types; + pool bel_types; for (auto bel : this->getBels()) bel_types.insert(this->getBelType(bel)); std::copy(bel_types.begin(), bel_types.end(), std::back_inserter(cell_types)); diff --git a/common/hashlib.h b/common/hashlib.h index 30fefc65..063df78f 100644 --- a/common/hashlib.h +++ b/common/hashlib.h @@ -74,6 +74,15 @@ template <> struct hash_ops : hash_int_ops static inline unsigned int hash(int64_t a) { return mkhash((unsigned int)(a), (unsigned int)(a >> 32)); } }; +template <> struct hash_ops : hash_int_ops +{ + static inline unsigned int hash(uint32_t a) { return a; } +}; +template <> struct hash_ops : hash_int_ops +{ + static inline unsigned int hash(uint64_t a) { return mkhash((unsigned int)(a), (unsigned int)(a >> 32)); } +}; + template <> struct hash_ops { static inline bool cmp(const std::string &a, const std::string &b) { return a == b; } diff --git a/ecp5/arch.h b/ecp5/arch.h index 063a3df6..be1a44d8 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -419,23 +419,9 @@ struct DelayKey { return celltype == other.celltype && from == other.from && to == other.to; } + unsigned int hash() const { return mkhash(celltype.hash(), mkhash(from.hash(), to.hash())); } }; -NEXTPNR_NAMESPACE_END -namespace std { -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DelayKey &dk) const noexcept - { - std::size_t seed = std::hash()(dk.celltype); - seed ^= std::hash()(dk.from) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - seed ^= std::hash()(dk.to) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } -}; -} // namespace std -NEXTPNR_NAMESPACE_BEGIN - struct ArchRanges : BaseArchRanges { using ArchArgsT = ArchArgs; @@ -458,15 +444,15 @@ struct Arch : BaseArch const PackageInfoPOD *package_info; const SpeedGradePOD *speed_grade; - mutable std::unordered_map pip_by_name; + mutable dict pip_by_name; std::vector bel_to_cell; - std::unordered_map wire_fanout; + dict wire_fanout; // fast access to X and Y IdStrings for building object names std::vector x_ids, y_ids; // inverse of the above for name->object mapping - std::unordered_map id_to_x, id_to_y; + dict id_to_x, id_to_y; ArchArgs args; Arch(ArchArgs args); @@ -914,10 +900,10 @@ struct Arch : BaseArch // Improves directivity of routing to DSP inputs, avoids issues // with different routes to the same physical reset wire causing // conflicts and slow routing - std::unordered_map> wire_loc_overrides; + dict> wire_loc_overrides; void setup_wire_locations(); - mutable std::unordered_map> celldelay_cache; + mutable dict> celldelay_cache; static const std::string defaultPlacer; static const std::vector availablePlacers; diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index c8349f88..ac9d4a4d 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -669,8 +669,8 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex } } // Find bank voltages - std::unordered_map bankVcc; - std::unordered_map bankLvds, bankVref, bankDiff; + dict bankVcc; + dict bankLvds, bankVref, bankDiff; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); diff --git a/ecp5/cells.cc b/ecp5/cells.cc index 7f9f1579..edc80329 100644 --- a/ecp5/cells.cc +++ b/ecp5/cells.cc @@ -422,7 +422,7 @@ void dram_to_ram_slice(Context *ctx, CellInfo *ram, CellInfo *lc, CellInfo *ramw } void nxio_to_tr(Context *ctx, CellInfo *nxio, CellInfo *trio, std::vector> &created_cells, - std::unordered_set &todelete_cells) + pool &todelete_cells) { if (nxio->type == ctx->id("$nextpnr_ibuf")) { trio->params[ctx->id("DIR")] = std::string("INPUT"); diff --git a/ecp5/cells.h b/ecp5/cells.h index e66f8f21..20ba97b4 100644 --- a/ecp5/cells.h +++ b/ecp5/cells.h @@ -65,7 +65,7 @@ void dram_to_ram_slice(Context *ctx, CellInfo *ram, CellInfo *lc, CellInfo *ramw // Convert a nextpnr IO buffer to a TRELLIS_IO void nxio_to_tr(Context *ctx, CellInfo *nxio, CellInfo *trio, std::vector> &created_cells, - std::unordered_set &todelete_cells); + pool &todelete_cells); NEXTPNR_NAMESPACE_END diff --git a/ecp5/globals.cc b/ecp5/globals.cc index 1e86fe6b..b840ac91 100644 --- a/ecp5/globals.cc +++ b/ecp5/globals.cc @@ -72,7 +72,7 @@ class Ecp5GlobalRouter std::vector get_clocks() { - std::unordered_map clockCount; + dict clockCount; for (auto &net : ctx->nets) { NetInfo *ni = net.second.get(); if (ni->name == ctx->id("$PACKER_GND_NET") || ni->name == ctx->id("$PACKER_VCC_NET")) @@ -147,7 +147,7 @@ class Ecp5GlobalRouter WireId globalWire; IdString global_name = ctx->id(fmt_str("G_HPBX" << std::setw(2) << std::setfill('0') << global_index << "00")); std::queue upstream; - std::unordered_map backtrace; + dict backtrace; upstream.push(userWire); bool already_routed = false; WireId next; @@ -230,7 +230,7 @@ class Ecp5GlobalRouter bool simple_router(NetInfo *net, WireId src, WireId dst, bool allow_fail = false) { std::queue visit; - std::unordered_map backtrace; + dict backtrace; visit.push(src); WireId cursor; while (true) { @@ -340,7 +340,7 @@ class Ecp5GlobalRouter bool has_short_route(WireId src, WireId dst, int thresh = 7) { std::queue visit; - std::unordered_map backtrace; + dict backtrace; visit.push(src); WireId cursor; while (true) { @@ -376,7 +376,7 @@ class Ecp5GlobalRouter return length < thresh; } - std::unordered_set used_pclkcib; + pool used_pclkcib; std::set get_candidate_pclkcibs(BelId dcc) { @@ -535,7 +535,7 @@ class Ecp5GlobalRouter fab_globals.insert(i); } std::vector> toroute; - std::unordered_map clocks; + dict clocks; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); if (ci->type == id_DCCA) { @@ -595,7 +595,7 @@ class Ecp5GlobalRouter WireId src = ctx->getNetinfoSourceWire(ni); WireId dst = ctx->getBelPinWire(ci->bel, pin); std::queue visit; - std::unordered_map backtrace; + dict backtrace; visit.push(dst); int iter = 0; WireId cursor; diff --git a/ecp5/lpf.cc b/ecp5/lpf.cc index 6d134e8d..39576fcb 100644 --- a/ecp5/lpf.cc +++ b/ecp5/lpf.cc @@ -19,7 +19,6 @@ #include #include -#include #include "arch.h" #include "log.h" @@ -27,7 +26,7 @@ NEXTPNR_NAMESPACE_BEGIN -static const std::unordered_set sysconfig_keys = { +static const pool sysconfig_keys = { "SLAVE_SPI_PORT", "MASTER_SPI_PORT", "SLAVE_PARALLEL_PORT", "BACKGROUND_RECONFIG", "DONE_EX", "DONE_OD", "DONE_PULL", "MCCLK_FREQ", "TRANSFR", @@ -35,7 +34,7 @@ static const std::unordered_set sysconfig_keys = { "COMPRESS_CONFIG", "CONFIG_MODE", "INBUF", }; -static const std::unordered_set iobuf_keys = { +static const pool iobuf_keys = { "IO_TYPE", "BANK", "BANK_VCC", "VREF", "PULLMODE", "DRIVE", "SLEWRATE", "CLAMP", "OPENDRAIN", "DIFFRESISTOR", "DIFFDRIVE", "HYSTERESIS", "TERMINATION", }; diff --git a/ecp5/pack.cc b/ecp5/pack.cc index db5d22a1..19eda9e2 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -21,7 +21,6 @@ #include #include #include -#include #include "cells.h" #include "chain_utils.h" #include "design_utils.h" @@ -261,7 +260,7 @@ class Ecp5Packer void pair_luts() { log_info("Finding LUT-LUT pairs...\n"); - std::unordered_set procdLuts; + pool procdLuts; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); if (is_lut(ctx, ci) && procdLuts.find(cell.first) == procdLuts.end()) { @@ -1134,7 +1133,7 @@ class Ecp5Packer // Used for packing an FF into a nearby SLICE template CellInfo *find_nearby_cell(CellInfo *origin, TFunc Func) { - std::unordered_set visited_cells; + pool visited_cells; std::queue to_visit; visited_cells.insert(origin); to_visit.push(origin); @@ -1971,7 +1970,7 @@ class Ecp5Packer IdString global_name = ctx->id("G_BANK" + std::to_string(bank) + "ECLK" + std::to_string(found_eclk)); std::queue upstream; - std::unordered_map backtrace; + dict backtrace; upstream.push(userWire); WireId next; while (true) { @@ -2026,7 +2025,7 @@ class Ecp5Packer new_cells.push_back(std::move(zero_cell)); } - std::unordered_map> dqsbuf_dqsg; + dict> dqsbuf_dqsg; // Pack DQSBUFs void pack_dqsbuf() { @@ -2119,7 +2118,7 @@ class Ecp5Packer // Pack IOLOGIC void pack_iologic() { - std::unordered_map pio_iologic; + dict pio_iologic; auto set_iologic_sclk = [&](CellInfo *iol, CellInfo *prim, IdString port, bool input, bool disconnect = true) { NetInfo *sclk = nullptr; @@ -2779,7 +2778,7 @@ class Ecp5Packer } } flush_cells(); - std::unordered_set used_eclksyncb; + pool used_eclksyncb; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); if (ci->type == id_CLKDIVF) { @@ -2967,7 +2966,7 @@ class Ecp5Packer auto equals_epsilon = [](delay_t a, delay_t b) { return (std::abs(a - b) / std::max(double(b), 1.0)) < 1e-3; }; - std::unordered_set user_constrained, changed_nets; + pool user_constrained, changed_nets; for (auto &net : ctx->nets) { if (net.second->clkconstr != nullptr) user_constrained.insert(net.first); @@ -3041,7 +3040,7 @@ class Ecp5Packer const int itermax = 5000; while (!changed_nets.empty() && iter < itermax) { ++iter; - std::unordered_set changed_cells; + pool changed_cells; for (auto net : changed_nets) { for (auto &user : ctx->nets.at(net)->users) if (user.port == id_CLKI || user.port == id_ECLKI || user.port == id_CLK0 || user.port == id_CLK1) @@ -3051,7 +3050,7 @@ class Ecp5Packer changed_cells.insert(drv.cell->name); } changed_nets.clear(); - for (auto cell : sorted(changed_cells)) { + for (auto cell : changed_cells) { CellInfo *ci = ctx->cells.at(cell).get(); if (ci->type == id_CLKDIVF) { std::string div = str_or_default(ci->params, ctx->id("DIV"), "2.0"); @@ -3152,7 +3151,7 @@ class Ecp5Packer private: Context *ctx; - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; struct SliceUsage @@ -3163,10 +3162,10 @@ class Ecp5Packer bool mux5_used = false, muxx_used = false; }; - std::unordered_map sliceUsage; - std::unordered_map lutffPairs; - std::unordered_map fflutPairs; - std::unordered_map lutPairs; + dict sliceUsage; + dict lutffPairs; + dict fflutPairs; + dict lutPairs; }; // Main pack function bool Arch::pack() diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index 663587fd..8e7fe2a3 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -63,21 +63,8 @@ struct SiteBelPair SiteBelPair(std::string site, IdString bel) : site(site), bel(bel) {} bool operator==(const SiteBelPair &other) const { return site == other.site && bel == other.bel; } + unsigned int hash() const { return mkhash(std::hash()(site), bel.hash()); } }; -NEXTPNR_NAMESPACE_END - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX SiteBelPair &site_bel) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(site_bel.site)); - boost::hash_combine(seed, std::hash()(site_bel.bel)); - return seed; - } -}; - -NEXTPNR_NAMESPACE_BEGIN static std::pair split_identifier_name_dot(const std::string &name) { @@ -180,7 +167,7 @@ Arch::Arch(ArchArgs args) : args(args), disallow_site_routing(false) } } - std::unordered_set site_bel_pads; + pool site_bel_pads; for (const auto &package_pin : chip_info->packages[package_index].pins) { IdString site(package_pin.site); IdString bel(package_pin.bel); @@ -1951,7 +1938,7 @@ void Arch::unmask_bel_pins() void Arch::remove_site_routing() { - HashTables::HashSet wires_to_unbind; + pool wires_to_unbind; for (auto &net_pair : nets) { for (auto &wire_pair : net_pair.second->wires) { WireId wire = wire_pair.first; diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 5c7bbc52..c8a61430 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -103,14 +103,14 @@ struct Arch : ArchAPI // Guard initialization of "by_name" maps if accessed from multiple // threads on a "const Context *". mutable std::mutex by_name_mutex; - mutable std::unordered_map tile_by_name; - mutable std::unordered_map> site_by_name; + mutable dict tile_by_name; + mutable dict> site_by_name; - std::unordered_map wire_to_net; - std::unordered_map pip_to_net; + dict wire_to_net; + dict pip_to_net; DedicatedInterconnect dedicated_interconnect; - HashTables::HashMap tileStatus; + dict tileStatus; PseudoPipData pseudo_pip_data; ArchArgs args; @@ -685,8 +685,8 @@ struct Arch : ArchAPI // ------------------------------------------------- - void place_iobufs(WireId pad_wire, NetInfo *net, const std::unordered_set &tightly_attached_bels, - std::unordered_set *placed_cells); + void place_iobufs(WireId pad_wire, NetInfo *net, const pool &tightly_attached_bels, + pool *placed_cells); void pack_ports(); void decode_lut_cells(); @@ -858,7 +858,7 @@ struct Arch : ArchAPI IdString get_bel_tiletype(BelId bel) const { return IdString(loc_info(chip_info, bel).name); } - std::unordered_map sink_locs, source_locs; + dict sink_locs, source_locs; // ------------------------------------------------- void assignArchInfo() final {} @@ -875,8 +875,8 @@ struct Arch : ArchAPI void write_physical_netlist(const std::string &filename) const; void parse_xdc(const std::string &filename); - std::unordered_set io_port_types; - std::unordered_set pads; + pool io_port_types; + pool pads; bool is_site_port(PipId pip) const { @@ -1083,7 +1083,7 @@ struct Arch : ArchAPI IdString gnd_cell_pin; IdString vcc_cell_pin; std::vector> lut_elements; - std::unordered_map lut_cells; + dict lut_cells; // Of the LUT cells, which is used for wires? // Note: May be null in arch's without wire LUT types. Assumption is diff --git a/fpga_interchange/arch_pack_io.cc b/fpga_interchange/arch_pack_io.cc index 9322d028..fdbb1130 100644 --- a/fpga_interchange/arch_pack_io.cc +++ b/fpga_interchange/arch_pack_io.cc @@ -24,8 +24,8 @@ NEXTPNR_NAMESPACE_BEGIN -void Arch::place_iobufs(WireId pad_wire, NetInfo *net, const std::unordered_set &tightly_attached_bels, - std::unordered_set *placed_cells) +void Arch::place_iobufs(WireId pad_wire, NetInfo *net, const pool &tightly_attached_bels, + pool *placed_cells) { for (BelPin bel_pin : getWireBelPins(pad_wire)) { BelId bel = bel_pin.bel; @@ -57,7 +57,7 @@ void Arch::place_iobufs(WireId pad_wire, NetInfo *net, const std::unordered_set< void Arch::pack_ports() { - std::unordered_map tile_type_prototypes; + dict tile_type_prototypes; for (size_t i = 0; i < chip_info->tiles.size(); ++i) { const auto &tile = chip_info->tiles[i]; const auto &tile_type = chip_info->tile_types[tile.type]; @@ -66,9 +66,9 @@ void Arch::pack_ports() } // set(site_types) for package pins - std::unordered_set package_sites; + pool package_sites; // Package pin -> (Site type -> BelId) - std::unordered_map>> package_pin_bels; + dict>> package_pin_bels; for (const PackagePinPOD &package_pin : chip_info->packages[package_index].pins) { IdString pin(package_pin.package_pin); IdString bel(package_pin.bel); @@ -78,7 +78,7 @@ void Arch::pack_ports() for (size_t i = 0; i < chip_info->tiles.size(); ++i) { const auto &tile = chip_info->tiles[i]; - std::unordered_set package_pin_sites; + pool package_pin_sites; for (size_t j = 0; j < tile.sites.size(); ++j) { auto &site_data = chip_info->sites[tile.sites[j]]; if (site == id(site_data.site_name.get())) { @@ -102,8 +102,8 @@ void Arch::pack_ports() } // Determine for each package site type, which site types are possible. - std::unordered_set package_pin_site_types; - std::unordered_map> possible_package_site_types; + pool package_pin_site_types; + dict> possible_package_site_types; for (const TileInstInfoPOD &tile : chip_info->tiles) { for (size_t site_index : tile.sites) { const SiteInstInfoPOD &site = chip_info->sites[site_index]; @@ -121,7 +121,7 @@ void Arch::pack_ports() for (auto port_pair : port_cells) { IdString port_name = port_pair.first; CellInfo *port_cell = port_pair.second; - std::unordered_set tightly_attached_bels; + pool tightly_attached_bels; for (auto port_pair : port_cell->ports) { const PortInfo &port_info = port_pair.second; @@ -145,7 +145,7 @@ void Arch::pack_ports() } NPNR_ASSERT(tightly_attached_bels.erase(port_cell) == 1); - std::unordered_set cell_types_in_io_group; + pool cell_types_in_io_group; for (CellInfo *cell : tightly_attached_bels) { NPNR_ASSERT(port_cells.find(cell->name) == port_cells.end()); cell_types_in_io_group.emplace(cell->type); @@ -153,7 +153,7 @@ void Arch::pack_ports() // Get possible placement locations for tightly coupled BELs with // port. - std::unordered_set possible_site_types; + pool possible_site_types; for (const TileTypeInfoPOD &tile_type : chip_info->tile_types) { IdString tile_type_name(tile_type.name); for (const BelInfoPOD &bel_info : tile_type.bel_data) { @@ -195,7 +195,7 @@ void Arch::pack_ports() } } - // std::unordered_map> package_pin_bels; + // dict> package_pin_bels; IdString package_pin_id = id(iter->second.as_string()); auto pin_iter = package_pin_bels.find(package_pin_id); if (pin_iter == package_pin_bels.end()) { @@ -233,7 +233,7 @@ void Arch::pack_ports() log_info("Binding port %s to BEL %s\n", port_name.c_str(getCtx()), getCtx()->nameOfBel(package_bel)); } - std::unordered_set placed_cells; + pool placed_cells; bindBel(package_bel, port_cell, STRENGTH_FIXED); placed_cells.emplace(port_cell); diff --git a/fpga_interchange/archdefs.h b/fpga_interchange/archdefs.h index ba4fe054..2d27cccf 100644 --- a/fpga_interchange/archdefs.h +++ b/fpga_interchange/archdefs.h @@ -24,7 +24,6 @@ #include #include -#include "hash_table.h" #include "hashlib.h" #include "luts.h" #include "nextpnr_namespaces.h" @@ -119,9 +118,9 @@ struct ArchNetInfo struct ArchCellInfo { int32_t cell_mapping = -1; - HashTables::HashMap> cell_bel_pins; - HashTables::HashMap> masked_cell_bel_pins; - HashTables::HashSet const_ports; + dict> cell_bel_pins; + dict> masked_cell_bel_pins; + pool const_ports; LutCell lut_cell; }; diff --git a/fpga_interchange/cell_parameters.h b/fpga_interchange/cell_parameters.h index de82e76b..d6d4ccec 100644 --- a/fpga_interchange/cell_parameters.h +++ b/fpga_interchange/cell_parameters.h @@ -25,7 +25,6 @@ #include "chipdb.h" #include "dynamic_bitarray.h" -#include "hash_table.h" #include "nextpnr_namespaces.h" #include "property.h" @@ -42,7 +41,7 @@ struct CellParameters bool compare_property(const Context *ctx, IdString cell_type, IdString parameter, const Property &property, IdString value_to_compare) const; - HashTables::HashMap, const CellParameterPOD *, PairHash> parameters; + dict, const CellParameterPOD *> parameters; std::regex verilog_binary_re; std::regex verilog_hex_re; diff --git a/fpga_interchange/cost_map.cc b/fpga_interchange/cost_map.cc index 868fdca0..c20ba11b 100644 --- a/fpga_interchange/cost_map.cc +++ b/fpga_interchange/cost_map.cc @@ -121,7 +121,7 @@ delay_t CostMap::get_delay(const Context *ctx, WireId src_wire, WireId dst_wire) } void CostMap::set_cost_map(const Context *ctx, const TypeWirePair &wire_pair, - const HashTables::HashMap, delay_t, PairHash> &delays) + const dict, delay_t> &delays) { CostMapEntry delay_matrix; diff --git a/fpga_interchange/cost_map.h b/fpga_interchange/cost_map.h index 810d0198..88fb97e4 100644 --- a/fpga_interchange/cost_map.h +++ b/fpga_interchange/cost_map.h @@ -24,7 +24,6 @@ #include #include -#include "hash_table.h" #include "lookahead.capnp.h" #include "nextpnr_namespaces.h" #include "nextpnr_types.h" @@ -39,7 +38,7 @@ class CostMap public: delay_t get_delay(const Context *ctx, WireId src, WireId dst) const; void set_cost_map(const Context *ctx, const TypeWirePair &wire_pair, - const HashTables::HashMap, delay_t, PairHash> &delays); + const dict, delay_t> &delays); void from_reader(lookahead_storage::CostMap::Reader reader); void to_builder(lookahead_storage::CostMap::Builder builder) const; @@ -53,7 +52,7 @@ class CostMap }; std::mutex cost_map_mutex_; - HashTables::HashMap cost_map_; + dict cost_map_; void fill_holes(const Context *ctx, const TypeWirePair &wire_pair, boost::multi_array &matrix, delay_t delay_penality); diff --git a/fpga_interchange/dedicated_interconnect.cc b/fpga_interchange/dedicated_interconnect.cc index 9f7e83ab..2f6fbcd3 100644 --- a/fpga_interchange/dedicated_interconnect.cc +++ b/fpga_interchange/dedicated_interconnect.cc @@ -496,7 +496,7 @@ void DedicatedInterconnect::find_dedicated_interconnect() } } - std::unordered_set seen_pins; + pool seen_pins; for (auto sink_pair : sinks) { for (auto src : sink_pair.second) { seen_pins.emplace(src.type_bel_pin); @@ -558,7 +558,7 @@ void DedicatedInterconnect::expand_sink_bel(BelId sink_bel, IdString sink_pin, W nodes_to_expand.push_back(wire_node); Loc sink_loc = ctx->getBelLocation(sink_bel); - std::unordered_set srcs; + pool srcs; while (!nodes_to_expand.empty()) { WireNode node_to_expand = nodes_to_expand.back(); @@ -701,7 +701,7 @@ void DedicatedInterconnect::expand_source_bel(BelId src_bel, IdString src_pin, W nodes_to_expand.push_back(wire_node); Loc src_loc = ctx->getBelLocation(src_bel); - std::unordered_set dsts; + pool dsts; while (!nodes_to_expand.empty()) { WireNode node_to_expand = nodes_to_expand.back(); diff --git a/fpga_interchange/dedicated_interconnect.h b/fpga_interchange/dedicated_interconnect.h index 9ddb05fd..085ced26 100644 --- a/fpga_interchange/dedicated_interconnect.h +++ b/fpga_interchange/dedicated_interconnect.h @@ -23,9 +23,9 @@ #include #include -#include #include "archdefs.h" +#include "hashlib.h" #include "idstring.h" #include "nextpnr_namespaces.h" @@ -58,6 +58,7 @@ struct TileTypeBelPin { return tile_type != other.tile_type || bel_index != other.bel_index || bel_pin != other.bel_pin; } + unsigned int hash() const { return mkhash(mkhash(tile_type, bel_index), bel_pin.hash()); } }; struct DeltaTileTypeBelPin @@ -74,36 +75,9 @@ struct DeltaTileTypeBelPin { return delta_x != other.delta_x || delta_y != other.delta_y || type_bel_pin != other.type_bel_pin; } + unsigned int hash() const { return mkhash(mkhash(delta_x, delta_y), type_bel_pin.hash()); } }; -NEXTPNR_NAMESPACE_END - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX TileTypeBelPin &type_bel_pin) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(type_bel_pin.tile_type)); - boost::hash_combine(seed, std::hash()(type_bel_pin.bel_index)); - boost::hash_combine(seed, std::hash()(type_bel_pin.bel_pin)); - return seed; - } -}; - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DeltaTileTypeBelPin &delta_bel_pin) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(delta_bel_pin.delta_x)); - boost::hash_combine(seed, std::hash()(delta_bel_pin.delta_y)); - boost::hash_combine(seed, std::hash()(delta_bel_pin.type_bel_pin)); - return seed; - } -}; - -NEXTPNR_NAMESPACE_BEGIN - struct Context; // This class models dedicated interconnect present in the given fabric. @@ -123,8 +97,8 @@ struct DedicatedInterconnect { const Context *ctx; - std::unordered_map> sinks; - std::unordered_map> sources; + dict> sinks; + dict> sources; void init(const Context *ctx); diff --git a/fpga_interchange/fpga_interchange.cpp b/fpga_interchange/fpga_interchange.cpp index cf89ef1c..1d08b128 100644 --- a/fpga_interchange/fpga_interchange.cpp +++ b/fpga_interchange/fpga_interchange.cpp @@ -43,7 +43,7 @@ static void write_message(::capnp::MallocMessageBuilder & message, const std::st struct StringEnumerator { std::vector strings; - std::unordered_map string_to_index; + dict string_to_index; size_t get_index(const std::string &s) { auto result = string_to_index.emplace(s, strings.size()); @@ -59,7 +59,7 @@ struct StringEnumerator { static PhysicalNetlist::PhysNetlist::RouteBranch::Builder emit_branch( const Context * ctx, StringEnumerator * strings, - const std::unordered_map &pip_place_strength, + const dict &pip_place_strength, PipId pip, PhysicalNetlist::PhysNetlist::RouteBranch::Builder branch) { if(ctx->is_pip_synthetic(pip)) { @@ -264,10 +264,10 @@ static void init_bel_pin( static void emit_net( const Context * ctx, StringEnumerator * strings, - const std::unordered_map> &pip_downhill, - const std::unordered_map> &sinks, - std::unordered_set *pips, - const std::unordered_map &pip_place_strength, + const dict> &pip_downhill, + const dict> &sinks, + pool *pips, + const dict &pip_place_strength, WireId wire, PhysicalNetlist::PhysNetlist::RouteBranch::Builder branch) { size_t number_branches = 0; @@ -349,7 +349,7 @@ static PhysicalNetlist::PhysNetlist::RouteBranch::Builder init_local_source( StringEnumerator * strings, PhysicalNetlist::PhysNetlist::RouteBranch::Builder source_branch, PipId root, - const std::unordered_map &pip_place_strength, + const dict &pip_place_strength, WireId *root_wire) { WireId source_wire = ctx->getPipSrcWire(root); BelPin source_bel_pin = find_source(ctx, source_wire); @@ -365,7 +365,7 @@ static PhysicalNetlist::PhysNetlist::RouteBranch::Builder init_local_source( } static void find_non_synthetic_edges(const Context * ctx, WireId root_wire, - const std::unordered_map> &pip_downhill, + const dict> &pip_downhill, std::vector *root_pips) { std::vector wires_to_expand; @@ -403,7 +403,7 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str phys_netlist.setPart(ctx->get_part()); - std::unordered_set placed_cells; + pool placed_cells; for(const auto & cell_pair : ctx->cells) { const CellInfo & cell = *cell_pair.second; if(cell.bel == BelId()) { @@ -444,7 +444,7 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str std::vector ports; - std::unordered_map sites; + dict sites; auto placements = phys_netlist.initPlacements(number_placements); auto placement_iter = placements.begin(); @@ -556,9 +556,9 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str net_out.setName(strings.get_index(net.name.str(ctx))); } - std::unordered_map root_wires; - std::unordered_map> pip_downhill; - std::unordered_set pips; + dict root_wires; + dict> pip_downhill; + pool pips; if (driver_cell != nullptr && driver_cell->bel != BelId() && ctx->isBelLocationValid(driver_cell->bel)) { for(IdString bel_pin_name : driver_cell->cell_bel_pins.at(net.driver.port)) { @@ -573,7 +573,7 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str } } - std::unordered_map> sinks; + dict> sinks; for(const auto &port_ref : net.users) { if(port_ref.cell != nullptr && port_ref.cell->bel != BelId() && ctx->isBelLocationValid(port_ref.cell->bel)) { auto pin_iter = port_ref.cell->cell_bel_pins.find(port_ref.port); @@ -598,7 +598,7 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str } } - std::unordered_map pip_place_strength; + dict pip_place_strength; for(auto &wire_pair : net.wires) { WireId downhill_wire = wire_pair.first; @@ -723,23 +723,11 @@ struct PortKey { bool operator == (const PortKey &other) const { return inst_idx == other.inst_idx && port_idx == other.port_idx; } -}; - -NEXTPNR_NAMESPACE_END - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PortKey &key) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(key.inst_idx)); - boost::hash_combine(seed, std::hash()(key.port_idx)); - return seed; + unsigned int hash() const { + return mkhash(inst_idx, port_idx); } }; -NEXTPNR_NAMESPACE_BEGIN - struct ModuleReader { const LogicalNetlistImpl *root; @@ -748,9 +736,9 @@ struct ModuleReader { LogicalNetlist::Netlist::Cell::Reader cell; LogicalNetlist::Netlist::CellDeclaration::Reader cell_decl; - std::unordered_map net_indicies; - std::unordered_map disconnected_nets; - std::unordered_map> connections; + dict net_indicies; + dict disconnected_nets; + dict> connections; ModuleReader(const LogicalNetlistImpl *root, LogicalNetlist::Netlist::CellInstance::Reader cell_inst, bool is_top); @@ -834,7 +822,6 @@ struct LogicalNetlistImpl template void foreach_netname(const ModuleReader &mod, TFunc Func) const { - // std::unordered_map net_indicies; for(auto net_pair : mod.net_indicies) { NetReader net_reader(&mod, net_pair.first); auto net = net_pair.second; @@ -842,7 +829,6 @@ struct LogicalNetlistImpl Func(strings.at(net.getName()), net_reader); } - // std::unordered_map disconnected_nets; for(auto net_pair : mod.disconnected_nets) { NetReader net_reader(&mod, net_pair.first); Func(net_pair.second, net_reader); diff --git a/fpga_interchange/globals.cc b/fpga_interchange/globals.cc index 918b916e..ed9f73a6 100644 --- a/fpga_interchange/globals.cc +++ b/fpga_interchange/globals.cc @@ -67,7 +67,7 @@ static int route_global_arc(Context *ctx, NetInfo *net, size_t usr_idx, size_t p WireId startpoint; GlobalVist best_visit; std::queue visit_queue; - std::unordered_map visits; + dict visits; visit_queue.push(dest); visits[dest].downhill = PipId(); diff --git a/fpga_interchange/lookahead.cc b/fpga_interchange/lookahead.cc index 6dc8c43a..f1cb13e1 100644 --- a/fpga_interchange/lookahead.cc +++ b/fpga_interchange/lookahead.cc @@ -64,9 +64,9 @@ struct PipAndCost int32_t depth; }; -static void expand_input(const Context *ctx, WireId input_wire, HashTables::HashMap *input_costs) +static void expand_input(const Context *ctx, WireId input_wire, dict *input_costs) { - HashTables::HashSet seen; + pool seen; std::priority_queue to_expand; RoutingNode initial; @@ -120,9 +120,8 @@ static void expand_input(const Context *ctx, WireId input_wire, HashTables::Hash } } -static void update_site_to_site_costs(const Context *ctx, WireId first_wire, - const HashTables::HashMap &best_path, - HashTables::HashMap *site_to_site_cost) +static void update_site_to_site_costs(const Context *ctx, WireId first_wire, const dict &best_path, + dict *site_to_site_cost) { for (auto &best_pair : best_path) { WireId last_wire = best_pair.first; @@ -161,9 +160,9 @@ static void update_site_to_site_costs(const Context *ctx, WireId first_wire, } static void expand_output(const Context *ctx, WireId output_wire, Lookahead::OutputSiteWireCost *output_cost, - HashTables::HashMap *site_to_site_cost) + dict *site_to_site_cost) { - HashTables::HashSet seen; + pool seen; std::priority_queue to_expand; RoutingNode initial; @@ -172,7 +171,7 @@ static void expand_output(const Context *ctx, WireId output_wire, Lookahead::Out to_expand.push(initial); - HashTables::HashMap best_path; + dict best_path; while (!to_expand.empty()) { RoutingNode node = to_expand.top(); @@ -228,7 +227,7 @@ static void expand_output(const Context *ctx, WireId output_wire, Lookahead::Out static void expand_input_type(const Context *ctx, DeterministicRNG *rng, const Sampler &tiles_of_type, TypeWireId input_wire, std::vector *input_costs) { - HashTables::HashMap input_costs_map; + dict input_costs_map; for (size_t region = 0; region < tiles_of_type.number_of_regions(); ++region) { size_t tile = tiles_of_type.get_sample_from_region(region, [rng]() -> int32_t { return rng->rng(); }); @@ -250,7 +249,7 @@ static void expand_input_type(const Context *ctx, DeterministicRNG *rng, const S struct DelayStorage { - HashTables::HashMap, delay_t, PairHash>> storage; + dict, delay_t>> storage; int32_t max_explore_depth; }; @@ -290,7 +289,7 @@ static void update_results(const Context *ctx, const FlatWireMap &be // Starting from end of result, walk backwards and record the path into // the delay storage. WireId cursor = sink_wire; - HashTables::HashSet seen; + pool seen; while (cursor != src_wire) { // No loops allowed in routing! auto result = seen.emplace(cursor); @@ -335,7 +334,7 @@ static void update_results(const Context *ctx, const FlatWireMap &be static void expand_routing_graph_from_wire(const Context *ctx, WireId first_wire, FlatWireMap *best_path, DelayStorage *storage) { - HashTables::HashSet seen; + pool seen; std::priority_queue to_expand; int src_tile; @@ -436,11 +435,10 @@ static bool has_multiple_outputs(const Context *ctx, WireId wire) } static void expand_routing_graph(const Context *ctx, DeterministicRNG *rng, const Sampler &tiles_of_type, - TypeWireId wire_type, HashTables::HashSet *types_explored, - DelayStorage *storage, HashTables::HashSet *types_deferred, - FlatWireMap *best_path) + TypeWireId wire_type, pool *types_explored, DelayStorage *storage, + pool *types_deferred, FlatWireMap *best_path) { - HashTables::HashSet new_types_explored; + pool new_types_explored; for (size_t region = 0; region < tiles_of_type.number_of_regions(); ++region) { size_t tile = tiles_of_type.get_sample_from_region(region, [rng]() -> int32_t { return rng->rng(); }); @@ -562,10 +560,10 @@ static WireId follow_pip_chain_up(const Context *ctx, WireId wire, delay_t *dela } static void expand_deferred_routing_graph(const Context *ctx, DeterministicRNG *rng, const Sampler &tiles_of_type, - TypeWireId wire_type, HashTables::HashSet *types_explored, + TypeWireId wire_type, pool *types_explored, DelayStorage *storage, FlatWireMap *best_path) { - HashTables::HashSet new_types_explored; + pool new_types_explored; for (size_t region = 0; region < tiles_of_type.number_of_regions(); ++region) { size_t tile = tiles_of_type.get_sample_from_region(region, [rng]() -> int32_t { return rng->rng(); }); @@ -603,7 +601,7 @@ static void expand_deferred_routing_graph(const Context *ctx, DeterministicRNG * static void expand_output_type(const Context *ctx, DeterministicRNG *rng, const Sampler &tiles_of_type, TypeWireId output_wire, Lookahead::OutputSiteWireCost *output_cost, - HashTables::HashMap *site_to_site_cost) + dict *site_to_site_cost) { for (size_t region = 0; region < tiles_of_type.number_of_regions(); ++region) { size_t tile = tiles_of_type.get_sample_from_region(region, [rng]() -> int32_t { return rng->rng(); }); @@ -651,8 +649,8 @@ struct ExpandLocals DeterministicRNG *rng; FlatWireMap *best_path; DelayStorage *storage; - HashTables::HashSet *explored; - HashTables::HashSet *deferred; + pool *explored; + pool *deferred; virtual void lock() {} virtual void unlock() {} @@ -698,8 +696,7 @@ static void expand_tile_type(const Context *ctx, int32_t tile_type, ExpandLocals static void expand_tile_type_serial(const Context *ctx, const std::vector &tile_types, const std::vector &tiles_of_type, DeterministicRNG *rng, FlatWireMap *best_path, DelayStorage *storage, - HashTables::HashSet *explored, - HashTables::HashSet *deferred, HashTables::HashSet *tiles_left) + pool *explored, pool *deferred, pool *tiles_left) { for (int32_t tile_type : tile_types) { @@ -725,9 +722,9 @@ struct TbbExpandLocals : public ExpandLocals std::mutex *all_costs_mutex; DelayStorage *all_tiles_storage; - HashTables::HashSet *types_explored; - HashTables::HashSet *types_deferred; - HashTables::HashSet *tiles_left; + pool *types_explored; + pool *types_deferred; + pool *tiles_left; void lock() override { all_costs_mutex->lock(); } @@ -785,16 +782,15 @@ struct TbbExpandLocals : public ExpandLocals // the data is joined with the global data. static void expand_tile_type_parallel(const Context *ctx, int32_t tile_type, const std::vector &tiles_of_type, DeterministicRNG *rng, std::mutex *all_costs_mutex, - DelayStorage *all_tiles_storage, HashTables::HashSet *types_explored, - HashTables::HashSet *types_deferred, - HashTables::HashSet *tiles_left) + DelayStorage *all_tiles_storage, pool *types_explored, + pool *types_deferred, pool *tiles_left) { TbbExpandLocals locals; DeterministicRNG rng_copy = *rng; FlatWireMap best_path(ctx); - HashTables::HashSet explored; - HashTables::HashSet deferred; + pool explored; + pool deferred; DelayStorage storage; storage.max_explore_depth = all_tiles_storage->max_explore_depth; @@ -823,7 +819,7 @@ void Lookahead::build_lookahead(const Context *ctx, DeterministicRNG *rng) log_info("Building lookahead, first gathering input and output site wires\n"); } - HashTables::HashSet input_site_ports; + pool input_site_ports; for (BelId bel : ctx->getBels()) { const auto &bel_data = bel_info(ctx->chip_info, bel); @@ -917,15 +913,15 @@ void Lookahead::build_lookahead(const Context *ctx, DeterministicRNG *rng) all_tiles_storage.max_explore_depth = kInitialExploreDepth; // These are wire types that have been explored. - HashTables::HashSet types_explored; + pool types_explored; // These are wire types that have been deferred because they are trival // copies of another wire type. These can be cheaply computed after the // graph has been explored. - HashTables::HashSet types_deferred; + pool types_deferred; std::vector tile_types; - HashTables::HashSet tiles_left; + pool tiles_left; tile_types.reserve(ctx->chip_info->tile_types.size()); for (int32_t tile_type = 0; tile_type < ctx->chip_info->tile_types.ssize(); ++tile_type) { tile_types.push_back(tile_type); @@ -994,16 +990,14 @@ void Lookahead::build_lookahead(const Context *ctx, DeterministicRNG *rng) } #if defined(NEXTPNR_USE_TBB) // Run parallely - tbb::parallel_for_each( - all_tiles_storage.storage, - [&](const std::pair, delay_t, PairHash>> - &type_pair) { + tbb::parallel_for_each(all_tiles_storage.storage, + [&](const std::pair, delay_t>> &type_pair) { #else for (const auto &type_pair : all_tiles_storage.storage) { #endif - cost_map.set_cost_map(ctx, type_pair.first, type_pair.second); + cost_map.set_cost_map(ctx, type_pair.first, type_pair.second); #if defined(NEXTPNR_USE_TBB) // Run parallely - }); + }); #else } #endif diff --git a/fpga_interchange/lookahead.h b/fpga_interchange/lookahead.h index b9d352d5..9655e13e 100644 --- a/fpga_interchange/lookahead.h +++ b/fpga_interchange/lookahead.h @@ -26,7 +26,6 @@ #include "cost_map.h" #include "deterministic_rng.h" -#include "hash_table.h" #include "lookahead.capnp.h" #include "nextpnr_namespaces.h" #include "type_wire.h" @@ -88,9 +87,9 @@ struct Lookahead delay_t cost; }; - HashTables::HashMap> input_site_wires; - HashTables::HashMap output_site_wires; - HashTables::HashMap site_to_site_cost; + dict> input_site_wires; + dict output_site_wires; + dict site_to_site_cost; CostMap cost_map; }; diff --git a/fpga_interchange/luts.cc b/fpga_interchange/luts.cc index 882cc474..0156d379 100644 --- a/fpga_interchange/luts.cc +++ b/fpga_interchange/luts.cc @@ -166,13 +166,13 @@ uint32_t LutMapper::check_wires(const Context *ctx) const } } - HashTables::HashSet blocked_luts; + pool blocked_luts; return check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins, &blocked_luts); } uint32_t LutMapper::check_wires(const std::vector> &bel_to_cell_pin_remaps, const std::vector &lut_bels, uint32_t used_pins, - HashTables::HashSet *blocked_luts) const + pool *blocked_luts) const { std::vector unused_luts; for (auto &lut_bel_pair : element.lut_bels) { @@ -253,9 +253,9 @@ uint32_t LutMapper::check_wires(const std::vector> &bel_to_ return vcc_mask; } -bool LutMapper::remap_luts(const Context *ctx, HashTables::HashSet *blocked_luts) +bool LutMapper::remap_luts(const Context *ctx, pool *blocked_luts) { - std::unordered_map lut_pin_map; + dict lut_pin_map; std::vector lut_bels; lut_bels.resize(cells.size()); @@ -366,7 +366,7 @@ bool LutMapper::remap_luts(const Context *ctx, HashTables::HashSet cell_to_bel_map; + dict cell_to_bel_map; for (size_t pin_idx = 0; pin_idx < cell->lut_cell.pins.size(); ++pin_idx) { size_t bel_pin_idx = cell_to_bel_pin_remaps[cell_idx][pin_idx]; NPNR_ASSERT(bel_pin_idx < lut_bel.pins.size()); @@ -452,8 +452,8 @@ bool LutMapper::remap_luts(const Context *ctx, HashTables::HashSet &cell_to_bel_map, - const LutBel &lut_bel, const std::vector &equation, uint32_t used_pins) +void check_equation(const LutCell &lut_cell, const dict &cell_to_bel_map, const LutBel &lut_bel, + const std::vector &equation, uint32_t used_pins) { std::vector pin_map; pin_map.resize(lut_bel.pins.size(), -1); diff --git a/fpga_interchange/luts.h b/fpga_interchange/luts.h index df0ac124..cbb817c9 100644 --- a/fpga_interchange/luts.h +++ b/fpga_interchange/luts.h @@ -20,14 +20,11 @@ #ifndef LUTS_H #define LUTS_H -#include -#include - #include "idstring.h" #include "nextpnr_namespaces.h" #include "dynamic_bitarray.h" -#include "hash_table.h" +#include "hashlib.h" NEXTPNR_NAMESPACE_BEGIN @@ -45,8 +42,8 @@ struct LutCell { // LUT cell pins for equation, LSB first. std::vector pins; - std::unordered_set lut_pins; - std::unordered_set vcc_pins; + pool lut_pins; + pool vcc_pins; DynamicBitarray<> equation; }; @@ -56,7 +53,7 @@ struct LutBel // LUT BEL pins to LUT array index. std::vector pins; - std::unordered_map pin_to_index; + dict pin_to_index; IdString output_pin; @@ -71,18 +68,18 @@ struct LutBel // Work forward from cell definition and cell -> bel pin map and check that // equation is valid. -void check_equation(const LutCell &lut_cell, const std::unordered_map &cell_to_bel_map, - const LutBel &lut_bel, const std::vector &equation, uint32_t used_pins); +void check_equation(const LutCell &lut_cell, const dict &cell_to_bel_map, const LutBel &lut_bel, + const std::vector &equation, uint32_t used_pins); struct LutElement { size_t width; - std::unordered_map lut_bels; + dict lut_bels; void compute_pin_order(); std::vector pins; - std::unordered_map pin_to_index; + dict pin_to_index; }; struct LutMapper @@ -92,7 +89,7 @@ struct LutMapper std::vector cells; - bool remap_luts(const Context *ctx, HashTables::HashSet *blocked_luts); + bool remap_luts(const Context *ctx, pool *blocked_luts); // Determine which wires given the current mapping must be tied to the // default constant. @@ -101,7 +98,7 @@ struct LutMapper // the pin is free to be a signal. uint32_t check_wires(const std::vector> &bel_to_cell_pin_remaps, const std::vector &lut_bels, uint32_t used_pins, - HashTables::HashSet *blocked_luts) const; + pool *blocked_luts) const; // Version of check_wires that uses current state of cells based on pin // mapping in cells variable. diff --git a/fpga_interchange/pseudo_pip_model.cc b/fpga_interchange/pseudo_pip_model.cc index 64da4548..2441c8a9 100644 --- a/fpga_interchange/pseudo_pip_model.cc +++ b/fpga_interchange/pseudo_pip_model.cc @@ -44,7 +44,7 @@ void PseudoPipData::init_tile_type(const Context *ctx, int32_t tile_type) max_pseudo_pip_index = pip_idx; } - HashTables::HashSet sites; + pool sites; std::vector pseudo_pip_bels; for (int32_t wire_index : pip_data.pseudo_cell_wires) { const TileWireInfoPOD &wire_data = type_data.wire_data[wire_index]; @@ -122,7 +122,7 @@ void PseudoPipData::init_tile_type(const Context *ctx, int32_t tile_type) } if (!pseudo_pip_bels.empty()) { - HashTables::HashSet pseudo_cell_wires; + pool pseudo_cell_wires; pseudo_cell_wires.insert(pip_data.pseudo_cell_wires.begin(), pip_data.pseudo_cell_wires.end()); // For each BEL, find the input bel pin used, and attach it to @@ -195,7 +195,7 @@ void PseudoPipModel::prepare_for_routing(const Context *ctx, const std::vector active_sites; + pool active_sites; for (size_t site = 0; site < sites.size(); ++site) { if (!sites[site].cells_in_site.empty()) { active_sites.emplace(site); @@ -309,7 +309,7 @@ void PseudoPipModel::update_site(const Context *ctx, size_t site) unused_pseudo_pips.clear(); unused_pseudo_pips.reserve(pseudo_pips_for_site.size()); - HashTables::HashMap used_bels; + dict used_bels; for (int32_t pseudo_pip : pseudo_pips_for_site) { if (!active_pseudo_pips.count(pseudo_pip)) { unused_pseudo_pips.push_back(pseudo_pip); diff --git a/fpga_interchange/pseudo_pip_model.h b/fpga_interchange/pseudo_pip_model.h index 1e79071d..b0e28059 100644 --- a/fpga_interchange/pseudo_pip_model.h +++ b/fpga_interchange/pseudo_pip_model.h @@ -24,7 +24,6 @@ #include #include "dynamic_bitarray.h" -#include "hash_table.h" #include "nextpnr_namespaces.h" #include "nextpnr_types.h" #include "site_router.h" @@ -58,28 +57,10 @@ struct LogicBelKey bool operator==(const LogicBelKey &other) const { return make_tuple() == other.make_tuple(); } bool operator<(const LogicBelKey &other) const { return make_tuple() < other.make_tuple(); } -}; - -NEXTPNR_NAMESPACE_END -namespace std { -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX LogicBelKey &key) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, hash()(key.tile_type)); - boost::hash_combine(seed, hash()(key.pip_index)); - boost::hash_combine(seed, hash()(key.site)); - - return seed; - } + unsigned int hash() const { return mkhash(mkhash(tile_type, pip_index), site); } }; -}; // namespace std - -NEXTPNR_NAMESPACE_BEGIN - // Storage for tile type generic pseudo pip data and lookup. struct PseudoPipData { @@ -97,9 +78,9 @@ struct PseudoPipData // This does **not** include site ports or site pips. const std::vector &get_logic_bels_for_pip(const Context *ctx, int32_t site, PipId pip) const; - HashTables::HashMap max_pseudo_pip_for_tile_type; - HashTables::HashMap, std::vector, PairHash> possibles_sites_for_pip; - HashTables::HashMap> logic_bels_for_pip; + dict max_pseudo_pip_for_tile_type; + dict, std::vector> possibles_sites_for_pip; + dict> logic_bels_for_pip; }; // Tile instance fast pseudo pip lookup. @@ -107,9 +88,9 @@ struct PseudoPipModel { int32_t tile; DynamicBitarray<> allowed_pseudo_pips; - HashTables::HashMap pseudo_pip_sites; - HashTables::HashMap> site_to_pseudo_pips; - HashTables::HashSet active_pseudo_pips; + dict pseudo_pip_sites; + dict> site_to_pseudo_pips; + pool active_pseudo_pips; std::vector scratch; // Call when a tile is initialized. diff --git a/fpga_interchange/site_arch.cc b/fpga_interchange/site_arch.cc index ed2f6c8d..6398d858 100644 --- a/fpga_interchange/site_arch.cc +++ b/fpga_interchange/site_arch.cc @@ -24,7 +24,7 @@ NEXTPNR_NAMESPACE_BEGIN SiteInformation::SiteInformation(const Context *ctx, int32_t tile, int32_t site, - const std::unordered_set &cells_in_site) + const pool &cells_in_site) : ctx(ctx), tile(tile), tile_type(ctx->chip_info->tiles[tile].type), site(site), cells_in_site(cells_in_site) { } diff --git a/fpga_interchange/site_arch.h b/fpga_interchange/site_arch.h index a7da5c68..54b91a4a 100644 --- a/fpga_interchange/site_arch.h +++ b/fpga_interchange/site_arch.h @@ -22,13 +22,12 @@ #define SITE_ARCH_H #include -#include #include #include "PhysicalNetlist.capnp.h" #include "arch_iterators.h" #include "chipdb.h" -#include "hash_table.h" +#include "hashlib.h" #include "log.h" #include "nextpnr_namespaces.h" #include "nextpnr_types.h" @@ -44,10 +43,10 @@ struct SiteInformation const int32_t tile; const int32_t tile_type; const int32_t site; - const std::unordered_set &cells_in_site; + const pool &cells_in_site; SiteInformation(const Context *ctx, int32_t tile, int32_t site, - const std::unordered_set &cells_in_site); + const pool &cells_in_site); inline const ChipInfoPOD &chip_info() const NPNR_ALWAYS_INLINE; @@ -143,6 +142,7 @@ struct SiteWire WireId wire; PipId pip; NetInfo *net = nullptr; + unsigned int hash() const { return mkhash(mkhash(int(type), wire.hash()), mkhash(pip.hash(), uintptr_t(net))); } }; struct SitePip @@ -214,36 +214,8 @@ struct SitePip { return type != other.type || pip != other.pip || wire != other.wire || other_pip != other.other_pip; } + unsigned int hash() const { return mkhash(mkhash(int(type), pip.hash()), mkhash(wire.hash(), other_pip.hash())); } }; -NEXTPNR_NAMESPACE_END - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX SiteWire &site_wire) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(site_wire.type)); - boost::hash_combine(seed, std::hash()(site_wire.wire)); - boost::hash_combine(seed, std::hash()(site_wire.pip)); - boost::hash_combine(seed, std::hash()(site_wire.net)); - return seed; - } -}; - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX SitePip &site_pip) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(site_pip.type)); - boost::hash_combine(seed, std::hash()(site_pip.pip)); - boost::hash_combine(seed, std::hash()(site_pip.wire)); - boost::hash_combine(seed, std::hash()(site_pip.other_pip)); - return seed; - } -}; - -NEXTPNR_NAMESPACE_BEGIN struct SitePipDownhillRange; struct SitePipUphillRange; @@ -266,9 +238,9 @@ struct SiteNetInfo { NetInfo *net; SiteWire driver; - HashTables::HashSet users; + pool users; - HashTables::HashMap wires; + dict wires; }; struct SiteArch @@ -276,8 +248,8 @@ struct SiteArch const Context *const ctx; const SiteInformation *const site_info; - HashTables::HashMap nets; - HashTables::HashMap wire_to_nets; + dict nets; + dict wire_to_nets; NetInfo blocking_net; SiteNetInfo blocking_site_net; diff --git a/fpga_interchange/site_router.cc b/fpga_interchange/site_router.cc index 69bd366f..090b9342 100644 --- a/fpga_interchange/site_router.cc +++ b/fpga_interchange/site_router.cc @@ -21,7 +21,6 @@ #include "design_utils.h" #include "dynamic_bitarray.h" -#include "hash_table.h" #include "log.h" #include "site_routing_cache.h" @@ -53,7 +52,7 @@ bool check_initial_wires(const Context *ctx, SiteInformation *site_info) { // Propagate from BEL pins to first wire, checking for trivial routing // conflicts. - HashTables::HashMap wires; + dict wires; for (CellInfo *cell : site_info->cells_in_site) { BelId bel = cell->bel; @@ -132,7 +131,7 @@ struct SiteExpansionLoop bool expand_result; SiteWire net_driver; - HashTables::HashSet net_users; + pool net_users; SiteRoutingSolution solution; @@ -206,7 +205,7 @@ struct SiteExpansionLoop auto node = new_node(net->driver, SitePip(), /*parent=*/nullptr); - HashTables::HashSet targets; + pool targets; targets.insert(net->users.begin(), net->users.end()); if (verbose_site_router(ctx)) { @@ -722,7 +721,7 @@ static bool route_site(SiteArch *ctx, SiteRoutingCache *site_routing_cache, Rout // Create a flat sink list and map. std::vector sinks; - HashTables::HashMap sink_map; + dict sink_map; size_t number_solutions = 0; for (const auto *expansion : expansions) { number_solutions += expansion->num_solutions(); @@ -963,8 +962,7 @@ static void apply_constant_routing(Context *ctx, const SiteArch &site_arch, NetI } } -static void apply_routing(Context *ctx, const SiteArch &site_arch, - HashTables::HashSet, PairHash> &lut_thrus) +static void apply_routing(Context *ctx, const SiteArch &site_arch, pool> &lut_thrus) { IdString gnd_net_name(ctx->chip_info->constants->gnd_net_name); NetInfo *gnd_net = ctx->nets.at(gnd_net_name).get(); @@ -1019,8 +1017,7 @@ static void apply_routing(Context *ctx, const SiteArch &site_arch, } } -static bool map_luts_in_site(const SiteInformation &site_info, - HashTables::HashSet, PairHash> *blocked_wires) +static bool map_luts_in_site(const SiteInformation &site_info, pool> *blocked_wires) { const Context *ctx = site_info.ctx; const std::vector &lut_elements = ctx->lut_elements.at(site_info.tile_type); @@ -1048,7 +1045,7 @@ static bool map_luts_in_site(const SiteInformation &site_info, continue; } - HashTables::HashSet blocked_luts; + pool blocked_luts; if (!lut_mapper.remap_luts(ctx, &blocked_luts)) { return false; } @@ -1062,8 +1059,7 @@ static bool map_luts_in_site(const SiteInformation &site_info, } // Block outputs of unavailable LUTs to prevent site router from using them. -static void block_lut_outputs(SiteArch *site_arch, - const HashTables::HashSet, PairHash> &blocked_wires) +static void block_lut_outputs(SiteArch *site_arch, const pool> &blocked_wires) { const Context *ctx = site_arch->site_info->ctx; auto &tile_info = ctx->chip_info->tile_types[site_arch->site_info->tile_type]; @@ -1185,7 +1181,7 @@ bool SiteRouter::checkSiteRouting(const Context *ctx, const TileStatus &tile_sta } SiteInformation site_info(ctx, tile, site, cells_in_site); - HashTables::HashSet, PairHash> blocked_wires; + pool> blocked_wires; if (!map_luts_in_site(site_info, &blocked_wires)) { site_ok = false; return site_ok; @@ -1263,7 +1259,7 @@ void SiteRouter::bindSiteRouting(Context *ctx) } SiteInformation site_info(ctx, tile, site, cells_in_site); - HashTables::HashSet, PairHash> blocked_wires; + pool> blocked_wires; NPNR_ASSERT(map_luts_in_site(site_info, &blocked_wires)); SiteArch site_arch(&site_info); diff --git a/fpga_interchange/site_router.h b/fpga_interchange/site_router.h index 0328b6b2..ad1cbf66 100644 --- a/fpga_interchange/site_router.h +++ b/fpga_interchange/site_router.h @@ -23,6 +23,7 @@ #include +#include "hashlib.h" #include "nextpnr_namespaces.h" #include "nextpnr_types.h" #include "site_arch.h" @@ -37,9 +38,9 @@ struct SiteRouter { SiteRouter(int16_t site) : site(site), dirty(false), site_ok(true) {} - std::unordered_set cells_in_site; + pool cells_in_site; std::vector valid_pips; - HashTables::HashSet, PairHash> lut_thrus; + pool> lut_thrus; const int16_t site; mutable bool dirty; diff --git a/fpga_interchange/site_routing_cache.cc b/fpga_interchange/site_routing_cache.cc index e6f4dc70..512ca2ac 100644 --- a/fpga_interchange/site_routing_cache.cc +++ b/fpga_interchange/site_routing_cache.cc @@ -70,7 +70,7 @@ void SiteRoutingSolution::store_solution(const SiteArch *ctx, const RouteNodeSto void SiteRoutingSolution::verify(const SiteArch *ctx, const SiteNetInfo &net) { - HashTables::HashSet seen_users; + pool seen_users; for (size_t i = 0; i < num_solutions(); ++i) { SiteWire cursor = solution_sink(i); NPNR_ASSERT(net.users.count(cursor) == 1); diff --git a/fpga_interchange/site_routing_cache.h b/fpga_interchange/site_routing_cache.h index 6ad218c7..b4baf65a 100644 --- a/fpga_interchange/site_routing_cache.h +++ b/fpga_interchange/site_routing_cache.h @@ -22,7 +22,6 @@ #define SITE_ROUTING_CACHE_H #include "PhysicalNetlist.capnp.h" -#include "hash_table.h" #include "nextpnr_namespaces.h" #include "site_arch.h" #include "site_routing_storage.h" @@ -97,35 +96,25 @@ struct SiteRoutingKey } static SiteRoutingKey make(const SiteArch *ctx, const SiteNetInfo &site_net); -}; - -NEXTPNR_NAMESPACE_END -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX SiteRoutingKey &key) const noexcept + unsigned int hash() const { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(key.tile_type)); - boost::hash_combine(seed, std::hash()(key.site)); - boost::hash_combine(seed, std::hash()(key.net_type)); - boost::hash_combine(seed, std::hash()(key.driver_type)); - boost::hash_combine(seed, std::hash()(key.driver_index)); - boost::hash_combine(seed, std::hash()(key.user_types.size())); - for (NEXTPNR_NAMESPACE_PREFIX SiteWire::Type user_type : key.user_types) { - boost::hash_combine(seed, std::hash()(user_type)); - } - - boost::hash_combine(seed, std::hash()(key.user_indicies.size())); - for (int32_t index : key.user_indicies) { - boost::hash_combine(seed, std::hash()(index)); - } + unsigned int seed = 0; + seed = mkhash(seed, tile_type); + seed = mkhash(seed, site); + seed = mkhash(seed, int(net_type)); + seed = mkhash(seed, int(driver_type)); + seed = mkhash(seed, driver_index); + seed = mkhash(seed, user_types.size()); + for (auto t : user_types) + seed = mkhash(seed, int(t)); + seed = mkhash(seed, user_indicies.size()); + for (auto i : user_indicies) + seed = mkhash(seed, i); return seed; } }; -NEXTPNR_NAMESPACE_BEGIN - // Provides an LRU cache for site routing solutions. class SiteRoutingCache { @@ -134,7 +123,7 @@ class SiteRoutingCache void add_solutions(const SiteArch *ctx, const SiteNetInfo &net, const SiteRoutingSolution &solution); private: - HashTables::HashMap cache_; + dict cache_; }; NEXTPNR_NAMESPACE_END diff --git a/fpga_interchange/type_wire.cc b/fpga_interchange/type_wire.cc index a08e024b..d1bdaed0 100644 --- a/fpga_interchange/type_wire.cc +++ b/fpga_interchange/type_wire.cc @@ -54,10 +54,9 @@ TypeWireSet::TypeWireSet(const Context *ctx, WireId wire) std::sort(wire_types_.begin(), wire_types_.end()); - hash_ = 0; - boost::hash_combine(hash_, std::hash()(wire_types_.size())); + hash_ = wire_types_.size(); for (const auto &wire : wire_types_) { - boost::hash_combine(hash_, std::hash()(wire)); + hash_ = mkhash(hash_, wire.hash()); } } diff --git a/fpga_interchange/type_wire.h b/fpga_interchange/type_wire.h index f2a675ef..a472bccc 100644 --- a/fpga_interchange/type_wire.h +++ b/fpga_interchange/type_wire.h @@ -24,6 +24,7 @@ #include #include +#include "hashlib.h" #include "nextpnr_namespaces.h" #include "nextpnr_types.h" @@ -48,6 +49,8 @@ struct TypeWireId return type < other.type || (type == other.type && index < other.index); } + unsigned int hash() const { return mkhash(type, index); } + int32_t type; int32_t index; }; @@ -63,49 +66,24 @@ struct TypeWirePair bool operator==(const TypeWirePair &other) const { return src == other.src && dst == other.dst; } bool operator!=(const TypeWirePair &other) const { return src != other.src || dst != other.dst; } + + unsigned int hash() const { return mkhash(src.hash(), dst.hash()); } }; struct TypeWireSet { public: TypeWireSet(const Context *ctx, WireId wire); - std::size_t hash() const { return hash_; } + unsigned int hash() const { return hash_; } bool operator==(const TypeWireSet &other) const { return wire_types_ == other.wire_types_; } bool operator!=(const TypeWireSet &other) const { return wire_types_ != other.wire_types_; } private: - std::size_t hash_; + unsigned int hash_; std::vector wire_types_; }; NEXTPNR_NAMESPACE_END -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX TypeWireId &wire) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(wire.type)); - boost::hash_combine(seed, std::hash()(wire.index)); - return seed; - } -}; - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX TypeWirePair &pair) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, std::hash()(pair.src)); - boost::hash_combine(seed, std::hash()(pair.dst)); - return seed; - } -}; - -template <> struct std::hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX TypeWireSet &set) const noexcept { return set.hash(); } -}; - #endif /* TYPE_WIRE_H */ diff --git a/generic/arch.h b/generic/arch.h index 50d2731c..9b16d873 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -80,7 +80,7 @@ struct BelInfo IdString type; std::map attrs; CellInfo *bound_cell; - std::unordered_map pins; + dict pins; DecalXY decalxy; int x, y, z; bool gb; @@ -101,27 +101,14 @@ struct CellDelayKey { IdString from, to; inline bool operator==(const CellDelayKey &other) const { return from == other.from && to == other.to; } + unsigned int hash() const { return mkhash(from.hash(), to.hash()); } }; -NEXTPNR_NAMESPACE_END -namespace std { -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX CellDelayKey &dk) const noexcept - { - std::size_t seed = std::hash()(dk.from); - seed ^= std::hash()(dk.to) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } -}; -} // namespace std -NEXTPNR_NAMESPACE_BEGIN - struct CellTiming { - std::unordered_map portClasses; - std::unordered_map combDelays; - std::unordered_map> clockingInfo; + dict portClasses; + dict combDelays; + dict> clockingInfo; }; struct ArchRanges @@ -160,10 +147,10 @@ struct Arch : ArchAPI { std::string chipName; - std::unordered_map wires; - std::unordered_map pips; - std::unordered_map bels; - std::unordered_map groups; + dict wires; + dict pips; + dict bels; + dict groups; // These functions include useful errors if not found WireInfo &wire_info(IdStringList wire); @@ -172,16 +159,16 @@ struct Arch : ArchAPI std::vector bel_ids, wire_ids, pip_ids; - std::unordered_map bel_by_loc; + dict bel_by_loc; std::vector>> bels_by_tile; - std::unordered_map> decal_graphics; + dict> decal_graphics; int gridDimX, gridDimY; std::vector> tileBelDimZ; std::vector> tilePipDimZ; - std::unordered_map cellTiming; + dict cellTiming; void addWire(IdStringList name, IdString type, int x, int y); void addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, delay_t delay, Loc loc); @@ -318,7 +305,7 @@ struct Arch : ArchAPI std::vector getCellTypes() const override { - std::unordered_set cell_types; + pool cell_types; for (auto bel : bels) { cell_types.insert(bel.second.type); } diff --git a/generic/archdefs.h b/generic/archdefs.h index 0489ab04..06680cc1 100644 --- a/generic/archdefs.h +++ b/generic/archdefs.h @@ -20,8 +20,7 @@ #ifndef GENERIC_ARCHDEFS_H #define GENERIC_ARCHDEFS_H -#include - +#include "hashlib.h" #include "idstringlist.h" NEXTPNR_NAMESPACE_BEGIN @@ -52,7 +51,7 @@ struct ArchCellInfo // Only packing rule for slice type primitives is a single clock per tile const NetInfo *slice_clk; // Cell to bel pin mapping - std::unordered_map> bel_pins; + dict> bel_pins; }; NEXTPNR_NAMESPACE_END diff --git a/generic/cells.cc b/generic/cells.cc index c4421f90..e1892353 100644 --- a/generic/cells.cc +++ b/generic/cells.cc @@ -106,7 +106,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l replace_port(dff, ctx->id("Q"), lc, ctx->id("Q")); } -void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set &todelete_cells) +void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, pool &todelete_cells) { if (nxio->type == ctx->id("$nextpnr_ibuf")) { iob->params[ctx->id("INPUT_USED")] = 1; diff --git a/generic/cells.h b/generic/cells.h index 646d738d..7a8443c5 100644 --- a/generic/cells.h +++ b/generic/cells.h @@ -48,7 +48,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = tr void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false); // Convert a nextpnr IO buffer to a GENERIC_IOB -void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells); +void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool &todelete_cells); NEXTPNR_NAMESPACE_END diff --git a/generic/pack.cc b/generic/pack.cc index a1c325f8..dba86cce 100644 --- a/generic/pack.cc +++ b/generic/pack.cc @@ -19,7 +19,6 @@ #include #include -#include #include "cells.h" #include "design_utils.h" #include "log.h" @@ -32,7 +31,7 @@ static void pack_lut_lutffs(Context *ctx) { log_info("Packing LUT-FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); @@ -89,7 +88,7 @@ static void pack_nonlut_ffs(Context *ctx) { log_info("Packing non-LUT FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { @@ -203,8 +202,8 @@ static bool is_generic_iob(const Context *ctx, const CellInfo *cell) { return ce // Pack IO buffers static void pack_io(Context *ctx) { - std::unordered_set packed_cells; - std::unordered_set delete_nets; + pool packed_cells; + pool delete_nets; std::vector> new_cells; log_info("Packing IOs..\n"); diff --git a/gowin/arch.h b/gowin/arch.h index 0f975f77..82fcb8c1 100644 --- a/gowin/arch.h +++ b/gowin/arch.h @@ -209,7 +209,7 @@ struct BelInfo IdString name, type; std::map attrs; CellInfo *bound_cell; - std::unordered_map pins; + dict pins; DecalXY decalxy; int x, y, z; bool gb; @@ -229,27 +229,14 @@ struct CellDelayKey { IdString from, to; inline bool operator==(const CellDelayKey &other) const { return from == other.from && to == other.to; } + unsigned int hash() const { return mkhash(from.hash(), to.hash()); } }; -NEXTPNR_NAMESPACE_END -namespace std { -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX CellDelayKey &dk) const noexcept - { - std::size_t seed = std::hash()(dk.from); - seed ^= std::hash()(dk.to) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } -}; -} // namespace std -NEXTPNR_NAMESPACE_BEGIN - struct CellTiming { - std::unordered_map portClasses; - std::unordered_map combDelays; - std::unordered_map> clockingInfo; + dict portClasses; + dict combDelays; + dict> clockingInfo; }; struct ArchRanges : BaseArchRanges @@ -287,10 +274,10 @@ struct Arch : BaseArch const PackagePOD *package; const TimingGroupsPOD *speed; - std::unordered_map wires; - std::unordered_map pips; - std::unordered_map bels; - std::unordered_map groups; + dict wires; + dict pips; + dict bels; + dict groups; // These functions include useful errors if not found WireInfo &wire_info(IdString wire); @@ -299,16 +286,16 @@ struct Arch : BaseArch std::vector bel_ids, wire_ids, pip_ids; - std::unordered_map bel_by_loc; + dict bel_by_loc; std::vector>> bels_by_tile; - std::unordered_map> decal_graphics; + dict> decal_graphics; int gridDimX, gridDimY; std::vector> tileBelDimZ; std::vector> tilePipDimZ; - std::unordered_map cellTiming; + dict cellTiming; void addWire(IdString name, IdString type, int x, int y); void addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayQuad delay, Loc loc); diff --git a/gowin/cells.cc b/gowin/cells.cc index e45cd482..93f1246f 100644 --- a/gowin/cells.cc +++ b/gowin/cells.cc @@ -114,7 +114,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l replace_port(dff, id_Q, lc, id_Q); } -void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set &todelete_cells) +void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, pool &todelete_cells) { if (nxio->type == id_IBUF) { iob->params[id_INPUT_USED] = 1; diff --git a/gowin/cells.h b/gowin/cells.h index 30b29f5b..7bf1befd 100644 --- a/gowin/cells.h +++ b/gowin/cells.h @@ -87,7 +87,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = tr void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false); // Convert a Gowin IO buffer to a IOB bel -void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells); +void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool &todelete_cells); NEXTPNR_NAMESPACE_END diff --git a/gowin/pack.cc b/gowin/pack.cc index a2998c63..d3a749ea 100644 --- a/gowin/pack.cc +++ b/gowin/pack.cc @@ -21,7 +21,6 @@ #include #include #include -#include #include "cells.h" #include "design_utils.h" #include "log.h" @@ -34,7 +33,7 @@ static void pack_lut_lutffs(Context *ctx) { log_info("Packing LUT-FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); @@ -90,7 +89,7 @@ static void pack_nonlut_ffs(Context *ctx) { log_info("Packing non-LUT FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { @@ -212,8 +211,8 @@ static bool is_gowin_iob(const Context *ctx, const CellInfo *cell) // Pack IO buffers static void pack_io(Context *ctx) { - std::unordered_set packed_cells; - std::unordered_set delete_nets; + pool packed_cells; + pool delete_nets; std::vector> new_cells; log_info("Packing IOs..\n"); diff --git a/ice40/arch.h b/ice40/arch.h index 29396f49..9c9a118f 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -400,10 +400,10 @@ struct Arch : BaseArch const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; - mutable std::unordered_map bel_by_name; - mutable std::unordered_map wire_by_name; - mutable std::unordered_map pip_by_name; - mutable std::unordered_map bel_by_loc; + mutable dict bel_by_name; + mutable dict wire_by_name; + mutable dict pip_by_name; + mutable dict bel_by_loc; std::vector bel_carry; std::vector bel_to_cell; @@ -414,7 +414,7 @@ struct Arch : BaseArch // fast access to X and Y IdStrings for building object names std::vector x_ids, y_ids; // inverse of the above for name->object mapping - std::unordered_map id_to_x, id_to_y; + dict id_to_x, id_to_y; ArchArgs args; Arch(ArchArgs args); diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 6b625b6a..56b5561c 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -252,7 +252,7 @@ static BelPin get_one_bel_pin(const Context *ctx, WireId wire) } // Permute LUT init value given map (LUT input -> ext input) -unsigned permute_lut(unsigned orig_init, const std::unordered_map &input_permute) +unsigned permute_lut(unsigned orig_init, const dict &input_permute) { unsigned new_init = 0; @@ -387,8 +387,8 @@ void write_asc(const Context *ctx, std::ostream &out) } // Scan for PLL and collects the affected SB_IOs - std::unordered_set sb_io_used_by_pll_out; - std::unordered_set sb_io_used_by_pll_pad; + pool sb_io_used_by_pll_out; + pool sb_io_used_by_pll_pad; for (auto &cell : ctx->cells) { if (cell.second->type != ctx->id("ICESTORM_PLL")) @@ -447,7 +447,7 @@ void write_asc(const Context *ctx, std::ostream &out) std::vector lc(20, false); // Discover permutation - std::unordered_map input_perm; + dict input_perm; std::set unused; for (int i = 0; i < 4; i++) unused.insert(i); diff --git a/ice40/cells.cc b/ice40/cells.cc index d23b6c49..9517c590 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -412,7 +412,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l replace_port(dff, ctx->id("Q"), lc, ctx->id("O")); } -void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells) +void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool &todelete_cells) { if (nxio->type == ctx->id("$nextpnr_ibuf")) { sbio->params[ctx->id("PIN_TYPE")] = 1; diff --git a/ice40/cells.h b/ice40/cells.h index 777ca3e2..d4c0edf4 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -130,7 +130,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = tr void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false); // Convert a nextpnr IO buffer to a SB_IO -void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells); +void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool &todelete_cells); // Return true if a port is a clock port bool is_clock_port(const BaseCtx *ctx, const PortRef &port); diff --git a/ice40/chains.cc b/ice40/chains.cc index f75d329f..cfc8b4a1 100644 --- a/ice40/chains.cc +++ b/ice40/chains.cc @@ -253,7 +253,7 @@ class ChainConstrainer return i3_next; return (CellInfo *)nullptr; }); - std::unordered_set chained; + pool chained; for (auto &base_chain : carry_chains) { for (auto c : base_chain.cells) chained.insert(c->name); diff --git a/ice40/pack.cc b/ice40/pack.cc index 1d05a8c2..62b08534 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -21,7 +21,6 @@ #include #include -#include #include "cells.h" #include "chains.h" #include "design_utils.h" @@ -35,7 +34,7 @@ static void pack_lut_lutffs(Context *ctx) { log_info("Packing LUT-FFs..\n"); int lut_only = 0, lut_and_ff = 0; - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); @@ -100,7 +99,7 @@ static void pack_nonlut_ffs(Context *ctx) { log_info("Packing non-LUT FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; int ff_only = 0; @@ -144,8 +143,8 @@ static bool net_is_constant(const Context *ctx, NetInfo *net, bool &value) static void pack_carries(Context *ctx) { log_info("Packing carries..\n"); - std::unordered_set exhausted_cells; - std::unordered_set packed_cells; + pool exhausted_cells; + pool packed_cells; std::vector> new_cells; int carry_only = 0; @@ -274,7 +273,7 @@ static void pack_ram(Context *ctx) { log_info("Packing RAMs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { @@ -466,8 +465,8 @@ static bool is_ice_iob(const Context *ctx, const CellInfo *cell) // Pack IO buffers static void pack_io(Context *ctx) { - std::unordered_set packed_cells; - std::unordered_set delete_nets; + pool packed_cells; + pool delete_nets; std::vector> new_cells; log_info("Packing IOs..\n"); @@ -1119,7 +1118,7 @@ static void pack_special(Context *ctx) { log_info("Packing special functions..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; // Handle LED_DRV_CUR first to set the ledCurConnected flag before RGB_DRV is handled below. @@ -1299,7 +1298,7 @@ void pack_plls(Context *ctx) { log_info("Packing PLLs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); diff --git a/machxo2/arch.h b/machxo2/arch.h index 15535fe1..219e87f2 100644 --- a/machxo2/arch.h +++ b/machxo2/arch.h @@ -403,12 +403,12 @@ struct Arch : BaseArch const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; - mutable std::unordered_map pip_by_name; + mutable dict pip_by_name; // fast access to X and Y IdStrings for building object names std::vector x_ids, y_ids; // inverse of the above for name->object mapping - std::unordered_map id_to_x, id_to_y; + dict id_to_x, id_to_y; // Helpers template const TileTypePOD *tile_info(Id &id) const diff --git a/machxo2/cells.cc b/machxo2/cells.cc index 03ba0a41..c71247f2 100644 --- a/machxo2/cells.cc +++ b/machxo2/cells.cc @@ -175,6 +175,6 @@ void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut) } } -void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set &todelete_cells) {} +void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, pool &todelete_cells) {} NEXTPNR_NAMESPACE_END diff --git a/machxo2/cells.h b/machxo2/cells.h index a6de219e..afb08138 100644 --- a/machxo2/cells.h +++ b/machxo2/cells.h @@ -49,7 +49,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = tr void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false); // Convert a nextpnr IO buffer to a GENERIC_IOB -void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells); +void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool &todelete_cells); NEXTPNR_NAMESPACE_END diff --git a/machxo2/pack.cc b/machxo2/pack.cc index 26bda946..6f2ee8e4 100644 --- a/machxo2/pack.cc +++ b/machxo2/pack.cc @@ -20,7 +20,6 @@ #include #include -#include #include "cells.h" #include "design_utils.h" #include "log.h" @@ -33,7 +32,7 @@ static void pack_lut_lutffs(Context *ctx) { log_info("Packing LUT-FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); @@ -91,7 +90,7 @@ static void pack_remaining_ffs(Context *ctx) { log_info("Packing remaining FFs..\n"); - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; for (auto &cell : ctx->cells) { @@ -130,7 +129,7 @@ static void set_net_constant(Context *ctx, NetInfo *orig, NetInfo *constnet, boo { (void)constval; - std::unordered_set packed_cells; + pool packed_cells; std::vector> new_cells; orig->driver.cell = nullptr; @@ -233,7 +232,7 @@ static bool is_facade_iob(const Context *ctx, const CellInfo *cell) { return cel // attributes. static void pack_io(Context *ctx) { - std::unordered_set packed_cells; + pool packed_cells; log_info("Packing IOs..\n"); diff --git a/mistral/arch.h b/mistral/arch.h index ee2c84a3..1a42530a 100644 --- a/mistral/arch.h +++ b/mistral/arch.h @@ -85,7 +85,7 @@ struct BelInfo // For cases where we need to determine an original block index, due to multiple bels at the same tile this // might not be the same as the nextpnr z-coordinate int block_index; - std::unordered_map pins; + dict pins; // Info for different kinds of bels union { @@ -153,7 +153,7 @@ struct UpDownhillPipRange UpDownhillPipIterator b, e; UpDownhillPipRange(const std::vector &v, WireId other_wire, bool is_uphill) - : b(v.cbegin(), other_wire, is_uphill), e(v.cend(), other_wire, is_uphill){}; + : b(v.begin(), other_wire, is_uphill), e(v.end(), other_wire, is_uphill){}; UpDownhillPipIterator begin() const { return b; } UpDownhillPipIterator end() const { return e; } @@ -161,7 +161,7 @@ struct UpDownhillPipRange // This iterates over the list of wires, and for each wire yields its uphill pips, as an efficient way of going over // all the pips in the device -using WireMapIterator = std::unordered_map::const_iterator; +using WireMapIterator = dict::const_iterator; struct AllPipIterator { WireMapIterator base, end; @@ -196,8 +196,7 @@ struct AllPipRange { AllPipIterator b, e; - AllPipRange(const std::unordered_map &wires) - : b(wires.cbegin(), wires.cend(), -1), e(wires.cend(), wires.cend(), 0) + AllPipRange(const dict &wires) : b(wires.begin(), wires.end(), -1), e(wires.end(), wires.end(), 0) { // Starting the begin iterator at index -1 and incrementing it ensures we skip over the first wire if it has no // uphill pips @@ -211,7 +210,7 @@ struct AllPipRange // This transforms a map to a range of keys, used as the wire iterator template struct key_range { - key_range(const T &t) : b(t.cbegin()), e(t.cend()){}; + key_range(const T &t) : b(t.begin()), e(t.end()){}; typename T::const_iterator b, e; struct xformed_iterator : public T::const_iterator @@ -224,7 +223,7 @@ template struct key_range xformed_iterator end() const { return xformed_iterator(e); } }; -using AllWireRange = key_range>; +using AllWireRange = key_range>; struct ArchRanges : BaseArchRanges { @@ -489,7 +488,7 @@ struct Arch : BaseArch static const std::string defaultRouter; static const std::vector availableRouters; - std::unordered_map wires; + dict wires; // List of LABs std::vector labs; @@ -499,13 +498,13 @@ struct Arch : BaseArch // Conversion between numbers and rnode types and IdString, for fast wire name implementation std::vector int2id; - std::unordered_map id2int; + dict id2int; std::vector rn_t2id; - std::unordered_map id2rn_t; + dict id2rn_t; // This structure is only used for nextpnr-created wires - std::unordered_map npnr_wirebyname; + dict npnr_wirebyname; std::vector> bels_by_tile; std::vector all_bels; @@ -525,18 +524,18 @@ struct Arch : BaseArch // ------------------------------------------------- void assign_default_pinmap(CellInfo *cell); - static const std::unordered_map comb_pinmap; + static const dict comb_pinmap; // ------------------------------------------------- - typedef std::unordered_map CellPinsData; // pins.cc - static const std::unordered_map cell_pins_db; // pins.cc + typedef dict CellPinsData; // pins.cc + static const dict cell_pins_db; // pins.cc CellPinStyle get_cell_pin_style(const CellInfo *cell, IdString port) const; // pins.cc // ------------------------------------------------- // List of IO constraints, used by QSF parser - std::unordered_map> io_attr; + dict> io_attr; void read_qsf(std::istream &in); // qsf.cc // ------------------------------------------------- diff --git a/mistral/archdefs.h b/mistral/archdefs.h index 9d953223..71e14ec2 100644 --- a/mistral/archdefs.h +++ b/mistral/archdefs.h @@ -203,7 +203,7 @@ struct ArchCellInfo : BaseClusterInfo } ffInfo; }; - std::unordered_map pin_data; + dict pin_data; CellPinState get_pin_state(IdString pin) const; }; diff --git a/mistral/lab.cc b/mistral/lab.cc index abd0fec3..56bc604a 100644 --- a/mistral/lab.cc +++ b/mistral/lab.cc @@ -718,7 +718,7 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm) // - C, E0, and F0 are exclusive to the top LUT5 secion // - D, E1, and F1 are exclusive to the bottom LUT5 section // First find up to two shared inputs - std::unordered_map shared_nets; + dict shared_nets; if (luts[0] && luts[1]) { for (int i = 0; i < luts[0]->combInfo.lut_input_count; i++) { for (int j = 0; j < luts[1]->combInfo.lut_input_count; j++) { @@ -826,7 +826,7 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm) // This default cell-bel pin mapping is used to provide estimates during placement only. It will have errors and // overlaps and a correct mapping will be resolved twixt placement and routing -const std::unordered_map Arch::comb_pinmap = { +const dict Arch::comb_pinmap = { {id_A, id_F0}, // fastest input first {id_B, id_E0}, {id_C, id_D}, {id_D, id_C}, {id_D0, id_C}, {id_D1, id_B}, {id_E, id_B}, {id_F, id_A}, {id_Q, id_COMBOUT}, {id_SO, id_COMBOUT}, diff --git a/mistral/pins.cc b/mistral/pins.cc index c3637115..51cb83c4 100644 --- a/mistral/pins.cc +++ b/mistral/pins.cc @@ -23,7 +23,7 @@ NEXTPNR_NAMESPACE_BEGIN -const std::unordered_map Arch::cell_pins_db = { +const dict Arch::cell_pins_db = { // For combinational cells, inversion and tieing can be implemented by manipulating the LUT function {id_MISTRAL_ALUT2, {{{}, PINSTYLE_COMB}}}, {id_MISTRAL_ALUT3, {{{}, PINSTYLE_COMB}}}, diff --git a/mistral/qsf.cc b/mistral/qsf.cc index 9a128595..88f51b1b 100644 --- a/mistral/qsf.cc +++ b/mistral/qsf.cc @@ -34,7 +34,7 @@ struct QsfOption bool required; // error out if this option isn't passed }; -typedef std::unordered_map> option_map_t; +typedef dict> option_map_t; struct QsfCommand { diff --git a/nexus/arch.h b/nexus/arch.h index b3558413..a669be0d 100644 --- a/nexus/arch.h +++ b/nexus/arch.h @@ -916,7 +916,7 @@ struct Arch : BaseArch // fast access to X and Y IdStrings for building object names std::vector x_ids, y_ids; // inverse of the above for name->object mapping - std::unordered_map id_to_x, id_to_y; + dict id_to_x, id_to_y; // ------------------------------------------------- @@ -1181,7 +1181,7 @@ struct Arch : BaseArch // for better DSP bounding boxes void pre_routing(); - std::unordered_set dsp_wires, lram_wires; + pool dsp_wires, lram_wires; // ------------------------------------------------- @@ -1271,9 +1271,9 @@ struct Arch : BaseArch // ------------------------------------------------- - typedef std::unordered_map CellPinsData; + typedef dict CellPinsData; - std::unordered_map cell_pins_db; + dict cell_pins_db; CellPinStyle get_cell_pin_style(const CellInfo *cell, IdString port) const; void init_cell_pin_data(); @@ -1361,7 +1361,7 @@ struct Arch : BaseArch // ------------------------------------------------- // Data about different IO standard, mostly used by bitgen - static const std::unordered_map io_types; + static const dict io_types; int get_io_type_vcc(const std::string &io_type) const; bool is_io_type_diff(const std::string &io_type) const; bool is_io_type_ref(const std::string &io_type) const; @@ -1388,7 +1388,7 @@ struct Arch : BaseArch // ------------------------------------------------- // List of IO constraints, used by PDC parser - std::unordered_map> io_attr; + dict> io_attr; void read_pdc(std::istream &in); diff --git a/nexus/archdefs.h b/nexus/archdefs.h index db8a3af4..76ba605b 100644 --- a/nexus/archdefs.h +++ b/nexus/archdefs.h @@ -21,7 +21,6 @@ #define NEXUS_ARCHDEFS_H #include -#include #include "base_clusterinfo.h" #include "hashlib.h" @@ -184,7 +183,7 @@ struct ArchCellInfo : BaseClusterInfo int tmg_index = -1; // Map from cell/bel ports to logical timing ports - std::unordered_map tmg_portmap; + dict tmg_portmap; }; NEXTPNR_NAMESPACE_END diff --git a/nexus/fasm.cc b/nexus/fasm.cc index 13fe00c1..48483bfe 100644 --- a/nexus/fasm.cc +++ b/nexus/fasm.cc @@ -336,7 +336,7 @@ struct NexusFasmWriter pop(2); } - std::unordered_set used_io; + pool used_io; struct BankConfig { @@ -556,7 +556,7 @@ struct NexusFasmWriter // Which PLL params are 'word' values /* clang-format off */ - const std::unordered_map pll_word_params = { + const dict pll_word_params = { {"DIVA", 7}, {"DELA", 7}, {"PHIA", 3}, {"DIVB", 7}, {"DELB", 7}, {"PHIB", 3}, {"DIVC", 7}, {"DELC", 7}, {"PHIC", 3}, {"DIVD", 7}, {"DELD", 7}, {"PHID", 3}, @@ -582,7 +582,7 @@ struct NexusFasmWriter }; // Which MIPI params are 'word' values - const std::unordered_map dphy_word_params = { + const dict dphy_word_params = { {"CM", 8}, {"CN", 5}, {"CO", 3}, {"RSEL", 2}, {"RXCDRP", 2}, {"RXDATAWIDTHHS", 2}, {"RXLPRP", 3}, {"TEST_ENBL", 6}, {"TEST_PATTERN", 32}, {"TST", 4}, {"TXDATAWIDTHHS", 2}, @@ -683,7 +683,7 @@ struct NexusFasmWriter write_comment("# Unused bels"); // DSP primitives are configured to a default mode; even if unused - static const std::unordered_map> dsp_defconf = { + static const dict> dsp_defconf = { {id_MULT9_CORE, { "GSR.ENABLED", @@ -733,7 +733,7 @@ struct NexusFasmWriter } } } - std::unordered_map bank_vcco; + dict bank_vcco; // bank VccO in mV int get_bank_vcco(const std::string &iostd) { diff --git a/nexus/global.cc b/nexus/global.cc index fa6212e8..9a0d095b 100644 --- a/nexus/global.cc +++ b/nexus/global.cc @@ -49,7 +49,7 @@ struct NexusGlobalRouter // Queue of wires to visit std::queue visit; // Wire -> upstream pip - std::unordered_map backtrace; + dict backtrace; // Lookup source and destination wires WireId src = ctx->getNetinfoSourceWire(net); diff --git a/nexus/io.cc b/nexus/io.cc index fd5e584f..314d80b6 100644 --- a/nexus/io.cc +++ b/nexus/io.cc @@ -23,7 +23,7 @@ NEXTPNR_NAMESPACE_BEGIN -const std::unordered_map Arch::io_types = { +const dict Arch::io_types = { {"LVCMOS33", {IOSTYLE_SE_WR, 330}}, {"LVCMOS25", {IOSTYLE_SE_WR, 250}}, {"LVCMOS18", {IOSTYLE_SE_WR, 180}}, {"LVCMOS15", {IOSTYLE_SE_WR, 150}}, {"LVCMOS12", {IOSTYLE_SE_WR, 120}}, {"LVCMOS10", {IOSTYLE_SE_WR, 120}}, diff --git a/nexus/pack.cc b/nexus/pack.cc index 812731cf..1d977f2c 100644 --- a/nexus/pack.cc +++ b/nexus/pack.cc @@ -106,16 +106,16 @@ struct NexusPacker struct XFormRule { IdString new_type; - std::unordered_map port_xform; - std::unordered_map> port_multixform; - std::unordered_map param_xform; + dict port_xform; + dict> port_multixform; + dict param_xform; std::vector> set_attrs; std::vector> set_params; std::vector> default_params; std::vector> parse_params; }; - void xform_cell(const std::unordered_map &rules, CellInfo *ci) + void xform_cell(const dict &rules, CellInfo *ci) { auto &rule = rules.at(ci->type); ci->type = rule.new_type; @@ -178,7 +178,7 @@ struct NexusPacker ci->params[param.first] = param.second; } - void generic_xform(const std::unordered_map &rules, bool print_summary = false) + void generic_xform(const dict &rules, bool print_summary = false) { std::map cell_count; std::map new_types; @@ -205,7 +205,7 @@ struct NexusPacker void pack_luts() { log_info("Packing LUTs...\n"); - std::unordered_map lut_rules; + dict lut_rules; lut_rules[id_LUT4].new_type = id_OXIDE_COMB; lut_rules[id_LUT4].port_xform[id_Z] = id_F; lut_rules[id_LUT4].parse_params.emplace_back(id_INIT, id_INIT, 16, 0); @@ -229,7 +229,7 @@ struct NexusPacker void pack_ffs() { log_info("Packing FFs...\n"); - std::unordered_map ff_rules; + dict ff_rules; for (auto type : {id_FD1P3BX, id_FD1P3DX, id_FD1P3IX, id_FD1P3JX}) { ff_rules[type].new_type = id_OXIDE_FF; ff_rules[type].port_xform[id_CK] = id_CLK; @@ -262,7 +262,7 @@ struct NexusPacker generic_xform(ff_rules, true); } - std::unordered_map reference_bels; + dict reference_bels; void autocreate_ports(CellInfo *cell) { @@ -549,11 +549,10 @@ struct NexusPacker void pack_io() { - std::unordered_set iob_types = {id_IB, id_OB, id_OBZ, id_BB, - id_BB_I3C_A, id_SEIO33, id_SEIO18, id_DIFFIO18, - id_SEIO33_CORE, id_SEIO18_CORE, id_DIFFIO18_CORE}; + pool iob_types = {id_IB, id_OB, id_OBZ, id_BB, id_BB_I3C_A, id_SEIO33, + id_SEIO18, id_DIFFIO18, id_SEIO33_CORE, id_SEIO18_CORE, id_DIFFIO18_CORE}; - std::unordered_map io_rules; + dict io_rules; // For the low level primitives, make sure we always preserve their type io_rules[id_SEIO33_CORE].new_type = id_SEIO33_CORE; @@ -567,12 +566,12 @@ struct NexusPacker io_rules[id_SEIO33].port_xform[id_PADDT] = id_T; io_rules[id_SEIO33].port_xform[id_IOPAD] = id_B; - io_rules[id_BB_I3C_A] = io_rules[id_SEIO33]; + io_rules[id_BB_I3C_A] = XFormRule(io_rules[id_SEIO33]); - io_rules[id_SEIO18] = io_rules[id_SEIO33]; + io_rules[id_SEIO18] = XFormRule(io_rules[id_SEIO33]); io_rules[id_SEIO18].new_type = id_SEIO18_CORE; - io_rules[id_DIFFIO18] = io_rules[id_SEIO33]; + io_rules[id_DIFFIO18] = XFormRule(io_rules[id_SEIO33]); io_rules[id_DIFFIO18].new_type = id_DIFFIO18_CORE; // Stage 0: deal with top level inserted IO buffers @@ -677,8 +676,8 @@ struct NexusPacker { int iter = 0; std::queue visit; - std::unordered_set seen_wires; - std::unordered_set seen_bels; + pool seen_wires; + pool seen_bels; BelId bel = get_bel_attr(cell); if (bel == BelId()) @@ -751,7 +750,7 @@ struct NexusPacker return best_bel; } - std::unordered_set used_bels; + pool used_bels; // Pre-place a primitive based on routeability first and distance second bool preplace_prim(CellInfo *cell, IdString pin, bool strict_routing) @@ -1024,7 +1023,7 @@ struct NexusPacker void convert_prims() { // Convert primitives from their non-CORE variant to their CORE variant - static const std::unordered_map prim_map = { + static const dict prim_map = { {id_OSCA, id_OSC_CORE}, {id_DP16K, id_DP16K_MODE}, {id_PDP16K, id_PDP16K_MODE}, {id_PDPSC16K, id_PDPSC16K_MODE}, {id_SP16K, id_SP16K_MODE}, {id_FIFO16K, id_FIFO16K_MODE}, {id_SP512K, id_SP512K_MODE}, {id_DPSC512K, id_DPSC512K_MODE}, {id_PDPSC512K, id_PDPSC512K_MODE}, @@ -1048,7 +1047,7 @@ struct NexusPacker void pack_bram() { - std::unordered_map bram_rules; + dict bram_rules; bram_rules[id_DP16K_MODE].new_type = id_OXIDE_EBR; bram_rules[id_DP16K_MODE].set_params.emplace_back(id_MODE, std::string("DP16K")); bram_rules[id_DP16K_MODE].parse_params.emplace_back(id_CSDECODE_A, id_CSDECODE_A, 3, 7); @@ -1074,7 +1073,7 @@ struct NexusPacker add_bus_xform(bram_rules[id_PDP16K_MODE], "DO", "DOA", 18, 18, 0); // Pseudo dual port; single clock - bram_rules[id_PDPSC16K_MODE] = bram_rules[id_PDP16K_MODE]; + bram_rules[id_PDPSC16K_MODE] = XFormRule(bram_rules[id_PDP16K_MODE]); bram_rules[id_PDPSC16K_MODE].set_params.clear(); bram_rules[id_PDPSC16K_MODE].set_params.emplace_back(id_MODE, std::string("PDPSC16K")); bram_rules[id_PDPSC16K_MODE].set_params.emplace_back(id_WEAMUX, std::string("1")); @@ -1096,7 +1095,7 @@ struct NexusPacker void pack_lram() { - std::unordered_map lram_rules; + dict lram_rules; lram_rules[id_SP512K_MODE].new_type = id_LRAM_CORE; lram_rules[id_SP512K_MODE].set_params.emplace_back(id_EBR_SP_EN, std::string("ENABLE")); lram_rules[id_SP512K_MODE].port_xform[id_CE] = id_CEA; @@ -1296,7 +1295,7 @@ struct NexusPacker // Automatically generate cascade connections downstream of a cell // using the temporary placement that we use solely to access the routing graph - void auto_cascade_cell(CellInfo *cell, BelId bel, const std::unordered_map &bel2cell) + void auto_cascade_cell(CellInfo *cell, BelId bel, const dict &bel2cell) { // Create outputs based on the actual bel for (auto bp : ctx->getBelPins(bel)) { @@ -1322,7 +1321,7 @@ struct NexusPacker // Standard BFS-type exploration std::queue visit; - std::unordered_set in_queue; + pool in_queue; visit.push(start_wire); in_queue.insert(start_wire); int iter = 0; @@ -1403,8 +1402,8 @@ struct NexusPacker // We first create a temporary placement so we can access the routing graph bool found = false; - std::unordered_map bel2cell; - std::unordered_map cell2bel; + dict bel2cell; + dict cell2bel; for (BelId root_bel : ctx->getBels()) { if (ctx->getBelType(root_bel) != root->type) @@ -1592,7 +1591,7 @@ struct NexusPacker int wide; // DSP is a "wide" (dot-product) variant }; - const std::unordered_map dsp_types = { + const dict dsp_types = { {id_MULT9X9, {9, 9, 0, 18, 1, 0, 0, false, false, -1}}, {id_MULT18X18, {18, 18, 0, 36, 2, 1, 0, false, false, -1}}, {id_MULT18X36, {18, 36, 0, 54, 4, 2, 1, false, false, -1}}, @@ -1805,7 +1804,7 @@ struct NexusPacker auto equals_epsilon = [](delay_t a, delay_t b) { return (std::abs(a - b) / std::max(double(b), 1.0)) < 1e-3; }; - std::unordered_set user_constrained, changed_nets; + pool user_constrained, changed_nets; for (auto &net : ctx->nets) { if (net.second->clkconstr != nullptr) user_constrained.insert(net.first); @@ -1883,7 +1882,7 @@ struct NexusPacker const int itermax = 5000; while (!changed_nets.empty() && iter < itermax) { ++iter; - std::unordered_set changed_cells; + pool changed_cells; for (auto net : changed_nets) { for (auto &user : ctx->nets.at(net)->users) if (user.port == id_CLKI || user.port == id_REFCK) @@ -1893,7 +1892,7 @@ struct NexusPacker changed_cells.insert(drv.cell->name); } changed_nets.clear(); - for (auto cell : sorted(changed_cells)) { + for (auto cell : changed_cells) { CellInfo *ci = ctx->cells.at(cell).get(); if (ci->type == id_DCC) { copy_constraint(ci, id_CLKI, id_CLKO, 1); @@ -1945,7 +1944,7 @@ struct NexusPacker void pack_plls() { - const std::unordered_map pll_defaults = { + const dict pll_defaults = { {id_FLOCK_CTRL, "2X"}, {id_FLOCK_EN, "ENABLED"}, {id_FLOCK_SRC_SEL, "REFCLK"}, {id_DIV_DEL, "0b0000001"}, {id_FBK_PI_RC, "0b1100"}, {id_FBK_PR_IC, "0b1000"}, }; @@ -1966,7 +1965,7 @@ struct NexusPacker // Map LOC attribute on DPHY_CORE to a bel // TDPHY_CORE2 is Radiant 2.0 style, DPHY0 is Radiant 2.2 // TODO: LIFCL-17 (perhaps remove the hardcoded map) - const std::unordered_map dphy_loc_map = { + const dict dphy_loc_map = { {"TDPHY_CORE2", "X4/Y0/TDPHY_CORE2"}, {"DPHY0", "X4/Y0/TDPHY_CORE2"}, {"TDPHY_CORE26", "X28/Y0/TDPHY_CORE26"}, diff --git a/nexus/pdc.cc b/nexus/pdc.cc index 1ffe0a64..f81bb74e 100644 --- a/nexus/pdc.cc +++ b/nexus/pdc.cc @@ -406,7 +406,7 @@ struct PDCParser TCLValue cmd_ldc_set_port(const std::vector &arguments) { - std::unordered_map args; + dict args; for (int i = 1; i < int(arguments.size()); i++) { auto &arg = arguments.at(i); if (arg.is_string) { diff --git a/nexus/pins.cc b/nexus/pins.cc index a283953b..e9841f4b 100644 --- a/nexus/pins.cc +++ b/nexus/pins.cc @@ -24,7 +24,7 @@ NEXTPNR_NAMESPACE_BEGIN namespace { -static const std::unordered_map base_cell_pin_data = { +static const dict base_cell_pin_data = { {id_OXIDE_COMB, { {id_WCK, PINSTYLE_DEDI}, -- cgit v1.2.3