1 /* 2 * nextpnr -- Next Generation Place and Route 3 * 4 * Copyright (C) 2018 David Shah <david@symbioticeda.com> 5 * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * 19 */ 20 21 #ifndef NEXTPNR_H 22 #error Include "archdefs.h" via "nextpnr.h" only. 23 #endif 24 25 #include <boost/functional/hash.hpp> 26 27 NEXTPNR_NAMESPACE_BEGIN 28 29 typedef int delay_t; 30 31 struct DelayInfo 32 { 33 delay_t min_delay = 0, max_delay = 0; 34 minRaiseDelayDelayInfo35 delay_t minRaiseDelay() const { return min_delay; } maxRaiseDelayDelayInfo36 delay_t maxRaiseDelay() const { return max_delay; } 37 minFallDelayDelayInfo38 delay_t minFallDelay() const { return min_delay; } maxFallDelayDelayInfo39 delay_t maxFallDelay() const { return max_delay; } 40 minDelayDelayInfo41 delay_t minDelay() const { return min_delay; } maxDelayDelayInfo42 delay_t maxDelay() const { return max_delay; } 43 44 DelayInfo operator+(const DelayInfo &other) const 45 { 46 DelayInfo ret; 47 ret.min_delay = this->min_delay + other.min_delay; 48 ret.max_delay = this->max_delay + other.max_delay; 49 return ret; 50 } 51 }; 52 53 // ----------------------------------------------------------------------- 54 55 // https://bugreports.qt.io/browse/QTBUG-80789 56 57 #ifndef Q_MOC_RUN 58 enum ConstIds 59 { 60 ID_NONE 61 #define X(t) , ID_##t 62 #include "constids.inc" 63 #undef X 64 , 65 DB_CONST_ID_COUNT 66 }; 67 68 #define X(t) static constexpr auto id_##t = IdString(ID_##t); 69 #include "constids.inc" 70 #undef X 71 #endif 72 73 NPNR_PACKED_STRUCT(struct LocationPOD { int16_t x, y; }); 74 75 struct Location 76 { 77 int16_t x = -1, y = -1; LocationLocation78 Location() : x(-1), y(-1){}; LocationLocation79 Location(int16_t x, int16_t y) : x(x), y(y){}; LocationLocation80 Location(const LocationPOD &pod) : x(pod.x), y(pod.y){}; LocationLocation81 Location(const Location &loc) : x(loc.x), y(loc.y){}; 82 83 bool operator==(const Location &other) const { return x == other.x && y == other.y; } 84 bool operator!=(const Location &other) const { return x != other.x || y != other.y; } 85 bool operator<(const Location &other) const { return y == other.y ? x < other.x : y < other.y; } 86 }; 87 88 inline Location operator+(const Location &a, const Location &b) { return Location(a.x + b.x, a.y + b.y); } 89 90 struct BelId 91 { 92 Location location; 93 int32_t index = -1; 94 95 bool operator==(const BelId &other) const { return index == other.index && location == other.location; } 96 bool operator!=(const BelId &other) const { return index != other.index || location != other.location; } 97 bool operator<(const BelId &other) const 98 { 99 return location == other.location ? index < other.index : location < other.location; 100 } 101 }; 102 103 struct WireId 104 { 105 Location location; 106 int32_t index = -1; 107 108 bool operator==(const WireId &other) const { return index == other.index && location == other.location; } 109 bool operator!=(const WireId &other) const { return index != other.index || location != other.location; } 110 bool operator<(const WireId &other) const 111 { 112 return location == other.location ? index < other.index : location < other.location; 113 } 114 }; 115 116 struct PipId 117 { 118 Location location; 119 int32_t index = -1; 120 121 bool operator==(const PipId &other) const { return index == other.index && location == other.location; } 122 bool operator!=(const PipId &other) const { return index != other.index || location != other.location; } 123 bool operator<(const PipId &other) const 124 { 125 return location == other.location ? index < other.index : location < other.location; 126 } 127 }; 128 129 struct GroupId 130 { 131 enum : int8_t 132 { 133 TYPE_NONE, 134 TYPE_SWITCHBOX 135 } type = TYPE_NONE; 136 Location location; 137 138 bool operator==(const GroupId &other) const { return (type == other.type) && (location == other.location); } 139 bool operator!=(const GroupId &other) const { return (type != other.type) || (location != other.location); } 140 }; 141 142 struct DecalId 143 { 144 enum 145 { 146 TYPE_NONE, 147 TYPE_BEL, 148 TYPE_WIRE, 149 TYPE_PIP, 150 TYPE_GROUP 151 } type = TYPE_NONE; 152 Location location; 153 uint32_t z = 0; 154 bool active = false; 155 bool operator==(const DecalId &other) const 156 { 157 return type == other.type && location == other.location && z == other.z && active == other.active; 158 } 159 bool operator!=(const DecalId &other) const 160 { 161 return type != other.type || location != other.location || z != other.z || active != other.active; 162 } 163 }; 164 165 struct ArchNetInfo 166 { 167 bool is_global = false; 168 }; 169 170 struct ArchCellInfo 171 { 172 struct 173 { 174 bool using_dff; 175 bool has_l6mux; 176 bool is_carry; 177 IdString clk_sig, lsr_sig, clkmux, lsrmux, srmode; 178 int sd0, sd1; 179 } sliceInfo; 180 struct 181 { 182 bool is_pdp; 183 // Are the outputs from a DP16KD registered (OUTREG) 184 // or non-registered (NOREG) 185 bool is_output_a_registered; 186 bool is_output_b_registered; 187 // Which timing information to use for a DP16KD. Depends on registering 188 // configuration. 189 nextpnr_ecp5::IdString regmode_timing_id; 190 } ramInfo; 191 struct 192 { 193 bool is_clocked; 194 nextpnr_ecp5::IdString timing_id; 195 } multInfo; 196 }; 197 198 NEXTPNR_NAMESPACE_END 199 200 namespace std { 201 template <> struct hash<NEXTPNR_NAMESPACE_PREFIX Location> 202 { 203 std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX Location &loc) const noexcept 204 { 205 std::size_t seed = std::hash<int>()(loc.x); 206 seed ^= std::hash<int>()(loc.y) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 207 return seed; 208 } 209 }; 210 211 template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelId> 212 { 213 std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const noexcept 214 { 215 std::size_t seed = std::hash<NEXTPNR_NAMESPACE_PREFIX Location>()(bel.location); 216 seed ^= std::hash<int>()(bel.index) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 217 return seed; 218 } 219 }; 220 221 template <> struct hash<NEXTPNR_NAMESPACE_PREFIX WireId> 222 { 223 std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const noexcept 224 { 225 std::size_t seed = std::hash<NEXTPNR_NAMESPACE_PREFIX Location>()(wire.location); 226 seed ^= std::hash<int>()(wire.index) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 227 return seed; 228 } 229 }; 230 231 template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PipId> 232 { 233 std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &pip) const noexcept 234 { 235 std::size_t seed = std::hash<NEXTPNR_NAMESPACE_PREFIX Location>()(pip.location); 236 seed ^= std::hash<int>()(pip.index) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 237 return seed; 238 } 239 }; 240 241 template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId> 242 { 243 std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept 244 { 245 std::size_t seed = 0; 246 boost::hash_combine(seed, hash<int>()(group.type)); 247 boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX Location>()(group.location)); 248 return seed; 249 } 250 }; 251 252 template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId> 253 { 254 std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept 255 { 256 std::size_t seed = 0; 257 boost::hash_combine(seed, hash<int>()(decal.type)); 258 boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX Location>()(decal.location)); 259 boost::hash_combine(seed, hash<int>()(decal.z)); 260 boost::hash_combine(seed, hash<bool>()(decal.active)); 261 return seed; 262 } 263 }; 264 265 } // namespace std 266