3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-07-25 05:37:02 +00:00

const: string and bits in a variant

This commit is contained in:
Emil J. Tywoniak 2024-07-30 19:58:43 +02:00
parent 498e0498c5
commit 5f85eef3b4
6 changed files with 208 additions and 128 deletions

View file

@ -1733,31 +1733,15 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
static std::string serialize_param_value(const RTLIL::Const &val) { static std::string serialize_param_value(const RTLIL::Const &val) {
std::string res; std::string res;
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) { if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING)
res.push_back('t'); res.push_back('t');
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING_COMPACT) {
res += stringf("%d", GetSize(val));
res.push_back('\'');
res.append(val.decode_string());
return res;
}
}
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) if (val.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED)
res.push_back('s'); res.push_back('s');
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_REAL) if (val.flags & RTLIL::ConstFlags::CONST_FLAG_REAL)
res.push_back('r'); res.push_back('r');
res += stringf("%d", GetSize(val)); res += stringf("%d", GetSize(val));
res.push_back('\''); res.push_back('\'');
for (int i = GetSize(val) - 1; i >= 0; i--) { res.append(val.as_string("?"));
switch (val.bits()[i]) {
case RTLIL::State::S0: res.push_back('0'); break;
case RTLIL::State::S1: res.push_back('1'); break;
case RTLIL::State::Sx: res.push_back('x'); break;
case RTLIL::State::Sz: res.push_back('z'); break;
case RTLIL::State::Sa: res.push_back('?'); break;
case RTLIL::State::Sm: res.push_back('m'); break;
}
}
return res; return res;
} }

View file

@ -72,7 +72,7 @@ static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_b
BigUnsigned mag = val.getMagnitude(); BigUnsigned mag = val.getMagnitude();
RTLIL::Const result(0, result_len); RTLIL::Const result(0, result_len);
log_debug("size %d\n", result.bits().size());
if (!mag.isZero()) if (!mag.isZero())
{ {
if (val.getSign() < 0) if (val.getSign() < 0)

View file

@ -274,10 +274,7 @@ Aig::Aig(Cell *cell)
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
} else { } else {
mkname_last = name; mkname_last = name;
if (p.second.flags & RTLIL::CONST_FLAG_STRING_COMPACT) name += ":" + p.second.pretty_fmt();
name += ":" + p.second.decode_string();
else
name += stringf(":%d", p.second.as_int());
} }
mkname_a_signed = false; mkname_a_signed = false;

View file

@ -202,16 +202,18 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
RTLIL::Const::Const(const std::string &str) RTLIL::Const::Const(const std::string &str)
{ {
flags = RTLIL::CONST_FLAG_STRING | CONST_FLAG_STRING_COMPACT; flags = RTLIL::CONST_FLAG_STRING;
this->str = str; backing = str;
} }
RTLIL::Const::Const(int val, int width) RTLIL::Const::Const(int val, int width)
{ {
flags = RTLIL::CONST_FLAG_NONE; flags = RTLIL::CONST_FLAG_NONE;
bits_.reserve(width); backing = bitvectype();
bitvectype& bv = assert_get_bits("Const::Const(int, int)");
bv.reserve(width);
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
bits_.push_back((val & 1) != 0 ? State::S1 : State::S0); bv.push_back((val & 1) != 0 ? State::S1 : State::S0);
val = val >> 1; val = val >> 1;
} }
} }
@ -219,75 +221,91 @@ RTLIL::Const::Const(int val, int width)
RTLIL::Const::Const(RTLIL::State bit, int width) RTLIL::Const::Const(RTLIL::State bit, int width)
{ {
flags = RTLIL::CONST_FLAG_NONE; flags = RTLIL::CONST_FLAG_NONE;
bits_.reserve(width); backing = bitvectype();
bitvectype& bv = assert_get_bits("Const::Const(State, int)");
bv.reserve(width);
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
bits_.push_back(bit); bv.push_back(bit);
} }
RTLIL::Const::Const(const std::vector<bool> &bits) RTLIL::Const::Const(const std::vector<bool> &bits)
{ {
flags = RTLIL::CONST_FLAG_NONE; flags = RTLIL::CONST_FLAG_NONE;
this->bits_.reserve(bits.size()); backing = bitvectype();
bitvectype& bv = assert_get_bits("Const::Const(std::vector<bool>)");
bv.reserve(bits.size());
for (const auto &b : bits) for (const auto &b : bits)
this->bits_.emplace_back(b ? State::S1 : State::S0); bv.emplace_back(b ? State::S1 : State::S0);
}
[[nodiscard]] RTLIL::Const::bitvectype& RTLIL::Const::assert_get_bits(const char* ctx) const {
// return assert_get<bitvectype, decltype(backing)>(&backing, ctx);
return std::get<bitvectype>(backing);
}
[[nodiscard]] std::string& RTLIL::Const::assert_get_str(const char* ctx) const {
// return assert_get<std::string, decltype(backing)>(&backing, ctx);
return std::get<std::string>(backing);
} }
bool RTLIL::Const::operator <(const RTLIL::Const &other) const bool RTLIL::Const::operator <(const RTLIL::Const &other) const
{ {
if ((flags & CONST_FLAG_STRING_COMPACT) != (other.flags & CONST_FLAG_STRING_COMPACT)) const char* ctx = "operator<";
if (std::get_if<std::string>(&backing) != std::get_if<std::string>(&other.backing))
return decode_string() < other.decode_string(); return decode_string() < other.decode_string();
if (flags & CONST_FLAG_STRING_COMPACT) if (std::get_if<std::string>(&backing))
return str < other.str; return assert_get_str(ctx) < other.assert_get_str(ctx);
if (bits_.size() != other.bits_.size()) bitvectype& bv = assert_get_bits(ctx);
return bits_.size() < other.bits_.size(); auto other_bv = other.assert_get_bits(ctx);
for (size_t i = 0; i < bits_.size(); i++)
if (bits_[i] != other.bits_[i]) if (bv.size() != other_bv.size())
return bits_[i] < other.bits_[i]; return bv.size() < other_bv.size();
for (size_t i = 0; i < bv.size(); i++)
if (bv[i] != other_bv[i])
return bv[i] < other_bv[i];
return false; return false;
} }
bool RTLIL::Const::operator ==(const RTLIL::Const &other) const bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
{ {
if ((flags & CONST_FLAG_STRING_COMPACT) != (other.flags & CONST_FLAG_STRING_COMPACT)) const char* ctx = "operator==";
if (std::get_if<std::string>(&backing) != std::get_if<std::string>(&other.backing))
return decode_string() == other.decode_string(); return decode_string() == other.decode_string();
if (flags & CONST_FLAG_STRING_COMPACT) if (std::get_if<std::string>(&backing))
return str == other.str; return assert_get_str(ctx) == other.assert_get_str(ctx);
return bits_ == other.bits_;
return assert_get_bits(ctx) == other.assert_get_bits(ctx);
} }
bool RTLIL::Const::operator !=(const RTLIL::Const &other) const bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
{ {
if ((flags & CONST_FLAG_STRING_COMPACT) != (other.flags & CONST_FLAG_STRING_COMPACT)) return !(*this == other);
return decode_string() != other.decode_string();
if (flags & CONST_FLAG_STRING_COMPACT)
return str != other.str;
return bits_ != other.bits_;
} }
std::vector<RTLIL::State>& RTLIL::Const::bits() std::vector<RTLIL::State>& RTLIL::Const::bits()
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
return bits_; return assert_get_bits("Const::bits()");
} }
const std::vector<RTLIL::State>& RTLIL::Const::bits() const const std::vector<RTLIL::State>& RTLIL::Const::bits() const
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
return bits_; return assert_get_bits("Const::bits()");
} }
std::vector<RTLIL::State> RTLIL::Const::to_bits() const std::vector<RTLIL::State> RTLIL::Const::to_bits() const
{ {
if (!(flags & CONST_FLAG_STRING_COMPACT)) { if (auto bv = std::get_if<bitvectype>(&backing)) {
return bits_; return *bv;
} }
auto str = assert_get_str("Const::to_bits");
std::vector<RTLIL::State> b; bitvectype b;
b.reserve(str.size() * 8); b.reserve(str.size() * 8);
for (int i = str.size()-1; i >= 0; i--) { for (int i = str.size()-1; i >= 0; i--) {
unsigned char ch = str[i]; unsigned char ch = str[i];
@ -299,40 +317,57 @@ std::vector<RTLIL::State> RTLIL::Const::to_bits() const
return b; return b;
} }
std::string RTLIL::Const::pretty_fmt() const {
if (std::get_if<std::string>(&backing))
return decode_string();
else
return std::to_string(as_int());
}
std::string RTLIL::Const::pretty_fmt_undef() const {
if (std::get_if<std::string>(&backing))
return decode_string();
else
return as_string();
}
bool RTLIL::Const::as_bool() const bool RTLIL::Const::as_bool() const
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
for (size_t i = 0; i < bits_.size(); i++) bitvectype& bv = assert_get_bits("Const::as_bool");
if (bits_[i] == State::S1) for (size_t i = 0; i < bv.size(); i++)
if (bv[i] == State::S1)
return true; return true;
return false; return false;
} }
int RTLIL::Const::as_int(bool is_signed) const int RTLIL::Const::as_int(bool is_signed) const
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
bitvectype& bv = assert_get_bits("Const::as_int");
int32_t ret = 0; int32_t ret = 0;
for (size_t i = 0; i < bits_.size() && i < 32; i++) for (size_t i = 0; i < bv.size() && i < 32; i++)
if (bits_[i] == State::S1) if (bv[i] == State::S1)
ret |= 1 << i; ret |= 1 << i;
if (is_signed && bits_.back() == State::S1) if (is_signed && bv.back() == State::S1)
for (size_t i = bits_.size(); i < 32; i++) for (size_t i = bv.size(); i < 32; i++)
ret |= 1 << i; ret |= 1 << i;
return ret; return ret;
} }
std::string RTLIL::Const::as_string() const std::string RTLIL::Const::as_string(std::string any) const
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
bitvectype& bv = assert_get_bits("Const::as_bool");
std::string ret; std::string ret;
ret.reserve(bits_.size()); ret.reserve(bv.size());
for (size_t i = bits_.size(); i > 0; i--) for (size_t i = bv.size(); i > 0; i--)
switch (bits_[i-1]) { switch (bv[i-1]) {
case S0: ret += "0"; break; case S0: ret += "0"; break;
case S1: ret += "1"; break; case S1: ret += "1"; break;
case Sx: ret += "x"; break; case Sx: ret += "x"; break;
case Sz: ret += "z"; break; case Sz: ret += "z"; break;
case Sa: ret += "-"; break; case Sa: ret += any; break;
case Sm: ret += "m"; break; case Sm: ret += "m"; break;
} }
return ret; return ret;
@ -341,25 +376,29 @@ std::string RTLIL::Const::as_string() const
RTLIL::Const RTLIL::Const::from_string(const std::string &str) RTLIL::Const RTLIL::Const::from_string(const std::string &str)
{ {
Const c; Const c;
c.bits_.reserve(str.size()); c.backing = bitvectype();
bitvectype& bv = c.assert_get_bits("Const::from_string");
bv.reserve(str.size());
for (auto it = str.rbegin(); it != str.rend(); it++) for (auto it = str.rbegin(); it != str.rend(); it++)
switch (*it) { switch (*it) {
case '0': c.bits_.push_back(State::S0); break; case '0': bv.push_back(State::S0); break;
case '1': c.bits_.push_back(State::S1); break; case '1': bv.push_back(State::S1); break;
case 'x': c.bits_.push_back(State::Sx); break; case 'x': bv.push_back(State::Sx); break;
case 'z': c.bits_.push_back(State::Sz); break; case 'z': bv.push_back(State::Sz); break;
case 'm': c.bits_.push_back(State::Sm); break; case 'm': bv.push_back(State::Sm); break;
default: c.bits_.push_back(State::Sa); default: bv.push_back(State::Sa);
} }
return c; return c;
} }
std::string RTLIL::Const::decode_string() const std::string RTLIL::Const::decode_string() const
{ {
if (flags & CONST_FLAG_STRING_COMPACT) if (auto str = std::get_if<std::string>(&backing))
return str; return *str;
const int n = GetSize(bits_); bitvectorize();
bitvectype& bv = assert_get_bits("Const::decode_string");
const int n = GetSize(bv);
const int n_over_8 = n / 8; const int n_over_8 = n / 8;
std::string s; std::string s;
s.reserve(n_over_8); s.reserve(n_over_8);
@ -367,7 +406,7 @@ std::string RTLIL::Const::decode_string() const
if (i < n) { if (i < n) {
char ch = 0; char ch = 0;
for (int j = 0; j < (n - i); j++) { for (int j = 0; j < (n - i); j++) {
if (bits_[i + j] == RTLIL::State::S1) { if (bv[i + j] == RTLIL::State::S1) {
ch |= 1 << j; ch |= 1 << j;
} }
} }
@ -378,7 +417,7 @@ std::string RTLIL::Const::decode_string() const
for (; i >= 0; i -= 8) { for (; i >= 0; i -= 8) {
char ch = 0; char ch = 0;
for (int j = 0; j < 8; j++) { for (int j = 0; j < 8; j++) {
if (bits_[i + j] == RTLIL::State::S1) { if (bv[i + j] == RTLIL::State::S1) {
ch |= 1 << j; ch |= 1 << j;
} }
} }
@ -390,10 +429,11 @@ std::string RTLIL::Const::decode_string() const
bool RTLIL::Const::is_fully_zero() const bool RTLIL::Const::is_fully_zero() const
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
bitvectype& bv = assert_get_bits("Const::decode_string");
cover("kernel.rtlil.const.is_fully_zero"); cover("kernel.rtlil.const.is_fully_zero");
for (const auto &bit : bits_) for (const auto &bit : bv)
if (bit != RTLIL::State::S0) if (bit != RTLIL::State::S0)
return false; return false;
@ -402,10 +442,11 @@ bool RTLIL::Const::is_fully_zero() const
bool RTLIL::Const::is_fully_ones() const bool RTLIL::Const::is_fully_ones() const
{ {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
bitvectype& bv = assert_get_bits("Const::decode_string");
cover("kernel.rtlil.const.is_fully_ones"); cover("kernel.rtlil.const.is_fully_ones");
for (const auto &bit : bits_) for (const auto &bit : bv)
if (bit != RTLIL::State::S1) if (bit != RTLIL::State::S1)
return false; return false;
@ -416,10 +457,10 @@ bool RTLIL::Const::is_fully_def() const
{ {
cover("kernel.rtlil.const.is_fully_def"); cover("kernel.rtlil.const.is_fully_def");
if (flags & CONST_FLAG_STRING_COMPACT) bitvectorize();
return true; bitvectype& bv = assert_get_bits("Const::decode_string");
for (const auto &bit : bits_) for (const auto &bit : bv)
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false; return false;
@ -430,10 +471,10 @@ bool RTLIL::Const::is_fully_undef() const
{ {
cover("kernel.rtlil.const.is_fully_undef"); cover("kernel.rtlil.const.is_fully_undef");
if (flags & CONST_FLAG_STRING_COMPACT) bitvectorize();
return false; bitvectype& bv = assert_get_bits("Const::decode_string");
for (const auto &bit : bits_) for (const auto &bit : bv)
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz) if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
return false; return false;
@ -444,10 +485,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const
{ {
cover("kernel.rtlil.const.is_fully_undef_x_only"); cover("kernel.rtlil.const.is_fully_undef_x_only");
if (flags & CONST_FLAG_STRING_COMPACT) bitvectorize();
return false; bitvectype& bv = assert_get_bits("Const::decode_string");
for (const auto &bit : bits_) for (const auto &bit : bv)
if (bit != RTLIL::State::Sx) if (bit != RTLIL::State::Sx)
return false; return false;
@ -458,12 +499,12 @@ bool RTLIL::Const::is_onehot(int *pos) const
{ {
cover("kernel.rtlil.const.is_onehot"); cover("kernel.rtlil.const.is_onehot");
if (flags & CONST_FLAG_STRING_COMPACT) bitvectorize();
return false; bitvectype& bv = assert_get_bits("Const::decode_string");
bool found = false; bool found = false;
for (int i = 0; i < GetSize(*this); i++) { for (int i = 0; i < GetSize(*this); i++) {
auto &bit = bits_[i]; auto &bit = bv[i];
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false; return false;
if (bit == RTLIL::State::S1) { if (bit == RTLIL::State::S1) {

View file

@ -22,6 +22,8 @@
#include "kernel/yosys_common.h" #include "kernel/yosys_common.h"
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include <variant>
#include "kernel/utils.h"
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
@ -47,14 +49,21 @@ namespace RTLIL
STi = 7 // init STi = 7 // init
}; };
// Semantic metadata - how can this constant be interpreted?
// Values may be generally non-exclusive
enum ConstFlags : unsigned char { enum ConstFlags : unsigned char {
CONST_FLAG_NONE = 0, CONST_FLAG_NONE = 0,
CONST_FLAG_STRING = 1, CONST_FLAG_STRING = 1,
CONST_FLAG_STRING_COMPACT = 2, // internally efficient string storage CONST_FLAG_SIGNED = 2, // only used for parameters
CONST_FLAG_SIGNED = 4, // only used for parameters CONST_FLAG_REAL = 4, // only used for parameters
CONST_FLAG_REAL = 8, // only used for parameters
}; };
// // Union discriminator. Values are exclusive
// enum ConstRepr : unsigned char {
// CONST_REPR_BITS = 1,
// CONST_REPR_STRING = 2,
// };
struct Const; struct Const;
struct AttrObject; struct AttrObject;
struct Selection; struct Selection;
@ -660,16 +669,16 @@ struct RTLIL::Const
{ {
private: private:
// TODO unionize // TODO unionize
std::vector<RTLIL::State> bits_; typedef std::vector<RTLIL::State> bitvectype;
std::string str; // active on CONST_FLAG_STRING_COMPACT mutable std::variant<bitvectype, std::string> backing;
public: public:
int flags; short flags;
Const() : flags(RTLIL::CONST_FLAG_NONE) {} Const() : backing(std::vector<RTLIL::State>()), flags(RTLIL::CONST_FLAG_NONE) {}
Const(const std::string &str); Const(const std::string &str);
Const(int val, int width = 32); Const(int val, int width = 32);
Const(RTLIL::State bit, int width = 1); Const(RTLIL::State bit, int width = 1);
Const(const std::vector<RTLIL::State> &bits) : bits_(bits) { flags = CONST_FLAG_NONE; } Const(const std::vector<RTLIL::State> &bits) : backing(bits) { flags = CONST_FLAG_NONE; }
Const(const std::vector<bool> &bits); Const(const std::vector<bool> &bits);
Const(const RTLIL::Const &c) = default; Const(const RTLIL::Const &c) = default;
RTLIL::Const &operator =(const RTLIL::Const &other) = default; RTLIL::Const &operator =(const RTLIL::Const &other) = default;
@ -678,22 +687,68 @@ struct RTLIL::Const
bool operator ==(const RTLIL::Const &other) const; bool operator ==(const RTLIL::Const &other) const;
bool operator !=(const RTLIL::Const &other) const; bool operator !=(const RTLIL::Const &other) const;
bitvectype& assert_get_bits(const char* ctx) const;
std::string& assert_get_str(const char* ctx) const;
const std::vector<RTLIL::State>& bits() const; const std::vector<RTLIL::State>& bits() const;
std::vector<RTLIL::State>& bits(); std::vector<RTLIL::State>& bits();
bool as_bool() const; bool as_bool() const;
int as_int(bool is_signed = false) const; int as_int(bool is_signed = false) const;
std::string as_string() const; std::string as_string(std::string any = "-") const;
static Const from_string(const std::string &str); static Const from_string(const std::string &str);
std::vector<RTLIL::State> to_bits() const; std::vector<RTLIL::State> to_bits() const;
std::string pretty_fmt() const;
std::string pretty_fmt_undef() const;
std::string decode_string() const; std::string decode_string() const;
// (flags & CONST_FLAG_STRING_COMPACT) ? : ; inline size_t size() const {
inline size_t size() const { return (flags & CONST_FLAG_STRING_COMPACT) ? 8 * str.size() : bits_.size(); } if (auto str = std::get_if<std::string>(&backing))
inline bool empty() const { return (flags & CONST_FLAG_STRING_COMPACT) ? str.empty() : bits_.empty(); } return 8 * str->size();
inline RTLIL::State &operator[](int index) { log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); return bits_.at(index); } else
inline const RTLIL::State &operator[](int index) const { log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); return bits_.at(index); } return assert_get_bits("Const::size").size();
inline decltype(bits_)::iterator begin() { log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); return bits_.begin(); } }
inline decltype(bits_)::iterator end() { log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); return bits_.end(); }
inline bool empty() const {
if (auto str = std::get_if<std::string>(&backing))
return str->empty();
else
return assert_get_bits("Const::empty").empty();
}
void bitvectorize() const {
if (std::get_if<bitvectype>(&backing))
return;
std::string& str = assert_get_str("Const::bitvectorize");
bitvectype bits;
bits.reserve(str.size() * 8);
for (int i = str.size() - 1; i >= 0; i--) {
unsigned char ch = str[i];
for (int j = 0; j < 8; j++) {
bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
ch = ch >> 1;
}
}
backing = bits;
}
inline RTLIL::State &operator[](int index) {
bitvectorize();
return assert_get_bits("Const::operator[]").at(index);
}
inline const RTLIL::State &operator[](int index) const {
bitvectorize();
return assert_get_bits("const Const::operator[]").at(index);
}
inline bitvectype::iterator begin() {
bitvectorize();
return assert_get_bits("Const bit iterator begin()").begin();
}
inline bitvectype::iterator end() {
bitvectorize();
return assert_get_bits("Const bit iterator end()").end();
}
bool is_fully_zero() const; bool is_fully_zero() const;
bool is_fully_ones() const; bool is_fully_ones() const;
@ -703,32 +758,35 @@ struct RTLIL::Const
bool is_onehot(int *pos = nullptr) const; bool is_onehot(int *pos = nullptr) const;
inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const { inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
RTLIL::Const ret; bitvectype& bv = assert_get_bits("Const::extract");
ret.bits_.reserve(len); bitvectype ret_bv;
ret_bv.reserve(len);
for (int i = offset; i < offset + len; i++) for (int i = offset; i < offset + len; i++)
ret.bits_.push_back(i < GetSize(bits_) ? bits_[i] : padding); ret_bv.push_back(i < GetSize(bv) ? bv[i] : padding);
return ret; return RTLIL::Const(ret_bv);
} }
void extu(int width) { void extu(int width) {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
bits_.resize(width, RTLIL::State::S0); assert_get_bits("Const::extu").resize(width, RTLIL::State::S0);
} }
void exts(int width) { void exts(int width) {
log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); bitvectorize();
bits_.resize(width, bits_.empty() ? RTLIL::State::Sx : bits_.back()); bitvectype& bv = assert_get_bits("Const::exts");
bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back());
} }
inline unsigned int hash() const { inline unsigned int hash() const {
unsigned int h = mkhash_init; unsigned int h = mkhash_init;
if(flags & CONST_FLAG_STRING_COMPACT) { if(auto str = std::get_if<std::string>(&backing)) {
for (auto c : str) for (auto c : *str)
h = mkhash(h, c); h = mkhash(h, c);
} else { } else {
for (auto b : bits_) bitvectype& bv = assert_get_bits("Const::hash");
for (auto b : bv)
h = mkhash(h, b); h = mkhash(h, b);
} }
return h; return h;

View file

@ -143,7 +143,7 @@ struct OptMergeWorker
for (auto &it : cell->parameters) { for (auto &it : cell->parameters) {
Const c = it.second; Const c = it.second;
std::string s = "P " + it.first.str() + "="; std::string s = "P " + it.first.str() + "=";
s += (c.flags & RTLIL::CONST_FLAG_STRING_COMPACT) ? c.decode_string() : c.as_string(); s += c.pretty_fmt_undef();
s += "\n"; s += "\n";
hash_conn_strings.push_back(s); hash_conn_strings.push_back(s);
} }