mirror of
https://github.com/YosysHQ/yosys
synced 2025-08-03 01:40:23 +00:00
Merge a54a673586
into 262b00d5e5
This commit is contained in:
commit
47ec9833af
5 changed files with 728 additions and 517 deletions
|
@ -27,10 +27,10 @@ YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct FfInitVals
|
struct FfInitVals
|
||||||
{
|
{
|
||||||
const SigMap *sigmap;
|
const SigMapView *sigmap;
|
||||||
dict<SigBit, std::pair<State,SigBit>> initbits;
|
dict<SigBit, std::pair<State,SigBit>> initbits;
|
||||||
|
|
||||||
void set(const SigMap *sigmap_, RTLIL::Module *module)
|
void set(const SigMapView *sigmap_, RTLIL::Module *module)
|
||||||
{
|
{
|
||||||
sigmap = sigmap_;
|
sigmap = sigmap_;
|
||||||
initbits.clear();
|
initbits.clear();
|
||||||
|
@ -126,7 +126,7 @@ struct FfInitVals
|
||||||
initbits.clear();
|
initbits.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FfInitVals (const SigMap *sigmap, RTLIL::Module *module)
|
FfInitVals (const SigMapView *sigmap, RTLIL::Module *module)
|
||||||
{
|
{
|
||||||
set(sigmap, module);
|
set(sigmap, module);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct FfMergeHelper
|
struct FfMergeHelper
|
||||||
{
|
{
|
||||||
const SigMap *sigmap;
|
const SigMapView *sigmap;
|
||||||
RTLIL::Module *module;
|
RTLIL::Module *module;
|
||||||
FfInitVals *initvals;
|
FfInitVals *initvals;
|
||||||
|
|
||||||
|
|
|
@ -1327,7 +1327,8 @@ public:
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge sets if the given indices belong to different sets
|
// Merge sets if the given indices belong to different sets.
|
||||||
|
// Makes ifind(j) the root of the merged set.
|
||||||
void imerge(int i, int j)
|
void imerge(int i, int j)
|
||||||
{
|
{
|
||||||
i = ifind(i);
|
i = ifind(i);
|
||||||
|
|
|
@ -237,6 +237,42 @@ 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>> {};
|
||||||
|
|
||||||
|
struct SigMapView
|
||||||
|
{
|
||||||
|
mfp<SigBit> database;
|
||||||
|
|
||||||
|
// Modify bit to its representative
|
||||||
|
void apply(RTLIL::SigBit &bit) const
|
||||||
|
{
|
||||||
|
bit = database.find(bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(RTLIL::SigSpec &sig) const
|
||||||
|
{
|
||||||
|
for (auto &bit : sig)
|
||||||
|
apply(bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::SigBit operator()(RTLIL::SigBit bit) const
|
||||||
|
{
|
||||||
|
apply(bit);
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const
|
||||||
|
{
|
||||||
|
apply(sig);
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::SigSpec operator()(RTLIL::Wire *wire) const
|
||||||
|
{
|
||||||
|
SigSpec sig(wire);
|
||||||
|
apply(sig);
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SigMap wraps a union-find "database"
|
* SigMap wraps a union-find "database"
|
||||||
* to map SigBits of a module to canonical representative SigBits.
|
* to map SigBits of a module to canonical representative SigBits.
|
||||||
|
@ -244,10 +280,8 @@ class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name
|
||||||
* If a SigBit has a const state (impl: bit.wire is nullptr),
|
* If a SigBit has a const state (impl: bit.wire is nullptr),
|
||||||
* it's promoted to a representative.
|
* it's promoted to a representative.
|
||||||
*/
|
*/
|
||||||
struct SigMap
|
struct SigMap final : public SigMapView
|
||||||
{
|
{
|
||||||
mfp<SigBit> database;
|
|
||||||
|
|
||||||
SigMap(RTLIL::Module *module = NULL)
|
SigMap(RTLIL::Module *module = NULL)
|
||||||
{
|
{
|
||||||
if (module != NULL)
|
if (module != NULL)
|
||||||
|
@ -320,37 +354,6 @@ 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
|
|
||||||
{
|
|
||||||
bit = database.find(bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(RTLIL::SigSpec &sig) const
|
|
||||||
{
|
|
||||||
for (auto &bit : sig)
|
|
||||||
apply(bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
RTLIL::SigBit operator()(RTLIL::SigBit bit) const
|
|
||||||
{
|
|
||||||
apply(bit);
|
|
||||||
return bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const
|
|
||||||
{
|
|
||||||
apply(sig);
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
RTLIL::SigSpec operator()(RTLIL::Wire *wire) const
|
|
||||||
{
|
|
||||||
SigSpec sig(wire);
|
|
||||||
apply(sig);
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// All non-const bits
|
// All non-const bits
|
||||||
RTLIL::SigSpec allbits() const
|
RTLIL::SigSpec allbits() const
|
||||||
{
|
{
|
||||||
|
@ -362,6 +365,107 @@ struct SigMap
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SiValgMap wraps a union-find "database" to map SigBits of a module to
|
||||||
|
* canonical representative SigBits plus some optional Val value associated with the bits.
|
||||||
|
* Val has a commutative, associative, idempotent operator|=, a default constructor
|
||||||
|
* which constructs an identity element, and a copy constructor.
|
||||||
|
* SigBits that are connected share a set in the underlying database;
|
||||||
|
* the associated value is the "sum" of all the values associated with the contributing bits.
|
||||||
|
* If any of the SigBits in a set are a constant, the canonical SigBit is a constant.
|
||||||
|
*/
|
||||||
|
template <class Val>
|
||||||
|
struct SigValMap final : public SigMapView
|
||||||
|
{
|
||||||
|
dict<SigBit, Val> values;
|
||||||
|
|
||||||
|
void swap(SigValMap<Val> &other)
|
||||||
|
{
|
||||||
|
database.swap(other.database);
|
||||||
|
values.swap(other.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
database.clear();
|
||||||
|
values.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild SigMap for all connections in module
|
||||||
|
void set(RTLIL::Module *module)
|
||||||
|
{
|
||||||
|
int bitcount = 0;
|
||||||
|
for (auto &it : module->connections())
|
||||||
|
bitcount += it.first.size();
|
||||||
|
|
||||||
|
database.clear();
|
||||||
|
values.clear();
|
||||||
|
database.reserve(bitcount);
|
||||||
|
|
||||||
|
for (auto &it : module->connections())
|
||||||
|
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));
|
||||||
|
|
||||||
|
for (int i = 0; i < GetSize(from); i++)
|
||||||
|
{
|
||||||
|
int bfi = database.lookup(from[i]);
|
||||||
|
int bti = database.lookup(to[i]);
|
||||||
|
if (bfi == bti) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RTLIL::SigBit &bf = database[bfi];
|
||||||
|
const RTLIL::SigBit &bt = database[bti];
|
||||||
|
if (bf.wire == nullptr) {
|
||||||
|
// bf is constant so make it the canonical representative.
|
||||||
|
database.imerge(bti, bfi);
|
||||||
|
merge_value(bt, bf);
|
||||||
|
} else {
|
||||||
|
// Make bt the canonical representative.
|
||||||
|
database.imerge(bfi, bti);
|
||||||
|
merge_value(bf, bt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addVal(const RTLIL::SigBit &bit, const Val &val)
|
||||||
|
{
|
||||||
|
values[database.find(bit)] |= val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addVal(const RTLIL::SigSpec &sig, const Val &val)
|
||||||
|
{
|
||||||
|
for (const auto &bit : sig)
|
||||||
|
addVal(bit, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
Val apply_and_get_value(RTLIL::SigBit &bit) const
|
||||||
|
{
|
||||||
|
bit = database.find(bit);
|
||||||
|
auto it = values.find(bit);
|
||||||
|
return it == values.end() ? Val() : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void merge_value(const RTLIL::SigBit &from, const RTLIL::SigBit &to)
|
||||||
|
{
|
||||||
|
auto it = values.find(from);
|
||||||
|
if (it == values.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// values[to] could resize the underlying `entries` so
|
||||||
|
// finish using `it` first.
|
||||||
|
Val v = it->second;
|
||||||
|
values.erase(it);
|
||||||
|
values[to] |= v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* SIGTOOLS_H */
|
#endif /* SIGTOOLS_H */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue