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:
parent
498e0498c5
commit
5f85eef3b4
6 changed files with 208 additions and 128 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
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)
|
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) {
|
||||||
|
|
114
kernel/rtlil.h
114
kernel/rtlil.h
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue