LUT mapping cache optimizations 1

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2021-07-16 13:28:40 +02:00
parent d52516756c
commit 044c9ba2d4
2 changed files with 48 additions and 32 deletions

View File

@ -73,29 +73,44 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
cell.type = cellInfo->type;
cell.belIndex = cellInfo->bel.index;
memset((void*)cell.conns, 0,
sizeof(int32_t) * SiteLutMappingKey::MAX_LUT_INPUTS);
size_t portId = 0;
for (const auto& port : cellInfo->ports) {
const auto& portInfo = port.second;
// Consider only LUT inputs
if (portInfo.type != PORT_IN) {
continue;
}
// Assign net id if any
int32_t netId = 0;
if (portInfo.net != nullptr) {
auto netInfo = portInfo.net;
int32_t netId = -1;
auto it = netMap.find(netInfo->name);
if (it != netMap.end()) {
netId = it->second;
}
else {
netId = (int32_t)netMap.size();
netId = (int32_t)netMap.size() + 1;
netMap[netInfo->name] = netId;
}
cell.conns[portInfo.name] = netId;
}
NPNR_ASSERT(portId < SiteLutMappingKey::MAX_LUT_INPUTS);
cell.conns[portId++] = netId;
}
// Add the cell entry
key.cells.push_back(cell);
}
// Compute hash
key.computeHash();
return key;
}
@ -120,9 +135,10 @@ bool SiteLutMappingResult::apply (const SiteInformation& siteInfo) {
// Cell <-> BEL pin map
size_t numPins = cellInfo->lut_cell.pins.size();
for (size_t pinIdx = 0; pinIdx < numPins; ++pinIdx) {
IdString cellPin = cellInfo->lut_cell.pins[pinIdx];
auto &belPins = cellInfo->cell_bel_pins[cellPin];
const IdString& cellPin = cellInfo->lut_cell.pins[pinIdx];
auto &belPins = cellInfo->cell_bel_pins[cellPin];
// There is only one pin
belPins.resize(1);
belPins[0] = cell.belPins[cellPin];
}

View File

@ -28,6 +28,11 @@ NEXTPNR_NAMESPACE_BEGIN
// Key structure used in site LUT mapping cache
struct SiteLutMappingKey {
// Maximum number of LUT cells
static constexpr size_t MAX_LUT_CELLS = 8;
// Maximum number of LUT inputs per cell
static constexpr size_t MAX_LUT_INPUTS = 6;
// LUT Cell data
struct Cell {
IdString type; // Cell type
@ -35,51 +40,46 @@ struct SiteLutMappingKey {
// Port to net assignments. These are local net ids generated during
// key creation. This is to abstract connections from actual design
// net names.
dict<IdString, 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 belIndex < other.belIndex;
}
// net names. the Id 0 means unconnected.
int32_t conns [MAX_LUT_INPUTS];
};
int32_t tileType; // Tile type
int32_t siteType; // Site type in that tile type
std::vector<Cell> cells; // LUT cell data
unsigned int hash_; // Precomputed hash
static SiteLutMappingKey create (const SiteInformation& siteInfo);
void computeHash () {
hash_ = mkhash(0, tileType);
hash_ = mkhash(hash_, siteType);
for (const auto& cell : cells) {
hash_ = mkhash(hash_, cell.type.index);
hash_ = mkhash(hash_, cell.belIndex);
for (size_t i=0; i<MAX_LUT_INPUTS; ++i) {
hash_ = mkhash(hash_, cell.conns[i]);
}
}
}
bool operator == (const SiteLutMappingKey &other) const {
return (tileType == other.tileType) &&
return (hash_ == other.hash_) &&
(tileType == other.tileType) &&
(siteType == other.siteType) &&
(cells == other.cells);
}
bool operator != (const SiteLutMappingKey &other) const {
return (tileType != other.tileType) ||
return (hash_ != other.hash_) ||
(tileType != other.tileType) ||
(siteType != other.siteType) ||
(cells != other.cells);
}
unsigned int hash () const {
unsigned int h = 0;
h = mkhash(h, tileType);
h = mkhash(h, siteType);
for (const auto& cell : cells) {
h = mkhash(h, cell.type.index);
h = mkhash(h, cell.belIndex);
for (const auto& conn : cell.conns) {
h = mkhash(h, conn.first.index);
h = mkhash(h, conn.second);
}
}
return h;
return hash_;
}
};