diff options
Diffstat (limited to 'common/nextpnr.h')
-rw-r--r-- | common/nextpnr.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index b4f68f93..78bbf66e 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -145,6 +145,152 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdString> NEXTPNR_NAMESPACE_BEGIN +// An small size optimised array that is statically allocated when the size is N or less; heap allocated otherwise +template <typename T, size_t N> class SSOArray +{ + private: + union + { + T data_static[N]; + T *data_heap; + }; + size_t m_size; + inline bool is_heap() const { return (m_size > N); } + void alloc() + { + if (is_heap()) { + data_heap = new T[m_size]; + } + } + + public: + T *data() { return is_heap() ? data_heap : data_static; } + const T *data() const { return is_heap() ? data_heap : data_static; } + size_t size() const { return m_size; } + + T *begin() { return data(); } + T *end() { return data() + m_size; } + const T *begin() const { return data(); } + const T *end() const { return data() + m_size; } + + SSOArray() : m_size(0){}; + + SSOArray(size_t size, const T &init = T()) : m_size(size) + { + alloc(); + std::fill(begin(), end(), init); + } + + SSOArray(const SSOArray &other) : m_size(other.size()) + { + alloc(); + std::copy(other.begin(), other.end(), begin()); + } + + template <typename Tother> SSOArray(const Tother &other) : m_size(other.size()) + { + alloc(); + std::copy(other.begin(), other.end(), begin()); + } + + ~SSOArray() + { + if (is_heap()) { + delete[] data_heap; + } + } + + bool operator==(const SSOArray &other) const + { + if (size() != other.size()) + return false; + return std::equal(begin(), end(), other.begin()); + } + bool operator!=(const SSOArray &other) const + { + if (size() != other.size()) + return true; + return !std::equal(begin(), end(), other.begin()); + } + T &operator[](size_t idx) + { + NPNR_ASSERT(idx < m_size); + return data()[idx]; + } + const T &operator[](size_t idx) const + { + NPNR_ASSERT(idx < m_size); + return data()[idx]; + } +}; + +struct IdStringList +{ + SSOArray<IdString, 4> ids; + + IdStringList(){}; + IdStringList(size_t n) : ids(n, IdString()){}; + IdStringList(IdString id) : ids(1, id){}; + template <typename Tlist> IdStringList(const Tlist &list) : ids(list){}; + + static IdStringList parse(Context *ctx, const std::string &str); + void build_str(const Context *ctx, std::string &str) const; + std::string str(const Context *ctx) const; + + size_t size() const { return ids.size(); } + const IdString *begin() const { return ids.begin(); } + const IdString *end() const { return ids.end(); } + const IdString &operator[](size_t idx) const { return ids[idx]; } + bool operator==(const IdStringList &other) const { return ids == other.ids; } + bool operator!=(const IdStringList &other) const { return ids != other.ids; } + bool operator<(const IdStringList &other) const + { + if (size() > other.size()) + return false; + if (size() < other.size()) + return true; + for (size_t i = 0; i < size(); i++) { + IdString a = ids[i], b = other[i]; + if (a.index < b.index) + return true; + if (a.index > b.index) + return false; + } + return false; + } +}; + +NEXTPNR_NAMESPACE_END + +namespace std { +template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdStringList> +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX IdStringList &obj) const noexcept + { + std::size_t seed = 0; + boost::hash_combine(seed, hash<size_t>()(obj.size())); + for (auto &id : obj) + boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(id)); + return seed; + } +}; +} // namespace std + +NEXTPNR_NAMESPACE_BEGIN + +// A ring buffer of strings, so we can return a simple const char * pointer for %s formatting - inspired by how logging +// in Yosys works Let's just hope noone tries to log more than 100 things in one call.... +class StrRingBuffer +{ + private: + static const size_t N = 100; + std::array<std::string, N> buffer; + size_t index = 0; + + public: + std::string &next(); +}; + struct GraphicElement { enum type_t @@ -667,6 +813,9 @@ struct BaseCtx mutable std::unordered_map<std::string, int> *idstring_str_to_idx; mutable std::vector<const std::string *> *idstring_idx_to_str; + // Temporary string backing store for logging + mutable StrRingBuffer log_strs; + // Project settings and config switches std::unordered_map<IdString, Property> settings; @@ -782,6 +931,12 @@ struct BaseCtx const char *nameOfPip(PipId pip) const; const char *nameOfGroup(GroupId group) const; + // Wrappers of arch functions that take a string and handle IdStringList parsing + BelId getBelByNameStr(const std::string &str); + WireId getWireByNameStr(const std::string &str); + PipId getPipByNameStr(const std::string &str); + GroupId getGroupByNameStr(const std::string &str); + // -------------------------------------------------------------- bool allUiReload = true; |