From 2f44d8ccf853870a661b5e528c7e3ad3e17ca21e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:32:18 +0200 Subject: [PATCH] Added sig.{replace,remove,extract} variants for std::{map,set} pattern --- kernel/rtlil.cc | 77 ++++++++++++++++++++++++++++++++++--------------- kernel/rtlil.h | 12 +++++++- 2 files changed, 64 insertions(+), 25 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 96ae0f97a..297537f00 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2071,26 +2071,40 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { - cover("kernel.rtlil.sigspec.replace"); + log_assert(pattern.width_ == with.width_); - unpack(); pattern.unpack(); with.unpack(); - log_assert(other != NULL); - log_assert(width_ == other->width_); - other->unpack(); - - log_assert(pattern.width_ == with.width_); + std::map rules; - std::map pattern_map; for (int i = 0; i < SIZE(pattern.bits_); i++) if (pattern.bits_[i].wire != NULL) - pattern_map[pattern.bits_[i]] = with.bits_[i]; + rules[pattern.bits_[i]] = with.bits_[i]; + + replace(rules, other); +} - for (int i = 0; i < SIZE(bits_); i++) - if (pattern_map.count(bits_[i])) - other->bits_[i] = pattern_map.at(bits_[i]); +void RTLIL::SigSpec::replace(const std::map &rules) +{ + replace(rules, this); +} + +void RTLIL::SigSpec::replace(const std::map &rules, RTLIL::SigSpec *other) const +{ + cover("kernel.rtlil.sigspec.replace"); + + log_assert(other != NULL); + log_assert(width_ == other->width_); + + unpack(); + other->unpack(); + + for (int i = 0; i < SIZE(bits_); i++) { + auto it = rules.find(bits_[i]); + if (it != rules.end()) + other->bits_[i] = it->second; + } other->check(); } @@ -2107,6 +2121,23 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other } void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) +{ + std::set pattern_bits = pattern.to_sigbit_set(); + remove2(pattern_bits, other); +} + +void RTLIL::SigSpec::remove(const std::set &pattern) +{ + remove2(pattern, NULL); +} + +void RTLIL::SigSpec::remove(const std::set &pattern, RTLIL::SigSpec *other) const +{ + RTLIL::SigSpec tmp = *this; + tmp.remove2(pattern, other); +} + +void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigSpec *other) { if (other) cover("kernel.rtlil.sigspec.remove_other"); @@ -2120,11 +2151,10 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe other->unpack(); } - std::set pattern_bits = pattern.to_sigbit_set(); std::vector new_bits, new_other_bits; for (int i = 0; i < SIZE(bits_); i++) { - if (bits_[i].wire != NULL && pattern_bits.count(bits_[i])) + if (bits_[i].wire != NULL && pattern.count(bits_[i])) continue; if (other != NULL) new_other_bits.push_back(other->bits_[i]); @@ -2142,33 +2172,32 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe check(); } -RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other) const +RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const +{ + std::set pattern_bits = pattern.to_sigbit_set(); + return extract(pattern_bits, other); +} + +RTLIL::SigSpec RTLIL::SigSpec::extract(const std::set &pattern, const RTLIL::SigSpec *other) const { if (other) cover("kernel.rtlil.sigspec.extract_other"); else cover("kernel.rtlil.sigspec.extract"); - pack(); - pattern.pack(); - - if (other != NULL) - other->pack(); - log_assert(other == NULL || width_ == other->width_); - std::set pat = pattern.to_sigbit_set(); std::vector bits_match = to_sigbit_vector(); RTLIL::SigSpec ret; if (other) { std::vector bits_other = other->to_sigbit_vector(); for (int i = 0; i < width_; i++) - if (bits_match[i].wire && pat.count(bits_match[i])) + if (bits_match[i].wire && pattern.count(bits_match[i])) ret.append_bit(bits_other[i]); } else { for (int i = 0; i < width_; i++) - if (bits_match[i].wire && pat.count(bits_match[i])) + if (bits_match[i].wire && pattern.count(bits_match[i])) ret.append_bit(bits_match[i]); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0093b8a1b..8f780c822 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -968,15 +968,25 @@ public: void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with); void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const; + + void replace(const std::map &rules); + void replace(const std::map &rules, RTLIL::SigSpec *other) const; + void replace(int offset, const RTLIL::SigSpec &with); void remove(const RTLIL::SigSpec &pattern); void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); + + void remove(const std::set &pattern); + void remove(const std::set &pattern, RTLIL::SigSpec *other) const; + void remove2(const std::set &pattern, RTLIL::SigSpec *other); + void remove(int offset, int length = 1); void remove_const(); - RTLIL::SigSpec extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(const std::set &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length = 1) const; void append(const RTLIL::SigSpec &signal); -- 2.30.2