180 lines
5.4 KiB
C++
180 lines
5.4 KiB
C++
/*
|
|
* 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<int32_t> 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<Cell> 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<IdString, IdString> belPins; // Cell to BEL pin mapping
|
|
};
|
|
|
|
bool isValid; // Validity flag
|
|
std::vector<Cell> cells; // Cell data
|
|
|
|
pool<std::pair<IdString, IdString>> 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<SiteLutMappingKey, SiteLutMappingResult> cache_; // The cache
|
|
|
|
size_t numHits = 0; // Hit count
|
|
size_t numMisses = 0; // Miss count
|
|
};
|
|
|
|
NEXTPNR_NAMESPACE_END
|
|
|
|
#endif /* SITE_LUT_MAPPING_CACHE_H */
|