diff --git a/common/timing.cc b/common/timing.cc index b68ca35c..1670bc7d 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "log.h" #include "util.h" @@ -272,7 +271,7 @@ void TimingAnalyser::setup_port_domains() void TimingAnalyser::reset_times() { for (auto &port : ports) { - auto do_reset = [&](std::unordered_map ×) { + auto do_reset = [&](dict ×) { for (auto &t : times) { t.second.value = init_delay; t.second.path_length = 0; @@ -426,7 +425,7 @@ void TimingAnalyser::walk_backward() void TimingAnalyser::print_fmax() { // Temporary testing code for comparison only - std::unordered_map domain_fmax; + dict domain_fmax; for (auto p : topological_order) { auto &pd = ports.at(p); for (auto &req : pd.required) { @@ -591,6 +590,7 @@ struct ClockEvent ClockEdge edge; bool operator==(const ClockEvent &other) const { return clock == other.clock && edge == other.edge; } + unsigned int hash() const { return mkhash(clock.hash(), int(edge)); } }; struct ClockPair @@ -598,37 +598,10 @@ struct ClockPair ClockEvent start, end; bool operator==(const ClockPair &other) const { return start == other.start && end == other.end; } + unsigned int hash() const { return mkhash(start.hash(), end.hash()); } }; } // namespace -NEXTPNR_NAMESPACE_END -namespace std { - -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX ClockEvent &obj) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, hash()(obj.clock)); - boost::hash_combine(seed, hash()(int(obj.edge))); - return seed; - } -}; - -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX ClockPair &obj) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, hash()(obj.start)); - boost::hash_combine(seed, hash()(obj.start)); - return seed; - } -}; - -} // namespace std -NEXTPNR_NAMESPACE_BEGIN - typedef std::vector PortRefVector; typedef std::map DelayFrequency; @@ -639,7 +612,7 @@ struct CriticalPath delay_t path_period; }; -typedef std::unordered_map CriticalPathMap; +typedef dict CriticalPathMap; struct Timing { @@ -660,7 +633,7 @@ struct Timing delay_t min_remaining_budget; bool false_startpoint = false; std::vector min_required; - std::unordered_map arrival_time; + dict arrival_time; }; Timing(Context *ctx, bool net_delays, bool update, CriticalPathMap *crit_path = nullptr, @@ -677,14 +650,14 @@ struct Timing // First, compute the topological order of nets to walk through the circuit, assuming it is a _acyclic_ graph // TODO(eddieh): Handle the case where it is cyclic, e.g. combinatorial loops std::vector topological_order; - std::unordered_map> net_data; + dict, hash_ptr_ops> net_data; // In lieu of deleting edges from the graph, simply count the number of fanins to each output port - std::unordered_map port_fanin; + dict port_fanin; std::vector input_ports; std::vector output_ports; - std::unordered_set ooc_port_nets; + pool ooc_port_nets; // In out-of-context mode, top-level inputs look floating but aren't if (bool_or_default(ctx->settings, ctx->id("arch.ooc"))) { @@ -880,7 +853,7 @@ struct Timing } } - std::unordered_map> crit_nets; + dict> crit_nets; // Now go backwards topologically to determine the minimum path slack, and to distribute all path slack evenly // between all nets on the path diff --git a/common/timing.h b/common/timing.h index 133bd4eb..974bb26b 100644 --- a/common/timing.h +++ b/common/timing.h @@ -35,15 +35,7 @@ struct CellPortKey port = pr.port; } IdString cell, port; - struct Hash - { - inline std::size_t operator()(const CellPortKey &arg) const noexcept - { - std::size_t seed = std::hash()(arg.cell); - seed ^= std::hash()(arg.port) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } - }; + unsigned int hash() const { return mkhash(cell.hash(), port.hash()); } inline bool operator==(const CellPortKey &other) const { return (cell == other.cell) && (port == other.port); } inline bool operator!=(const CellPortKey &other) const { return (cell != other.cell) || (port != other.port); } inline bool operator<(const CellPortKey &other) const @@ -69,15 +61,8 @@ struct NetPortKey return idx; } - struct Hash - { - std::size_t operator()(const NetPortKey &arg) const noexcept - { - std::size_t seed = std::hash()(arg.net); - seed ^= std::hash()(arg.idx) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } - }; + unsigned int hash() const { return mkhash(net.hash(), idx); } + inline bool operator==(const NetPortKey &other) const { return (net == other.net) && (idx == other.idx); } }; @@ -89,15 +74,8 @@ struct ClockDomainKey // probably also need something here to deal with constraints inline bool is_async() const { return clock == IdString(); } - struct Hash - { - std::size_t operator()(const ClockDomainKey &arg) const noexcept - { - std::size_t seed = std::hash()(arg.clock); - seed ^= std::hash()(int(arg.edge)) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } - }; + unsigned int hash() const { return mkhash(clock.hash(), int(edge)); } + inline bool operator==(const ClockDomainKey &other) const { return (clock == other.clock) && (edge == other.edge); } }; @@ -111,15 +89,7 @@ struct ClockDomainPairKey { return (launch == other.launch) && (capture == other.capture); } - struct Hash - { - std::size_t operator()(const ClockDomainPairKey &arg) const noexcept - { - std::size_t seed = std::hash()(arg.launch); - seed ^= std::hash()(arg.capture) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } - }; + unsigned int hash() const { return mkhash(launch, capture); } }; struct TimingAnalyser @@ -223,16 +193,17 @@ struct TimingAnalyser NetPortKey net_port; PortType type; // per domain timings - std::unordered_map arrival; - std::unordered_map required; - std::unordered_map domain_pairs; + dict arrival; + dict required; + dict domain_pairs; // cell timing arcs to (outputs)/from (inputs) from this port std::vector cell_arcs; // routing delay into this port (input ports only) - DelayPair route_delay; + DelayPair route_delay{0}; // worst criticality and slack across domain pairs - float worst_crit; - delay_t worst_setup_slack, worst_hold_slack; + float worst_crit = 0; + delay_t worst_setup_slack = std::numeric_limits::max(), + worst_hold_slack = std::numeric_limits::max(); }; struct PerDomain @@ -260,9 +231,9 @@ struct TimingAnalyser void copy_domains(const CellPortKey &from, const CellPortKey &to, bool backwards); - std::unordered_map ports; - std::unordered_map domain_to_id; - std::unordered_map pair_to_id; + dict ports; + dict domain_to_id; + dict pair_to_id; std::vector domains; std::vector domain_pairs;