/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2021 Symbiflow Authors * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef SITE_LUT_MAPPING_CACHE_H #define SITE_LUT_MAPPING_CACHE_H #include "idstring.h" #include "nextpnr_namespaces.h" #include "site_arch.h" NEXTPNR_NAMESPACE_BEGIN // Key structure used in site LUT mapping cache struct SiteLutMappingKey { // LUT Cell data struct Cell { IdString type; // Cell type int32_t belIndex; // Bound BEL index // Port to net assignments. These are local net ids generated during // key creation. This is to abstract connections from actual design // net names. the Id 0 means unconnected. std::vector conns; bool operator==(const Cell &other) const { return (type == other.type) && (belIndex == other.belIndex) && (conns == other.conns); } bool operator!=(const Cell &other) const { return (type != other.type) || (belIndex != other.belIndex) || (conns != other.conns); } }; int32_t tileType; // Tile type int32_t siteType; // Site type in that tile type size_t numCells; // LUT cell count std::vector cells; // LUT cell data unsigned int hash_; // Precomputed hash // Creates a key from the given site state static SiteLutMappingKey create(const SiteInformation &siteInfo); // Returns size in bytes of the key size_t getSizeInBytes() const { return sizeof(SiteLutMappingKey); } // Precomputes hash of the key and stores it within void computeHash() { hash_ = mkhash(0, tileType); hash_ = mkhash(hash_, siteType); hash_ = mkhash(hash_, numCells); for (size_t j = 0; j < numCells; ++j) { const auto &cell = cells[j]; hash_ = mkhash(hash_, cell.type.index); hash_ = mkhash(hash_, cell.belIndex); for (size_t i = 0; i < cell.conns.size(); ++i) { hash_ = mkhash(hash_, cell.conns[i]); } } } // Compares cell data of this and other key bool compareCells(const SiteLutMappingKey &other) const { if (numCells != other.numCells) { return false; } for (size_t i = 0; i < numCells; ++i) { if (cells[i] != other.cells[i]) { return false; } } return true; } bool operator==(const SiteLutMappingKey &other) const { return (hash_ == other.hash_) && (tileType == other.tileType) && (siteType == other.siteType) && compareCells(other); } bool operator!=(const SiteLutMappingKey &other) const { return (hash_ != other.hash_) || (tileType != other.tileType) || (siteType != other.siteType) || !compareCells(other); } unsigned int hash() const { return hash_; } }; // Site LUT mapping result data struct SiteLutMappingResult { // LUT cell data struct Cell { int32_t belIndex; // BEL in tile index LutCell lutCell; // LUT mapping data dict belPins; // Cell to BEL pin mapping }; bool isValid; // Validity flag std::vector cells; // Cell data pool> blockedWires; // Set of blocked wires // Applies the mapping result to the site bool apply(const SiteInformation &siteInfo); // Returns size in bytes size_t getSizeInBytes() const; }; // Site LUT mapping cache object class SiteLutMappingCache { public: // Adds an entry to the cache void add(const SiteLutMappingKey &key, const SiteLutMappingResult &result); // Retrieves an entry from the cache. Returns false if not found bool get(const SiteLutMappingKey &key, SiteLutMappingResult *result); // Clears the cache void clear(); // Clears statistics counters of the cache void clearStats(); // Return get() miss ratio float getMissRatio() const { return (float)numMisses / (float)(numHits + numMisses); } // Returns count of entries in the cache size_t getCount() const { return cache_.size(); } // Returns size of the cache rounded upwards to full MBs. size_t getSizeMB() const { size_t size = 0; for (const auto &it : cache_) { size += it.first.getSizeInBytes(); size += it.second.getSizeInBytes(); } const size_t MB = 1024L * 1024L; return (size + MB - 1) / MB; // Round up to megabytes } private: dict cache_; // The cache size_t numHits = 0; // Hit count size_t numMisses = 0; // Miss count }; NEXTPNR_NAMESPACE_END #endif /* SITE_LUT_MAPPING_CACHE_H */