Merge pull request #4425 from YosysHQ/emil/doc-sigmap

sigmap: comments
This commit is contained in:
Emil J 2024-07-29 10:18:44 +02:00 committed by GitHub
commit 49eaa108a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 0 deletions

View File

@ -1129,6 +1129,11 @@ public:
const_iterator end() const { return const_iterator(*this, offset + size()); } const_iterator end() const { return const_iterator(*this, offset + size()); }
}; };
/**
* Union-find data structure with a promotion method
* mfp stands for "merge, find, promote"
* i-prefixed methods operate on indices in parents
*/
template<typename K, typename OPS> template<typename K, typename OPS>
class mfp class mfp
{ {
@ -1142,13 +1147,18 @@ public:
{ {
} }
// Finds a given element's index. If it isn't in the data structure,
// it is added as its own set
int operator()(const K &key) const int operator()(const K &key) const
{ {
int i = database(key); int i = database(key);
// If the lookup caused the database to grow,
// also add a corresponding entry in parents initialized to -1 (no parent)
parents.resize(database.size(), -1); parents.resize(database.size(), -1);
return i; return i;
} }
// Finds an element at given index
const K &operator[](int index) const const K &operator[](int index) const
{ {
return database[index]; return database[index];
@ -1161,6 +1171,11 @@ public:
while (parents[p] != -1) while (parents[p] != -1)
p = parents[p]; p = parents[p];
// p is now the representative of i
// Now we traverse from i up to the representative again
// and make p the parent of all the nodes along the way.
// This is a side effect and doesn't affect the return value.
// It speeds up future find operations
while (k != p) { while (k != p) {
int next_k = parents[k]; int next_k = parents[k];
parents[k] = p; parents[k] = p;
@ -1170,6 +1185,7 @@ public:
return p; return p;
} }
// Merge sets if the given indices belong to different sets
void imerge(int i, int j) void imerge(int i, int j)
{ {
i = ifind(i); i = ifind(i);

View File

@ -229,6 +229,13 @@ using sort_by_name_id_guard = typename std::enable_if<std::is_same<T,RTLIL::Cell
template<typename T> template<typename T>
class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name_id<typename std::remove_pointer<T>::type>> {}; class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name_id<typename std::remove_pointer<T>::type>> {};
/**
* SigMap wraps a union-find "database"
* to map SigBits of a module to canonical representative SigBits.
* SigBits that are connected share a set in the underlying database.
* If a SigBit has a const state (impl: bit.wire is nullptr),
* it's promoted to a representative.
*/
struct SigMap struct SigMap
{ {
mfp<SigBit> database; mfp<SigBit> database;
@ -249,6 +256,7 @@ struct SigMap
database.clear(); database.clear();
} }
// Rebuild SigMap for all connections in module
void set(RTLIL::Module *module) void set(RTLIL::Module *module)
{ {
int bitcount = 0; int bitcount = 0;
@ -262,6 +270,7 @@ struct SigMap
add(it.first, it.second); add(it.first, it.second);
} }
// Add connections from "from" to "to", bit-by-bit
void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to) void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to)
{ {
log_assert(GetSize(from) == GetSize(to)); log_assert(GetSize(from) == GetSize(to));
@ -287,6 +296,7 @@ struct SigMap
} }
} }
// Add sig as disconnected from anything
void add(const RTLIL::SigBit &bit) void add(const RTLIL::SigBit &bit)
{ {
const auto &b = database.find(bit); const auto &b = database.find(bit);
@ -302,6 +312,7 @@ struct SigMap
inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); } inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); }
// Modify bit to its representative
void apply(RTLIL::SigBit &bit) const void apply(RTLIL::SigBit &bit) const
{ {
bit = database.find(bit); bit = database.find(bit);
@ -332,6 +343,7 @@ struct SigMap
return sig; return sig;
} }
// All non-const bits
RTLIL::SigSpec allbits() const RTLIL::SigSpec allbits() const
{ {
RTLIL::SigSpec sig; RTLIL::SigSpec sig;