mirror of https://github.com/YosysHQ/yosys.git
commit
49eaa108a5
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue