mirror of https://github.com/YosysHQ/yosys.git
Added hashing to RTLIL::SigSpec relational and equal operators
This commit is contained in:
parent
f368d792fb
commit
82fa356037
|
@ -1411,12 +1411,14 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
|
||||||
RTLIL::SigSpec::SigSpec()
|
RTLIL::SigSpec::SigSpec()
|
||||||
{
|
{
|
||||||
width_ = 0;
|
width_ = 0;
|
||||||
|
hash_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
|
RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
|
||||||
{
|
{
|
||||||
chunks_.push_back(RTLIL::SigChunk(value));
|
chunks_.push_back(RTLIL::SigChunk(value));
|
||||||
width_ = chunks_.back().width;
|
width_ = chunks_.back().width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,6 +1426,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
|
||||||
{
|
{
|
||||||
chunks_.push_back(chunk);
|
chunks_.push_back(chunk);
|
||||||
width_ = chunks_.back().width;
|
width_ = chunks_.back().width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,6 +1434,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
|
||||||
{
|
{
|
||||||
chunks_.push_back(RTLIL::SigChunk(wire));
|
chunks_.push_back(RTLIL::SigChunk(wire));
|
||||||
width_ = chunks_.back().width;
|
width_ = chunks_.back().width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1438,6 +1442,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
|
||||||
{
|
{
|
||||||
chunks_.push_back(RTLIL::SigChunk(wire, offset, width));
|
chunks_.push_back(RTLIL::SigChunk(wire, offset, width));
|
||||||
width_ = chunks_.back().width;
|
width_ = chunks_.back().width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,6 +1450,7 @@ RTLIL::SigSpec::SigSpec(const std::string &str)
|
||||||
{
|
{
|
||||||
chunks_.push_back(RTLIL::SigChunk(str));
|
chunks_.push_back(RTLIL::SigChunk(str));
|
||||||
width_ = chunks_.back().width;
|
width_ = chunks_.back().width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1452,6 +1458,7 @@ RTLIL::SigSpec::SigSpec(int val, int width)
|
||||||
{
|
{
|
||||||
chunks_.push_back(RTLIL::SigChunk(val, width));
|
chunks_.push_back(RTLIL::SigChunk(val, width));
|
||||||
width_ = width;
|
width_ = width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,6 +1466,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
|
||||||
{
|
{
|
||||||
chunks_.push_back(RTLIL::SigChunk(bit, width));
|
chunks_.push_back(RTLIL::SigChunk(bit, width));
|
||||||
width_ = width;
|
width_ = width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,12 +1478,14 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
|
||||||
for (int i = 0; i < width; i++)
|
for (int i = 0; i < width; i++)
|
||||||
chunks_.push_back(bit);
|
chunks_.push_back(bit);
|
||||||
width_ = width;
|
width_ = width;
|
||||||
|
hash_ = 0;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
|
RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
|
||||||
{
|
{
|
||||||
width_ = 0;
|
width_ = 0;
|
||||||
|
hash_ = 0;
|
||||||
for (auto &c : chunks)
|
for (auto &c : chunks)
|
||||||
append(c);
|
append(c);
|
||||||
check();
|
check();
|
||||||
|
@ -1484,6 +1494,7 @@ RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
|
||||||
RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
|
RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
|
||||||
{
|
{
|
||||||
width_ = 0;
|
width_ = 0;
|
||||||
|
hash_ = 0;
|
||||||
for (auto &bit : bits)
|
for (auto &bit : bits)
|
||||||
append_bit(bit);
|
append_bit(bit);
|
||||||
check();
|
check();
|
||||||
|
@ -1492,6 +1503,7 @@ RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
|
||||||
RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
|
RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
|
||||||
{
|
{
|
||||||
width_ = 0;
|
width_ = 0;
|
||||||
|
hash_ = 0;
|
||||||
for (auto &bit : bits)
|
for (auto &bit : bits)
|
||||||
append_bit(bit);
|
append_bit(bit);
|
||||||
check();
|
check();
|
||||||
|
@ -1529,11 +1541,34 @@ void RTLIL::SigSpec::unpack() const
|
||||||
that->bits_.push_back(RTLIL::SigBit(c, i));
|
that->bits_.push_back(RTLIL::SigBit(c, i));
|
||||||
|
|
||||||
that->chunks_.clear();
|
that->chunks_.clear();
|
||||||
|
that->hash_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RTLIL::SigSpec::packed() const
|
#define DJB2(_hash, _value) do { (_hash) = (((_hash) << 5) + (_hash)) + (_value); } while (0)
|
||||||
|
|
||||||
|
void RTLIL::SigSpec::hash() const
|
||||||
{
|
{
|
||||||
return bits_.empty();
|
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
|
||||||
|
|
||||||
|
if (that->hash_ != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
that->pack();
|
||||||
|
that->hash_ = 5381;
|
||||||
|
|
||||||
|
for (auto &c : that->chunks_)
|
||||||
|
if (c.wire == NULL) {
|
||||||
|
for (auto &v : c.data.bits)
|
||||||
|
DJB2(that->hash_, v);
|
||||||
|
} else {
|
||||||
|
for (auto &v : c.wire->name)
|
||||||
|
DJB2(that->hash_, v);
|
||||||
|
DJB2(that->hash_, c.offset);
|
||||||
|
DJB2(that->hash_, c.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (that->hash_ == 0)
|
||||||
|
that->hash_ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::sort()
|
void RTLIL::SigSpec::sort()
|
||||||
|
@ -1842,39 +1877,53 @@ void RTLIL::SigSpec::check() const
|
||||||
|
|
||||||
bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
|
bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
|
||||||
{
|
{
|
||||||
pack();
|
if (this == &other)
|
||||||
other.pack();
|
return false;
|
||||||
|
|
||||||
if (width_ != other.width_)
|
if (width_ != other.width_)
|
||||||
return width_ < other.width_;
|
return width_ < other.width_;
|
||||||
|
|
||||||
RTLIL::SigSpec a = *this, b = other;
|
pack();
|
||||||
|
other.pack();
|
||||||
|
|
||||||
if (a.chunks_.size() != b.chunks_.size())
|
if (chunks_.size() != other.chunks_.size())
|
||||||
return a.chunks_.size() < b.chunks_.size();
|
return chunks_.size() < other.chunks_.size();
|
||||||
|
|
||||||
for (size_t i = 0; i < a.chunks_.size(); i++)
|
hash();
|
||||||
if (a.chunks_[i] != b.chunks_[i])
|
other.hash();
|
||||||
return a.chunks_[i] < b.chunks_[i];
|
|
||||||
|
if (hash_ != other.hash_)
|
||||||
|
return hash_ < other.hash_;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < chunks_.size(); i++)
|
||||||
|
if (chunks_[i] != other.chunks_[i])
|
||||||
|
return chunks_[i] < other.chunks_[i];
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
|
bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
|
||||||
{
|
{
|
||||||
pack();
|
if (this == &other)
|
||||||
other.pack();
|
return true;
|
||||||
|
|
||||||
if (width_ != other.width_)
|
if (width_ != other.width_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RTLIL::SigSpec a = *this, b = other;
|
pack();
|
||||||
|
other.pack();
|
||||||
|
|
||||||
if (a.chunks_.size() != b.chunks_.size())
|
if (chunks_.size() != chunks_.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (size_t i = 0; i < a.chunks_.size(); i++)
|
hash();
|
||||||
if (a.chunks_[i] != b.chunks_[i])
|
other.hash();
|
||||||
|
|
||||||
|
if (hash_ != other.hash_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < chunks_.size(); i++)
|
||||||
|
if (chunks_[i] != other.chunks_[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -505,13 +505,18 @@ struct RTLIL::SigSpecIterator {
|
||||||
|
|
||||||
struct RTLIL::SigSpec {
|
struct RTLIL::SigSpec {
|
||||||
private:
|
private:
|
||||||
|
int width_;
|
||||||
|
unsigned long hash_;
|
||||||
std::vector<RTLIL::SigChunk> chunks_; // LSB at index 0
|
std::vector<RTLIL::SigChunk> chunks_; // LSB at index 0
|
||||||
std::vector<RTLIL::SigBit> bits_; // LSB at index 0
|
std::vector<RTLIL::SigBit> bits_; // LSB at index 0
|
||||||
int width_;
|
|
||||||
|
|
||||||
void pack() const;
|
void pack() const;
|
||||||
void unpack() const;
|
void unpack() const;
|
||||||
bool packed() const;
|
void hash() const;
|
||||||
|
|
||||||
|
inline bool packed() const {
|
||||||
|
return bits_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
inline void inline_unpack() const {
|
inline void inline_unpack() const {
|
||||||
if (!chunks_.empty())
|
if (!chunks_.empty())
|
||||||
|
|
Loading…
Reference in New Issue