summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-07-26 13:59:30 +0200
committerClifford Wolf <clifford@clifford.at>2014-07-26 13:59:30 +0200
commit3719281ed44aa9d8b2ac11eb936b750c4642be38 (patch)
tree7f412fda8c279d9cf7aacef7da404dff6c18c82f
parente75e495c2bddb62634c6d50f90e09e0ff358faa5 (diff)
Automatically pack SigSpec on copy/assign
-rw-r--r--kernel/rtlil.cc77
-rw-r--r--kernel/rtlil.h3
2 files changed, 63 insertions, 17 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 27063aea..2378e95c 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1518,6 +1518,48 @@ RTLIL::SigSpec::SigSpec()
hash_ = 0;
}
+RTLIL::SigSpec::SigSpec(const RTLIL::SigSpec &other)
+{
+ *this = other;
+}
+
+const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
+{
+ cover("kernel.rtlil.sigspec.assign");
+
+ width_ = other.width_;
+ hash_ = other.hash_;
+ chunks_ = other.chunks_;
+ bits_.clear();
+
+ if (!other.bits_.empty())
+ {
+ RTLIL::SigChunk *last = NULL;
+ int last_end_offset = 0;
+
+ for (auto &bit : other.bits_) {
+ if (last && bit.wire == last->wire) {
+ if (bit.wire == NULL) {
+ last->data.bits.push_back(bit.data);
+ last->width++;
+ continue;
+ } else if (last_end_offset == bit.offset) {
+ last_end_offset++;
+ last->width++;
+ continue;
+ }
+ }
+ chunks_.push_back(bit);
+ last = &chunks_.back();
+ last_end_offset = bit.offset + 1;
+ }
+
+ check();
+ }
+
+ return *this;
+}
+
RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
{
chunks_.push_back(RTLIL::SigChunk(value));
@@ -1626,24 +1668,25 @@ void RTLIL::SigSpec::pack() const
std::vector<RTLIL::SigBit> old_bits;
old_bits.swap(that->bits_);
- RTLIL::SigChunk *last_const = NULL;
- RTLIL::SigChunk *last_wire = NULL;
- int last_wire_end = 0;
-
- for (auto &bit : old_bits)
- if (bit.wire == NULL && last_const) {
- last_const->data.bits.push_back(bit.data);
- last_const->width++;
- } else
- if (bit.wire && last_wire && last_wire->wire == bit.wire && last_wire_end == bit.offset) {
- last_wire->width++;
- last_wire_end++;
- } else {
- that->chunks_.push_back(bit);
- last_const = bit.wire ? NULL : &that->chunks_.back();
- last_wire = bit.wire ? &that->chunks_.back() : NULL;
- last_wire_end = bit.offset + 1;
+ RTLIL::SigChunk *last = NULL;
+ int last_end_offset = 0;
+
+ for (auto &bit : old_bits) {
+ if (last && bit.wire == last->wire) {
+ if (bit.wire == NULL) {
+ last->data.bits.push_back(bit.data);
+ last->width++;
+ continue;
+ } else if (last_end_offset == bit.offset) {
+ last_end_offset++;
+ last->width++;
+ continue;
+ }
}
+ that->chunks_.push_back(bit);
+ last = &that->chunks_.back();
+ last_end_offset = bit.offset + 1;
+ }
check();
}
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 0b92405e..a2320873 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -567,6 +567,9 @@ private:
public:
SigSpec();
+ SigSpec(const RTLIL::SigSpec &other);
+ const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
+
SigSpec(const RTLIL::Const &value);
SigSpec(const RTLIL::SigChunk &chunk);
SigSpec(RTLIL::Wire *wire);