/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2021 Lofty #include "cyclonev.h" #include "idstring.h" #include "nextpnr_assertions.h" #include "nextpnr_namespaces.h" NEXTPNR_NAMESPACE_BEGIN using mistral::CycloneV; typedef int delay_t; // https://bugreports.qt.io/browse/QTBUG-80789 #ifndef Q_MOC_RUN enum ConstIds { ID_NONE #define X(t) , ID_##t #include "constids.inc" #undef X }; #define X(t) static constexpr auto id_##t = IdString(ID_##t); #include "constids.inc" #undef X #endif struct DelayInfo { delay_t delay = 0; delay_t minRaiseDelay() const { return delay; } delay_t maxRaiseDelay() const { return delay; } delay_t minFallDelay() const { return delay; } delay_t maxFallDelay() const { return delay; } delay_t minDelay() const { return delay; } delay_t maxDelay() const { return delay; } DelayInfo operator+(const DelayInfo &other) const { DelayInfo ret; ret.delay = this->delay + other.delay; return ret; } }; struct BelId { BelId() = default; BelId(CycloneV::pos_t _pos, uint16_t _z) : pos{_pos}, z{_z} {} // pos_t is used for X/Y, nextpnr-cyclonev uses its own Z coordinate system. CycloneV::pos_t pos = 0; uint16_t z = 0; bool operator==(const BelId &other) const { return pos == other.pos && z == other.z; } bool operator!=(const BelId &other) const { return pos != other.pos || z != other.z; } bool operator<(const BelId &other) const { return pos < other.pos || (pos == other.pos && z < other.z); } }; static constexpr auto invalid_rnode = std::numeric_limits::max(); struct WireId { WireId() = default; explicit WireId(CycloneV::rnode_t node) : node(node){}; CycloneV::rnode_t node = invalid_rnode; // Wires created by nextpnr have rnode type >= 128 bool is_nextpnr_created() const { NPNR_ASSERT(node != invalid_rnode); return CycloneV::rn2t(node) >= 128; } bool operator==(const WireId &other) const { return node == other.node; } bool operator!=(const WireId &other) const { return node != other.node; } bool operator<(const WireId &other) const { return node < other.node; } }; struct PipId { PipId() = default; PipId(CycloneV::rnode_t src, CycloneV::rnode_t dst) : src(src), dst(dst){}; CycloneV::rnode_t src = invalid_rnode, dst = invalid_rnode; bool operator==(const PipId &other) const { return src == other.src && dst == other.dst; } bool operator!=(const PipId &other) const { return src != other.src || dst != other.dst; } bool operator<(const PipId &other) const { return dst < other.dst || (dst == other.dst && src < other.src); } }; typedef IdString DecalId; typedef IdString GroupId; typedef IdString BelBucketId; struct ArchNetInfo { }; struct ArchCellInfo { }; NEXTPNR_NAMESPACE_END namespace std { template <> struct hash { std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const noexcept { return hash()((static_cast(bel.pos) << 16) | bel.z); } }; template <> struct hash { std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const noexcept { return hash()(wire.node); } }; template <> struct hash { std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &pip) const noexcept { return hash()((uint64_t(pip.dst) << 32) | pip.src); } }; } // namespace std #endif