mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-11 03:33:36 +00:00
const: string and bits in a variant
This commit is contained in:
parent
498e0498c5
commit
5f85eef3b4
|
@ -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) {
|
||||
std::string res;
|
||||
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) {
|
||||
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING)
|
||||
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)
|
||||
res.push_back('s');
|
||||
if (val.flags & RTLIL::ConstFlags::CONST_FLAG_REAL)
|
||||
res.push_back('r');
|
||||
res += stringf("%d", GetSize(val));
|
||||
res.push_back('\'');
|
||||
for (int i = GetSize(val) - 1; i >= 0; i--) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
res.append(val.as_string("?"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_b
|
|||
|
||||
BigUnsigned mag = val.getMagnitude();
|
||||
RTLIL::Const result(0, result_len);
|
||||
|
||||
log_debug("size %d\n", result.bits().size());
|
||||
if (!mag.isZero())
|
||||
{
|
||||
if (val.getSign() < 0)
|
||||
|
|
|
@ -274,10 +274,7 @@ Aig::Aig(Cell *cell)
|
|||
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
|
||||
} else {
|
||||
mkname_last = name;
|
||||
if (p.second.flags & RTLIL::CONST_FLAG_STRING_COMPACT)
|
||||
name += ":" + p.second.decode_string();
|
||||
else
|
||||
name += stringf(":%d", p.second.as_int());
|
||||
name += ":" + p.second.pretty_fmt();
|
||||
}
|
||||
|
||||
mkname_a_signed = false;
|
||||
|
|
193
kernel/rtlil.cc
193
kernel/rtlil.cc
|
@ -202,16 +202,18 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
|
|||
|
||||
RTLIL::Const::Const(const std::string &str)
|
||||
{
|
||||
flags = RTLIL::CONST_FLAG_STRING | CONST_FLAG_STRING_COMPACT;
|
||||
this->str = str;
|
||||
flags = RTLIL::CONST_FLAG_STRING;
|
||||
backing = str;
|
||||
}
|
||||
|
||||
RTLIL::Const::Const(int val, int width)
|
||||
{
|
||||
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++) {
|
||||
bits_.push_back((val & 1) != 0 ? State::S1 : State::S0);
|
||||
bv.push_back((val & 1) != 0 ? State::S1 : State::S0);
|
||||
val = val >> 1;
|
||||
}
|
||||
}
|
||||
|
@ -219,75 +221,91 @@ RTLIL::Const::Const(int val, int width)
|
|||
RTLIL::Const::Const(RTLIL::State bit, int width)
|
||||
{
|
||||
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++)
|
||||
bits_.push_back(bit);
|
||||
bv.push_back(bit);
|
||||
}
|
||||
|
||||
RTLIL::Const::Const(const std::vector<bool> &bits)
|
||||
{
|
||||
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)
|
||||
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
|
||||
{
|
||||
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();
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return str < other.str;
|
||||
if (std::get_if<std::string>(&backing))
|
||||
return assert_get_str(ctx) < other.assert_get_str(ctx);
|
||||
|
||||
if (bits_.size() != other.bits_.size())
|
||||
return bits_.size() < other.bits_.size();
|
||||
for (size_t i = 0; i < bits_.size(); i++)
|
||||
if (bits_[i] != other.bits_[i])
|
||||
return bits_[i] < other.bits_[i];
|
||||
bitvectype& bv = assert_get_bits(ctx);
|
||||
auto other_bv = other.assert_get_bits(ctx);
|
||||
|
||||
if (bv.size() != other_bv.size())
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return str == other.str;
|
||||
return bits_ == other.bits_;
|
||||
if (std::get_if<std::string>(&backing))
|
||||
return assert_get_str(ctx) == other.assert_get_str(ctx);
|
||||
|
||||
return assert_get_bits(ctx) == other.assert_get_bits(ctx);
|
||||
}
|
||||
|
||||
bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
|
||||
{
|
||||
if ((flags & CONST_FLAG_STRING_COMPACT) != (other.flags & CONST_FLAG_STRING_COMPACT))
|
||||
return decode_string() != other.decode_string();
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return str != other.str;
|
||||
return bits_ != other.bits_;
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::vector<RTLIL::State>& RTLIL::Const::bits()
|
||||
{
|
||||
log_assert(!(flags & CONST_FLAG_STRING_COMPACT));
|
||||
return bits_;
|
||||
bitvectorize();
|
||||
return assert_get_bits("Const::bits()");
|
||||
}
|
||||
|
||||
const std::vector<RTLIL::State>& RTLIL::Const::bits() const
|
||||
{
|
||||
log_assert(!(flags & CONST_FLAG_STRING_COMPACT));
|
||||
return bits_;
|
||||
bitvectorize();
|
||||
return assert_get_bits("Const::bits()");
|
||||
}
|
||||
|
||||
|
||||
std::vector<RTLIL::State> RTLIL::Const::to_bits() const
|
||||
{
|
||||
if (!(flags & CONST_FLAG_STRING_COMPACT)) {
|
||||
return bits_;
|
||||
if (auto bv = std::get_if<bitvectype>(&backing)) {
|
||||
return *bv;
|
||||
}
|
||||
|
||||
std::vector<RTLIL::State> b;
|
||||
auto str = assert_get_str("Const::to_bits");
|
||||
bitvectype b;
|
||||
b.reserve(str.size() * 8);
|
||||
for (int i = str.size()-1; i >= 0; i--) {
|
||||
unsigned char ch = str[i];
|
||||
|
@ -299,40 +317,57 @@ std::vector<RTLIL::State> RTLIL::Const::to_bits() const
|
|||
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
|
||||
{
|
||||
log_assert(!(flags & CONST_FLAG_STRING_COMPACT));
|
||||
for (size_t i = 0; i < bits_.size(); i++)
|
||||
if (bits_[i] == State::S1)
|
||||
bitvectorize();
|
||||
bitvectype& bv = assert_get_bits("Const::as_bool");
|
||||
for (size_t i = 0; i < bv.size(); i++)
|
||||
if (bv[i] == State::S1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < bits_.size() && i < 32; i++)
|
||||
if (bits_[i] == State::S1)
|
||||
for (size_t i = 0; i < bv.size() && i < 32; i++)
|
||||
if (bv[i] == State::S1)
|
||||
ret |= 1 << i;
|
||||
if (is_signed && bits_.back() == State::S1)
|
||||
for (size_t i = bits_.size(); i < 32; i++)
|
||||
if (is_signed && bv.back() == State::S1)
|
||||
for (size_t i = bv.size(); i < 32; i++)
|
||||
ret |= 1 << i;
|
||||
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;
|
||||
ret.reserve(bits_.size());
|
||||
for (size_t i = bits_.size(); i > 0; i--)
|
||||
switch (bits_[i-1]) {
|
||||
ret.reserve(bv.size());
|
||||
for (size_t i = bv.size(); i > 0; i--)
|
||||
switch (bv[i-1]) {
|
||||
case S0: ret += "0"; break;
|
||||
case S1: ret += "1"; break;
|
||||
case Sx: ret += "x"; break;
|
||||
case Sz: ret += "z"; break;
|
||||
case Sa: ret += "-"; break;
|
||||
case Sa: ret += any; break;
|
||||
case Sm: ret += "m"; break;
|
||||
}
|
||||
return ret;
|
||||
|
@ -341,25 +376,29 @@ std::string RTLIL::Const::as_string() const
|
|||
RTLIL::Const RTLIL::Const::from_string(const std::string &str)
|
||||
{
|
||||
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++)
|
||||
switch (*it) {
|
||||
case '0': c.bits_.push_back(State::S0); break;
|
||||
case '1': c.bits_.push_back(State::S1); break;
|
||||
case 'x': c.bits_.push_back(State::Sx); break;
|
||||
case 'z': c.bits_.push_back(State::Sz); break;
|
||||
case 'm': c.bits_.push_back(State::Sm); break;
|
||||
default: c.bits_.push_back(State::Sa);
|
||||
case '0': bv.push_back(State::S0); break;
|
||||
case '1': bv.push_back(State::S1); break;
|
||||
case 'x': bv.push_back(State::Sx); break;
|
||||
case 'z': bv.push_back(State::Sz); break;
|
||||
case 'm': bv.push_back(State::Sm); break;
|
||||
default: bv.push_back(State::Sa);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
std::string RTLIL::Const::decode_string() const
|
||||
{
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return str;
|
||||
if (auto str = std::get_if<std::string>(&backing))
|
||||
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;
|
||||
std::string s;
|
||||
s.reserve(n_over_8);
|
||||
|
@ -367,7 +406,7 @@ std::string RTLIL::Const::decode_string() const
|
|||
if (i < n) {
|
||||
char ch = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +417,7 @@ std::string RTLIL::Const::decode_string() const
|
|||
for (; i >= 0; i -= 8) {
|
||||
char ch = 0;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (bits_[i + j] == RTLIL::State::S1) {
|
||||
if (bv[i + j] == RTLIL::State::S1) {
|
||||
ch |= 1 << j;
|
||||
}
|
||||
}
|
||||
|
@ -390,10 +429,11 @@ std::string RTLIL::Const::decode_string() 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");
|
||||
|
||||
for (const auto &bit : bits_)
|
||||
for (const auto &bit : bv)
|
||||
if (bit != RTLIL::State::S0)
|
||||
return false;
|
||||
|
||||
|
@ -402,10 +442,11 @@ bool RTLIL::Const::is_fully_zero() 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");
|
||||
|
||||
for (const auto &bit : bits_)
|
||||
for (const auto &bit : bv)
|
||||
if (bit != RTLIL::State::S1)
|
||||
return false;
|
||||
|
||||
|
@ -416,10 +457,10 @@ bool RTLIL::Const::is_fully_def() const
|
|||
{
|
||||
cover("kernel.rtlil.const.is_fully_def");
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return true;
|
||||
bitvectorize();
|
||||
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)
|
||||
return false;
|
||||
|
||||
|
@ -430,10 +471,10 @@ bool RTLIL::Const::is_fully_undef() const
|
|||
{
|
||||
cover("kernel.rtlil.const.is_fully_undef");
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return false;
|
||||
bitvectorize();
|
||||
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)
|
||||
return false;
|
||||
|
||||
|
@ -444,10 +485,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const
|
|||
{
|
||||
cover("kernel.rtlil.const.is_fully_undef_x_only");
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return false;
|
||||
bitvectorize();
|
||||
bitvectype& bv = assert_get_bits("Const::decode_string");
|
||||
|
||||
for (const auto &bit : bits_)
|
||||
for (const auto &bit : bv)
|
||||
if (bit != RTLIL::State::Sx)
|
||||
return false;
|
||||
|
||||
|
@ -458,12 +499,12 @@ bool RTLIL::Const::is_onehot(int *pos) const
|
|||
{
|
||||
cover("kernel.rtlil.const.is_onehot");
|
||||
|
||||
if (flags & CONST_FLAG_STRING_COMPACT)
|
||||
return false;
|
||||
bitvectorize();
|
||||
bitvectype& bv = assert_get_bits("Const::decode_string");
|
||||
|
||||
bool found = false;
|
||||
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)
|
||||
return false;
|
||||
if (bit == RTLIL::State::S1) {
|
||||
|
|
114
kernel/rtlil.h
114
kernel/rtlil.h
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "kernel/yosys_common.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include <variant>
|
||||
#include "kernel/utils.h"
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -47,14 +49,21 @@ namespace RTLIL
|
|||
STi = 7 // init
|
||||
};
|
||||
|
||||
// Semantic metadata - how can this constant be interpreted?
|
||||
// Values may be generally non-exclusive
|
||||
enum ConstFlags : unsigned char {
|
||||
CONST_FLAG_NONE = 0,
|
||||
CONST_FLAG_STRING = 1,
|
||||
CONST_FLAG_STRING_COMPACT = 2, // internally efficient string storage
|
||||
CONST_FLAG_SIGNED = 4, // only used for parameters
|
||||
CONST_FLAG_REAL = 8, // only used for parameters
|
||||
CONST_FLAG_SIGNED = 2, // only used for parameters
|
||||
CONST_FLAG_REAL = 4, // only used for parameters
|
||||
};
|
||||
|
||||
// // Union discriminator. Values are exclusive
|
||||
// enum ConstRepr : unsigned char {
|
||||
// CONST_REPR_BITS = 1,
|
||||
// CONST_REPR_STRING = 2,
|
||||
// };
|
||||
|
||||
struct Const;
|
||||
struct AttrObject;
|
||||
struct Selection;
|
||||
|
@ -660,16 +669,16 @@ struct RTLIL::Const
|
|||
{
|
||||
private:
|
||||
// TODO unionize
|
||||
std::vector<RTLIL::State> bits_;
|
||||
std::string str; // active on CONST_FLAG_STRING_COMPACT
|
||||
typedef std::vector<RTLIL::State> bitvectype;
|
||||
mutable std::variant<bitvectype, std::string> backing;
|
||||
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(int val, int width = 32);
|
||||
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 RTLIL::Const &c) = 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;
|
||||
|
||||
bitvectype& assert_get_bits(const char* ctx) const;
|
||||
std::string& assert_get_str(const char* ctx) const;
|
||||
|
||||
const std::vector<RTLIL::State>& bits() const;
|
||||
std::vector<RTLIL::State>& bits();
|
||||
bool as_bool() 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);
|
||||
std::vector<RTLIL::State> to_bits() const;
|
||||
std::string pretty_fmt() const;
|
||||
std::string pretty_fmt_undef() const;
|
||||
|
||||
|
||||
std::string decode_string() const;
|
||||
// (flags & CONST_FLAG_STRING_COMPACT) ? : ;
|
||||
inline size_t size() const { return (flags & CONST_FLAG_STRING_COMPACT) ? 8 * str.size() : bits_.size(); }
|
||||
inline bool empty() const { return (flags & CONST_FLAG_STRING_COMPACT) ? str.empty() : bits_.empty(); }
|
||||
inline RTLIL::State &operator[](int index) { log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); return bits_.at(index); }
|
||||
inline const RTLIL::State &operator[](int index) const { log_assert(!(flags & CONST_FLAG_STRING_COMPACT)); return bits_.at(index); }
|
||||
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 size_t size() const {
|
||||
if (auto str = std::get_if<std::string>(&backing))
|
||||
return 8 * str->size();
|
||||
else
|
||||
return assert_get_bits("Const::size").size();
|
||||
}
|
||||
|
||||
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_ones() const;
|
||||
|
@ -703,32 +758,35 @@ struct RTLIL::Const
|
|||
bool is_onehot(int *pos = nullptr) const;
|
||||
|
||||
inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const {
|
||||
log_assert(!(flags & CONST_FLAG_STRING_COMPACT));
|
||||
RTLIL::Const ret;
|
||||
ret.bits_.reserve(len);
|
||||
bitvectorize();
|
||||
bitvectype& bv = assert_get_bits("Const::extract");
|
||||
bitvectype ret_bv;
|
||||
ret_bv.reserve(len);
|
||||
for (int i = offset; i < offset + len; i++)
|
||||
ret.bits_.push_back(i < GetSize(bits_) ? bits_[i] : padding);
|
||||
return ret;
|
||||
ret_bv.push_back(i < GetSize(bv) ? bv[i] : padding);
|
||||
return RTLIL::Const(ret_bv);
|
||||
}
|
||||
|
||||
void extu(int width) {
|
||||
log_assert(!(flags & CONST_FLAG_STRING_COMPACT));
|
||||
bits_.resize(width, RTLIL::State::S0);
|
||||
bitvectorize();
|
||||
assert_get_bits("Const::extu").resize(width, RTLIL::State::S0);
|
||||
}
|
||||
|
||||
void exts(int width) {
|
||||
log_assert(!(flags & CONST_FLAG_STRING_COMPACT));
|
||||
bits_.resize(width, bits_.empty() ? RTLIL::State::Sx : bits_.back());
|
||||
bitvectorize();
|
||||
bitvectype& bv = assert_get_bits("Const::exts");
|
||||
bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back());
|
||||
}
|
||||
|
||||
inline unsigned int hash() const {
|
||||
unsigned int h = mkhash_init;
|
||||
|
||||
if(flags & CONST_FLAG_STRING_COMPACT) {
|
||||
for (auto c : str)
|
||||
if(auto str = std::get_if<std::string>(&backing)) {
|
||||
for (auto c : *str)
|
||||
h = mkhash(h, c);
|
||||
} else {
|
||||
for (auto b : bits_)
|
||||
bitvectype& bv = assert_get_bits("Const::hash");
|
||||
for (auto b : bv)
|
||||
h = mkhash(h, b);
|
||||
}
|
||||
return h;
|
||||
|
|
|
@ -143,7 +143,7 @@ struct OptMergeWorker
|
|||
for (auto &it : cell->parameters) {
|
||||
Const c = it.second;
|
||||
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";
|
||||
hash_conn_strings.push_back(s);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue