aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bitpattern.h
diff options
context:
space:
mode:
authorAhmed Irfan <irfan@levert.(none)>2015-04-03 16:38:07 +0200
committerAhmed Irfan <irfan@levert.(none)>2015-04-03 16:38:07 +0200
commitbdf6b2b19ab2206f5957ad5b2ec582c2730d45ee (patch)
tree1d02541701054a1c3b1cdb66478d0cbc31c2d38f /kernel/bitpattern.h
parent8acdd90bc918b780ad45cdac42b3baf84d2cc476 (diff)
parent4b4490761949e738dee54bdfc52e080e0a5c9067 (diff)
downloadyosys-bdf6b2b19ab2206f5957ad5b2ec582c2730d45ee.tar.gz
yosys-bdf6b2b19ab2206f5957ad5b2ec582c2730d45ee.tar.bz2
yosys-bdf6b2b19ab2206f5957ad5b2ec582c2730d45ee.zip
Merge branch 'master' of https://github.com/cliffordwolf/yosys
Diffstat (limited to 'kernel/bitpattern.h')
-rw-r--r--kernel/bitpattern.h89
1 files changed, 57 insertions, 32 deletions
diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h
index 91f54593f..00bbc3bfb 100644
--- a/kernel/bitpattern.h
+++ b/kernel/bitpattern.h
@@ -23,24 +23,46 @@
#include "kernel/log.h"
#include "kernel/rtlil.h"
+YOSYS_NAMESPACE_BEGIN
+
struct BitPatternPool
{
int width;
- typedef std::vector<RTLIL::State> bits_t;
- std::set<bits_t> pool;
+ struct bits_t {
+ std::vector<RTLIL::State> bitdata;
+ unsigned int cached_hash;
+ bits_t(int width = 0) : bitdata(width), cached_hash(0) { }
+ RTLIL::State &operator[](int index) {
+ return bitdata[index];
+ }
+ const RTLIL::State &operator[](int index) const {
+ return bitdata[index];
+ }
+ bool operator==(const bits_t &other) const {
+ if (hash() != other.hash())
+ return false;
+ return bitdata == other.bitdata;
+ }
+ unsigned int hash() const {
+ if (!cached_hash)
+ ((bits_t*)this)->cached_hash = hash_ops<std::vector<RTLIL::State>>::hash(bitdata);
+ return cached_hash;
+ }
+ };
+ pool<bits_t> database;
BitPatternPool(RTLIL::SigSpec sig)
{
width = sig.size();
if (width > 0) {
- std::vector<RTLIL::State> pattern(width);
+ bits_t pattern(width);
for (int i = 0; i < width; i++) {
if (sig[i].wire == NULL && sig[i].data <= RTLIL::State::S1)
pattern[i] = sig[i].data;
else
pattern[i] = RTLIL::State::Sa;
}
- pool.insert(pattern);
+ database.insert(pattern);
}
}
@@ -48,17 +70,18 @@ struct BitPatternPool
{
this->width = width;
if (width > 0) {
- std::vector<RTLIL::State> pattern(width);
+ bits_t pattern(width);
for (int i = 0; i < width; i++)
pattern[i] = RTLIL::State::Sa;
- pool.insert(pattern);
+ database.insert(pattern);
}
}
bits_t sig2bits(RTLIL::SigSpec sig)
{
- bits_t bits = sig.as_const().bits;
- for (auto &b : bits)
+ bits_t bits;
+ bits.bitdata = sig.as_const().bits;
+ for (auto &b : bits.bitdata)
if (b > RTLIL::State::S1)
b = RTLIL::State::Sa;
return bits;
@@ -66,8 +89,8 @@ struct BitPatternPool
bool match(bits_t a, bits_t b)
{
- log_assert(int(a.size()) == width);
- log_assert(int(b.size()) == width);
+ log_assert(int(a.bitdata.size()) == width);
+ log_assert(int(b.bitdata.size()) == width);
for (int i = 0; i < width; i++)
if (a[i] <= RTLIL::State::S1 && b[i] <= RTLIL::State::S1 && a[i] != b[i])
return false;
@@ -77,7 +100,7 @@ struct BitPatternPool
bool has_any(RTLIL::SigSpec sig)
{
bits_t bits = sig2bits(sig);
- for (auto &it : pool)
+ for (auto &it : database)
if (match(it, bits))
return true;
return false;
@@ -86,13 +109,13 @@ struct BitPatternPool
bool has_all(RTLIL::SigSpec sig)
{
bits_t bits = sig2bits(sig);
- for (auto &it : pool)
+ for (auto &it : database)
if (match(it, bits)) {
for (int i = 0; i < width; i++)
if (bits[i] > RTLIL::State::S1 && it[i] <= RTLIL::State::S1)
- goto next_pool_entry;
+ goto next_database_entry;
return true;
- next_pool_entry:;
+ next_database_entry:;
}
return false;
}
@@ -101,36 +124,38 @@ struct BitPatternPool
{
bool status = false;
bits_t bits = sig2bits(sig);
- std::vector<bits_t> pattern_list;
- for (auto &it : pool)
- if (match(it, bits))
- pattern_list.push_back(it);
- for (auto pattern : pattern_list) {
- pool.erase(pattern);
- for (int i = 0; i < width; i++) {
- if (pattern[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa)
- continue;
- bits_t new_pattern = pattern;
- new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1;
- pool.insert(new_pattern);
- }
- status = true;
- }
+ for (auto it = database.begin(); it != database.end();)
+ if (match(*it, bits)) {
+ for (int i = 0; i < width; i++) {
+ if ((*it)[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa)
+ continue;
+ bits_t new_pattern;
+ new_pattern.bitdata = it->bitdata;
+ new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1;
+ database.insert(new_pattern);
+ }
+ it = database.erase(it);
+ status = true;
+ continue;
+ } else
+ ++it;
return status;
}
bool take_all()
{
- if (pool.empty())
+ if (database.empty())
return false;
- pool.clear();
+ database.clear();
return true;
}
bool empty()
{
- return pool.empty();
+ return database.empty();
}
};
+YOSYS_NAMESPACE_END
+
#endif