Added more code comments, formatted the code

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2021-07-16 16:01:21 +02:00
parent ccf2bb123c
commit 8fc16a57c9
6 changed files with 120 additions and 119 deletions

View File

@ -814,8 +814,10 @@ bool Arch::place()
archInfoToAttributes(); archInfoToAttributes();
// Print site LUT mapping caching stats // Print site LUT mapping caching stats
log_info("Site LUT mapping cache miss ratio: %.1f%%\n", log_info("Site LUT mapping cache stats:\n");
getCtx()->site_lut_mapping_cache.getMissRatio() * 100.0f); log_info(" miss ratio: %.1f%%\n", getCtx()->site_lut_mapping_cache.getMissRatio() * 100.0f);
log_info(" peak size : %zuMB (%zu items)\n", getCtx()->site_lut_mapping_cache.getSizeMB(),
getCtx()->site_lut_mapping_cache.getCount());
getCtx()->check(); getCtx()->check();

View File

@ -255,7 +255,8 @@ uint32_t LutMapper::check_wires(const std::vector<std::vector<int32_t>> &bel_to_
return vcc_mask; return vcc_mask;
} }
bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult* lut_mapping, pool<const LutBel *, hash_ptr_ops> *blocked_luts) bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult *lut_mapping,
pool<const LutBel *, hash_ptr_ops> *blocked_luts)
{ {
dict<NetInfo *, LutPin, hash_ptr_ops> lut_pin_map; dict<NetInfo *, LutPin, hash_ptr_ops> lut_pin_map;
std::vector<const LutBel *> lut_bels; std::vector<const LutBel *> lut_bels;

View File

@ -70,12 +70,12 @@ struct LutBel
struct SiteLutMapping struct SiteLutMapping
{ {
struct LutCellMapping { struct LutCellMapping
{
LutCell lut_cell; LutCell lut_cell;
}; };
}; };
// Work forward from cell definition and cell -> bel pin map and check that // Work forward from cell definition and cell -> bel pin map and check that
// equation is valid. // equation is valid.
void check_equation(const LutCell &lut_cell, const dict<IdString, IdString> &cell_to_bel_map, const LutBel &lut_bel, void check_equation(const LutCell &lut_cell, const dict<IdString, IdString> &cell_to_bel_map, const LutBel &lut_bel,
@ -99,7 +99,8 @@ struct LutMapper
std::vector<CellInfo *> cells; std::vector<CellInfo *> cells;
bool remap_luts(const Context *ctx, SiteLutMappingResult* lut_mapping, pool<const LutBel *, hash_ptr_ops> *blocked_luts); bool remap_luts(const Context *ctx, SiteLutMappingResult *lut_mapping,
pool<const LutBel *, hash_ptr_ops> *blocked_luts);
// Determine which wires given the current mapping must be tied to the // Determine which wires given the current mapping must be tied to the
// default constant. // default constant.

View File

@ -17,23 +17,22 @@
* *
*/ */
#include "nextpnr.h"
#include "archdefs.h"
#include "site_arch.h"
#include "site_lut_mapping_cache.h" #include "site_lut_mapping_cache.h"
#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
// ============================================================================ // ============================================================================
SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) { SiteLutMappingKey SiteLutMappingKey::create(const SiteInformation &siteInfo)
{
const Context *ctx = siteInfo.ctx; const Context *ctx = siteInfo.ctx;
// Look for LUT cells in the site // Look for LUT cells in the site
std::vector<CellInfo*> lutCells; std::vector<CellInfo *> lutCells;
lutCells.reserve(siteInfo.cells_in_site.size()); lutCells.reserve(siteInfo.cells_in_site.size());
for (CellInfo* cellInfo : siteInfo.cells_in_site) { for (CellInfo *cellInfo : siteInfo.cells_in_site) {
// Not a LUT cell // Not a LUT cell
if (cellInfo->lut_cell.pins.empty()) { if (cellInfo->lut_cell.pins.empty()) {
@ -52,10 +51,7 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
// Sort cells by BEL indices to maintain always the same order // Sort cells by BEL indices to maintain always the same order
std::sort(lutCells.begin(), lutCells.end(), std::sort(lutCells.begin(), lutCells.end(),
[](const CellInfo* a, const CellInfo* b) [](const CellInfo *a, const CellInfo *b) { return a->bel.index > b->bel.index; });
{
return a->bel.index > b->bel.index;
});
// Initialize the key // Initialize the key
SiteLutMappingKey key; SiteLutMappingKey key;
@ -67,10 +63,10 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
// to get always the same key for the same LUT port configuration even // to get always the same key for the same LUT port configuration even
// when the actual global net names are different. // when the actual global net names are different.
dict<IdString, int32_t> netMap; dict<IdString, int32_t> netMap;
for (CellInfo* cellInfo : lutCells) { for (CellInfo *cellInfo : lutCells) {
NPNR_ASSERT(key.numCells < SiteLutMappingKey::MAX_LUT_CELLS); NPNR_ASSERT(key.numCells < SiteLutMappingKey::MAX_LUT_CELLS);
auto& cell = key.cells[key.numCells++]; auto &cell = key.cells[key.numCells++];
cell.type = cellInfo->type; cell.type = cellInfo->type;
cell.belIndex = cellInfo->bel.index; cell.belIndex = cellInfo->bel.index;
@ -78,8 +74,8 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
cell.conns.fill(0); cell.conns.fill(0);
size_t portId = 0; size_t portId = 0;
for (const auto& port : cellInfo->ports) { for (const auto &port : cellInfo->ports) {
const auto& portInfo = port.second; const auto &portInfo = port.second;
// Consider only LUT inputs // Consider only LUT inputs
if (portInfo.type != PORT_IN) { if (portInfo.type != PORT_IN) {
@ -94,8 +90,7 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
auto it = netMap.find(netInfo->name); auto it = netMap.find(netInfo->name);
if (it != netMap.end()) { if (it != netMap.end()) {
netId = it->second; netId = it->second;
} } else {
else {
netId = (int32_t)netMap.size() + 1; netId = (int32_t)netMap.size() + 1;
netMap[netInfo->name] = netId; netMap[netInfo->name] = netId;
} }
@ -114,16 +109,16 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
// ============================================================================ // ============================================================================
bool SiteLutMappingResult::apply(const SiteInformation &siteInfo)
{
bool SiteLutMappingResult::apply (const SiteInformation& siteInfo) { Context *ctx = const_cast<Context *>(siteInfo.ctx);
Context *ctx = const_cast<Context*>(siteInfo.ctx);
TileStatus &tileStatus = ctx->get_tile_status(siteInfo.tile); TileStatus &tileStatus = ctx->get_tile_status(siteInfo.tile);
for (auto& cell : cells) { for (auto &cell : cells) {
// Get the bound cell // Get the bound cell
CellInfo* cellInfo = tileStatus.boundcells[cell.belIndex]; CellInfo *cellInfo = tileStatus.boundcells[cell.belIndex];
NPNR_ASSERT(cellInfo); NPNR_ASSERT(cellInfo);
// Double check BEL binding // Double check BEL binding
@ -133,7 +128,7 @@ bool SiteLutMappingResult::apply (const SiteInformation& siteInfo) {
// Cell <-> BEL pin map // Cell <-> BEL pin map
size_t numPins = cellInfo->lut_cell.pins.size(); size_t numPins = cellInfo->lut_cell.pins.size();
for (size_t pinIdx = 0; pinIdx < numPins; ++pinIdx) { for (size_t pinIdx = 0; pinIdx < numPins; ++pinIdx) {
const IdString& cellPin = cellInfo->lut_cell.pins[pinIdx]; const IdString &cellPin = cellInfo->lut_cell.pins[pinIdx];
auto &belPins = cellInfo->cell_bel_pins[cellPin]; auto &belPins = cellInfo->cell_bel_pins[cellPin];
// There is only one pin // There is only one pin
@ -149,14 +144,15 @@ bool SiteLutMappingResult::apply (const SiteInformation& siteInfo) {
return true; return true;
} }
size_t SiteLutMappingResult::getSizeInBytes () const { size_t SiteLutMappingResult::getSizeInBytes() const
{
size_t size = 0; size_t size = 0;
size += sizeof(SiteLutMappingResult); size += sizeof(SiteLutMappingResult);
size += blockedWires.size() * sizeof(std::pair<IdString, IdString>); size += blockedWires.size() * sizeof(std::pair<IdString, IdString>);
for (const auto& cell : cells) { for (const auto &cell : cells) {
size += sizeof(Cell); size += sizeof(Cell);
size += cell.belPins.size() * sizeof(decltype(cell.belPins)::value_type); size += cell.belPins.size() * sizeof(decltype(cell.belPins)::value_type);
} }
@ -166,14 +162,12 @@ size_t SiteLutMappingResult::getSizeInBytes () const {
// ============================================================================ // ============================================================================
void SiteLutMappingCache::add (const SiteLutMappingKey& key, void SiteLutMappingCache::add(const SiteLutMappingKey &key, const SiteLutMappingResult &result)
const SiteLutMappingResult& result)
{ {
cache_[key] = result; cache_[key] = result;
} }
bool SiteLutMappingCache::get (const SiteLutMappingKey& key, bool SiteLutMappingCache::get(const SiteLutMappingKey &key, SiteLutMappingResult *result)
SiteLutMappingResult* result)
{ {
if (cache_.count(key) == 0) { if (cache_.count(key) == 0) {
numMisses++; numMisses++;
@ -185,12 +179,14 @@ bool SiteLutMappingCache::get (const SiteLutMappingKey& key,
return true; return true;
} }
void SiteLutMappingCache::clear () { void SiteLutMappingCache::clear()
{
cache_.clear(); cache_.clear();
clearStats(); clearStats();
} }
void SiteLutMappingCache::clearStats () { void SiteLutMappingCache::clearStats()
{
numHits = 0; numHits = 0;
numMisses = 0; numMisses = 0;
} }
@ -198,4 +194,3 @@ void SiteLutMappingCache::clearStats () {
// ============================================================================ // ============================================================================
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -20,13 +20,15 @@
#ifndef SITE_LUT_MAPPING_CACHE_H #ifndef SITE_LUT_MAPPING_CACHE_H
#define SITE_LUT_MAPPING_CACHE_H #define SITE_LUT_MAPPING_CACHE_H
#include "idstring.h"
#include "nextpnr_namespaces.h" #include "nextpnr_namespaces.h"
#include "idstring.h"
#include "site_arch.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
// Key structure used in site LUT mapping cache // Key structure used in site LUT mapping cache
struct SiteLutMappingKey { struct SiteLutMappingKey
{
// Maximum number of LUT cells per site // Maximum number of LUT cells per site
static constexpr size_t MAX_LUT_CELLS = 8; static constexpr size_t MAX_LUT_CELLS = 8;
@ -34,7 +36,8 @@ struct SiteLutMappingKey {
static constexpr size_t MAX_LUT_INPUTS = 6; static constexpr size_t MAX_LUT_INPUTS = 6;
// LUT Cell data // LUT Cell data
struct Cell { struct Cell
{
IdString type; // Cell type IdString type; // Cell type
int32_t belIndex; // Bound BEL index int32_t belIndex; // Bound BEL index
@ -43,16 +46,14 @@ struct SiteLutMappingKey {
// net names. the Id 0 means unconnected. // net names. the Id 0 means unconnected.
std::array<int32_t, MAX_LUT_INPUTS> conns; std::array<int32_t, MAX_LUT_INPUTS> conns;
bool operator == (const Cell& other) const { bool operator==(const Cell &other) const
return (type == other.type) && {
(belIndex == other.belIndex) && return (type == other.type) && (belIndex == other.belIndex) && (conns == other.conns);
(conns == other.conns);
} }
bool operator != (const Cell& other) const { bool operator!=(const Cell &other) const
return (type != other.type) || {
(belIndex != other.belIndex) || return (type != other.type) || (belIndex != other.belIndex) || (conns != other.conns);
(conns != other.conns);
} }
}; };
@ -63,32 +64,36 @@ struct SiteLutMappingKey {
unsigned int hash_; // Precomputed hash unsigned int hash_; // Precomputed hash
static SiteLutMappingKey create (const SiteInformation& siteInfo); // Creates a key from the given site state
static SiteLutMappingKey create(const SiteInformation &siteInfo);
size_t getSizeInBytes () const { // Returns size in bytes of the key
return sizeof(SiteLutMappingKey); size_t getSizeInBytes() const { return sizeof(SiteLutMappingKey); }
}
void computeHash () { // Precomputes hash of the key and stores it within
void computeHash()
{
hash_ = mkhash(0, tileType); hash_ = mkhash(0, tileType);
hash_ = mkhash(hash_, siteType); hash_ = mkhash(hash_, siteType);
hash_ = mkhash(hash_, numCells); hash_ = mkhash(hash_, numCells);
for (size_t j=0; j<numCells; ++j) { for (size_t j = 0; j < numCells; ++j) {
const auto& cell = cells[j]; const auto &cell = cells[j];
hash_ = mkhash(hash_, cell.type.index); hash_ = mkhash(hash_, cell.type.index);
hash_ = mkhash(hash_, cell.belIndex); hash_ = mkhash(hash_, cell.belIndex);
for (size_t i=0; i<MAX_LUT_INPUTS; ++i) { for (size_t i = 0; i < MAX_LUT_INPUTS; ++i) {
hash_ = mkhash(hash_, cell.conns[i]); hash_ = mkhash(hash_, cell.conns[i]);
} }
} }
} }
bool compareCells (const SiteLutMappingKey &other) const { // Compares cell data of this and other key
bool compareCells(const SiteLutMappingKey &other) const
{
if (numCells != other.numCells) { if (numCells != other.numCells) {
return false; return false;
} }
for (size_t i=0; i<numCells; ++i) { for (size_t i = 0; i < numCells; ++i) {
if (cells[i] != other.cells[i]) { if (cells[i] != other.cells[i]) {
return false; return false;
} }
@ -96,30 +101,28 @@ struct SiteLutMappingKey {
return true; return true;
} }
bool operator == (const SiteLutMappingKey &other) const { bool operator==(const SiteLutMappingKey &other) const
return (hash_ == other.hash_) && {
(tileType == other.tileType) && return (hash_ == other.hash_) && (tileType == other.tileType) && (siteType == other.siteType) &&
(siteType == other.siteType) &&
compareCells(other); compareCells(other);
} }
bool operator != (const SiteLutMappingKey &other) const { bool operator!=(const SiteLutMappingKey &other) const
return (hash_ != other.hash_) || {
(tileType != other.tileType) || return (hash_ != other.hash_) || (tileType != other.tileType) || (siteType != other.siteType) ||
(siteType != other.siteType) ||
!compareCells(other); !compareCells(other);
} }
unsigned int hash () const { unsigned int hash() const { return hash_; }
return hash_;
}
}; };
// Site LUT mapping result data // Site LUT mapping result data
struct SiteLutMappingResult { struct SiteLutMappingResult
{
// LUT cell data // LUT cell data
struct Cell { struct Cell
{
int32_t belIndex; // BEL in tile index int32_t belIndex; // BEL in tile index
LutCell lutCell; // LUT mapping data LutCell lutCell; // LUT mapping data
dict<IdString, IdString> belPins; // Cell to BEL pin mapping dict<IdString, IdString> belPins; // Cell to BEL pin mapping
@ -128,36 +131,40 @@ struct SiteLutMappingResult {
bool isValid; // Validity flag bool isValid; // Validity flag
std::vector<Cell> cells; // Cell data std::vector<Cell> cells; // Cell data
pool<std::pair<IdString, IdString>> blockedWires; pool<std::pair<IdString, IdString>> blockedWires; // Set of blocked wires
// Applies the mapping result to the site // Applies the mapping result to the site
bool apply (const SiteInformation& siteInfo); bool apply(const SiteInformation &siteInfo);
// Returns size in bytes // Returns size in bytes
size_t getSizeInBytes () const; size_t getSizeInBytes() const;
}; };
// Site LUT mapping cache object // Site LUT mapping cache object
class SiteLutMappingCache { class SiteLutMappingCache
public: {
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);
void add (const SiteLutMappingKey& key, const SiteLutMappingResult& result); // Clears the cache
bool get (const SiteLutMappingKey& key, SiteLutMappingResult* result); void clear();
// Clears statistics counters of the cache
void clearStats();
void clear (); // Return get() miss ratio
void clearStats (); float getMissRatio() const { return (float)numMisses / (float)(numHits + numMisses); }
float getMissRatio () const { // Returns count of entries in the cache
return (float)numMisses / (float)(numHits + numMisses); size_t getCount() const { return cache_.size(); }
}
size_t getCount () const { // Returns size of the cache rounded upwards to full MBs.
return cache_.size(); size_t getSizeMB() const
} {
size_t getSizeMB () const {
size_t size = 0; size_t size = 0;
for (const auto& it : cache_) { for (const auto &it : cache_) {
size += it.first.getSizeInBytes(); size += it.first.getSizeInBytes();
size += it.second.getSizeInBytes(); size += it.second.getSizeInBytes();
} }
@ -166,15 +173,13 @@ public:
return (size + MB - 1) / MB; // Round up to megabytes return (size + MB - 1) / MB; // Round up to megabytes
} }
private: private:
dict<SiteLutMappingKey, SiteLutMappingResult> cache_; // The cache
dict<SiteLutMappingKey, SiteLutMappingResult> cache_; size_t numHits = 0; // Hit count
size_t numMisses = 0; // Miss count
size_t numHits = 0;
size_t numMisses = 0;
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END
#endif /* SITE_LUT_MAPPING_CACHE_H */ #endif /* SITE_LUT_MAPPING_CACHE_H */

View File

@ -1099,10 +1099,7 @@ static bool map_luts_in_site(const SiteInformation &site_info, pool<std::pair<Id
lutMapping.apply(site_info); lutMapping.apply(site_info);
blocked_wires->clear(); blocked_wires->clear();
blocked_wires->insert( blocked_wires->insert(lutMapping.blockedWires.begin(), lutMapping.blockedWires.end());
lutMapping.blockedWires.begin(),
lutMapping.blockedWires.end()
);
} }
return lutMapping.isValid; return lutMapping.isValid;