Better handling of width of enum literals in expressions.
This commit is contained in:
parent
d37126bda5
commit
5e2c0e5d04
13
elab_expr.cc
13
elab_expr.cc
|
|
@ -2070,6 +2070,19 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
// The width of an enumeration literal is the width of the
|
||||
// enumeration base.
|
||||
if (const NetEConstEnum*par_enum = dynamic_cast<const NetEConstEnum*> (par)) {
|
||||
netenum_t*use_enum = par_enum->enumeration();
|
||||
ivl_assert(*this, use_enum != 0);
|
||||
|
||||
expr_type_ = use_enum->base_type();
|
||||
unsized_flag = false;
|
||||
expr_width_ = max(use_enum->base_width(), min);
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
// The width of a parameter name is the width of the range for
|
||||
// the parameter name, if a range is declared. Otherwise, the
|
||||
// width is undefined.
|
||||
|
|
|
|||
|
|
@ -229,7 +229,11 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
for (list<named_number_t>::const_iterator cur = enum_type->names->begin()
|
||||
; cur != enum_type->names->end() ; ++ cur) {
|
||||
|
||||
rc_flag = use_enum->insert_name(cur->name, cur->parm);
|
||||
// The values are explicitly sized to the width of the
|
||||
// base type of the enumeration.
|
||||
verinum tmp_val (cur->parm, use_enum->base_width());
|
||||
|
||||
rc_flag = use_enum->insert_name(cur->name, tmp_val);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
if (! rc_flag) {
|
||||
cerr << "<>:0: error: Duplicate enumeration name " << cur->name << endl;
|
||||
|
|
|
|||
|
|
@ -440,6 +440,7 @@ unsigned NetEConcat::repeat() const
|
|||
NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, netenum_t*eset, const verinum&v)
|
||||
: NetEConst(v), scope_(s), enum_set_(eset), name_(n)
|
||||
{
|
||||
assert(has_width());
|
||||
}
|
||||
|
||||
NetEConstEnum::~NetEConstEnum()
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@
|
|||
*/
|
||||
|
||||
# include "netenum.h"
|
||||
# include <cassert>
|
||||
|
||||
netenum_t::netenum_t(ivl_variable_type_t base_type, bool signed_flag, long msb, long lsb)
|
||||
: base_type_(base_type), signed_flag_(signed_flag), msb_(msb), lsb_(lsb)
|
||||
netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag, long msb, long lsb)
|
||||
: base_type_(btype), signed_flag_(signed_flag), msb_(msb), lsb_(lsb)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +33,8 @@ bool netenum_t::insert_name(perm_string name, const verinum&val)
|
|||
{
|
||||
std::pair<std::map<perm_string,verinum>::iterator, bool> res;
|
||||
|
||||
assert(val.has_len() && val.len() == (msb_-lsb_+1));
|
||||
|
||||
res = names_map_.insert( make_pair(name,val) );
|
||||
// Only add the name to the list if it is not there already.
|
||||
if (res.second) names_.push_back(name);
|
||||
|
|
|
|||
15
netenum.h
15
netenum.h
|
|
@ -32,6 +32,10 @@ class netenum_t {
|
|||
long msb, long lsb);
|
||||
~netenum_t();
|
||||
|
||||
ivl_variable_type_t base_type() const;
|
||||
unsigned base_width() const;
|
||||
|
||||
// The size() is the number of enumeration literals.
|
||||
size_t size() const;
|
||||
|
||||
bool insert_name(perm_string name, const verinum&val);
|
||||
|
|
@ -53,6 +57,17 @@ class netenum_t {
|
|||
std::list<perm_string> names_;
|
||||
};
|
||||
|
||||
inline ivl_variable_type_t netenum_t::base_type() const
|
||||
{ return base_type_; }
|
||||
|
||||
inline unsigned netenum_t::base_width() const
|
||||
{
|
||||
if (msb_ >= lsb_)
|
||||
return msb_ - lsb_ + 1;
|
||||
else
|
||||
return lsb_ - msb_ + 1;
|
||||
}
|
||||
|
||||
inline size_t netenum_t::size() const { return names_.size(); }
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue