Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sigmap: comments #4425

Merged
merged 1 commit into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions kernel/hashlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,11 @@ class idict
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>
class mfp
{
Expand All @@ -1142,13 +1147,18 @@ class mfp
{
}

// 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 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);
return i;
}

// Finds an element at given index
const K &operator[](int index) const
{
return database[index];
Expand All @@ -1161,6 +1171,11 @@ class mfp
while (parents[p] != -1)
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) {
int next_k = parents[k];
parents[k] = p;
Expand All @@ -1170,6 +1185,7 @@ class mfp
return p;
}

// Merge sets if the given indices belong to different sets
void imerge(int i, int j)
{
i = ifind(i);
Expand Down
12 changes: 12 additions & 0 deletions kernel/sigtools.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ using sort_by_name_id_guard = typename std::enable_if<std::is_same<T,RTLIL::Cell
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>> {};

/**
* 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
{
mfp<SigBit> database;
Expand All @@ -249,6 +256,7 @@ struct SigMap
database.clear();
}

// Rebuild SigMap for all connections in module
void set(RTLIL::Module *module)
{
int bitcount = 0;
Expand All @@ -262,6 +270,7 @@ struct SigMap
add(it.first, it.second);
}

// Add connections from "from" to "to", bit-by-bit
void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to)
{
log_assert(GetSize(from) == GetSize(to));
Expand All @@ -287,6 +296,7 @@ struct SigMap
}
}

// Add sig as disconnected from anything
void add(const RTLIL::SigBit &bit)
{
const auto &b = database.find(bit);
Expand All @@ -302,6 +312,7 @@ struct SigMap

inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); }

// Modify bit to its representative
void apply(RTLIL::SigBit &bit) const
{
bit = database.find(bit);
Expand Down Expand Up @@ -332,6 +343,7 @@ struct SigMap
return sig;
}

// All non-const bits
RTLIL::SigSpec allbits() const
{
RTLIL::SigSpec sig;
Expand Down
Loading