mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #2171 from whitequark/cxxrtl-accessors
cxxrtl: add .get() and .set() accessors on value<> and wire<>
This commit is contained in:
commit
87f45b7bd0
|
@ -111,6 +111,35 @@ struct value : public expr_base<value<Bits>> {
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conversion operations.
|
||||||
|
//
|
||||||
|
// These functions ensure that a conversion is never out of range, and should be always used, if at all
|
||||||
|
// possible, instead of direct manipulation of the `data` member. For very large types, .slice() and
|
||||||
|
// .concat() can be used to split them into more manageable parts.
|
||||||
|
template<class IntegerT>
|
||||||
|
CXXRTL_ALWAYS_INLINE
|
||||||
|
IntegerT get() const {
|
||||||
|
static_assert(std::numeric_limits<IntegerT>::is_integer && !std::numeric_limits<IntegerT>::is_signed,
|
||||||
|
"get<T>() requires T to be an unsigned integral type");
|
||||||
|
static_assert(std::numeric_limits<IntegerT>::digits >= Bits,
|
||||||
|
"get<T>() requires T to be at least as wide as the value is");
|
||||||
|
IntegerT result = 0;
|
||||||
|
for (size_t n = 0; n < chunks; n++)
|
||||||
|
result |= IntegerT(data[n]) << (n * chunk::bits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class IntegerT>
|
||||||
|
CXXRTL_ALWAYS_INLINE
|
||||||
|
void set(IntegerT other) {
|
||||||
|
static_assert(std::numeric_limits<IntegerT>::is_integer && !std::numeric_limits<IntegerT>::is_signed,
|
||||||
|
"set<T>() requires T to be an unsigned integral type");
|
||||||
|
static_assert(std::numeric_limits<IntegerT>::digits >= Bits,
|
||||||
|
"set<T>() requires the value to be at least as wide as T is");
|
||||||
|
for (size_t n = 0; n < chunks; n++)
|
||||||
|
data[n] = (other >> (n * chunk::bits)) & chunk::mask;
|
||||||
|
}
|
||||||
|
|
||||||
// Operations with compile-time parameters.
|
// Operations with compile-time parameters.
|
||||||
//
|
//
|
||||||
// These operations are used to implement slicing, concatenation, and blitting.
|
// These operations are used to implement slicing, concatenation, and blitting.
|
||||||
|
@ -274,6 +303,10 @@ struct value : public expr_base<value<Bits>> {
|
||||||
data[offset_chunks] |= value ? 1 << offset_bits : 0;
|
data[offset_chunks] |= value ? 1 << offset_bits : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return !is_zero();
|
||||||
|
}
|
||||||
|
|
||||||
bool is_zero() const {
|
bool is_zero() const {
|
||||||
for (size_t n = 0; n < chunks; n++)
|
for (size_t n = 0; n < chunks; n++)
|
||||||
if (data[n] != 0)
|
if (data[n] != 0)
|
||||||
|
@ -281,10 +314,6 @@ struct value : public expr_base<value<Bits>> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const {
|
|
||||||
return !is_zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_neg() const {
|
bool is_neg() const {
|
||||||
return data[chunks - 1] & (1 << ((Bits - 1) % chunk::bits));
|
return data[chunks - 1] & (1 << ((Bits - 1) % chunk::bits));
|
||||||
}
|
}
|
||||||
|
@ -621,6 +650,18 @@ struct wire {
|
||||||
wire(wire<Bits> &&) = default;
|
wire(wire<Bits> &&) = default;
|
||||||
wire<Bits> &operator=(const wire<Bits> &) = delete;
|
wire<Bits> &operator=(const wire<Bits> &) = delete;
|
||||||
|
|
||||||
|
template<class IntegerT>
|
||||||
|
CXXRTL_ALWAYS_INLINE
|
||||||
|
IntegerT get() const {
|
||||||
|
return curr.template get<IntegerT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class IntegerT>
|
||||||
|
CXXRTL_ALWAYS_INLINE
|
||||||
|
void set(IntegerT other) {
|
||||||
|
next.template set<IntegerT>(other);
|
||||||
|
}
|
||||||
|
|
||||||
bool commit() {
|
bool commit() {
|
||||||
if (curr != next) {
|
if (curr != next) {
|
||||||
curr = next;
|
curr = next;
|
||||||
|
@ -967,13 +1008,13 @@ value<BitsY> logic_not(const value<BitsA> &a) {
|
||||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||||
CXXRTL_ALWAYS_INLINE
|
CXXRTL_ALWAYS_INLINE
|
||||||
value<BitsY> logic_and(const value<BitsA> &a, const value<BitsB> &b) {
|
value<BitsY> logic_and(const value<BitsA> &a, const value<BitsB> &b) {
|
||||||
return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u };
|
return value<BitsY> { (bool(a) && bool(b)) ? 1u : 0u };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||||
CXXRTL_ALWAYS_INLINE
|
CXXRTL_ALWAYS_INLINE
|
||||||
value<BitsY> logic_or(const value<BitsA> &a, const value<BitsB> &b) {
|
value<BitsY> logic_or(const value<BitsA> &a, const value<BitsB> &b) {
|
||||||
return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u };
|
return value<BitsY> { (bool(a) || bool(b)) ? 1u : 0u };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduction operations
|
// Reduction operations
|
||||||
|
|
Loading…
Reference in New Issue