diff --git a/PScope.h b/PScope.h index 3a16c72fa..a6c11466c 100644 --- a/PScope.h +++ b/PScope.h @@ -100,7 +100,7 @@ class LexicalScope { list analog_behaviors; // Enumeration sets. - list enum_sets; + list enum_sets; LexicalScope* parent_scope() const { return parent_; } diff --git a/PWire.cc b/PWire.cc index 652c02d6a..83bcc8374 100644 --- a/PWire.cc +++ b/PWire.cc @@ -30,7 +30,7 @@ PWire::PWire(perm_string n, signed_(false), isint_(false), port_msb_(0), port_lsb_(0), port_set_(false), net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false), - error_cnt_(0), lidx_(0), ridx_(0), enum_set_(0), discipline_(0) + error_cnt_(0), lidx_(0), ridx_(0), enum_type_(0), discipline_(0) { if (t == NetNet::INTEGER) { type_ = NetNet::REG; @@ -206,10 +206,10 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx) } } -void PWire::set_enumeration(enum_set_t enum_set) +void PWire::set_enumeration(enum_type_t*enum_type) { - assert(enum_set_ == 0); - enum_set_ = enum_set; + assert(enum_type_ == 0); + enum_type_ = enum_type; } void PWire::set_discipline(ivl_discipline_t d) diff --git a/PWire.h b/PWire.h index 72c02a63d..680593edb 100644 --- a/PWire.h +++ b/PWire.h @@ -79,7 +79,7 @@ class PWire : public LineInfo { void set_memory_idx(PExpr*ldx, PExpr*rdx); - void set_enumeration(enum_set_t enum_set); + void set_enumeration(enum_type_t*enum_type); void set_discipline(ivl_discipline_t); ivl_discipline_t get_discipline(void) const; @@ -115,7 +115,7 @@ class PWire : public LineInfo { PExpr*lidx_; PExpr*ridx_; - enum_set_t enum_set_; + enum_type_t*enum_type_; ivl_discipline_t discipline_; diff --git a/elab_scope.cc b/elab_scope.cc index 5cd1aadf7..a83bfa269 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -208,29 +208,41 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope, } static void elaborate_scope_enumeration(Design*des, NetScope*scope, - enum_set_t enum_set) + enum_type_t*enum_type) { - netenum_t*use_enum = new netenum_t(IVL_VT_BOOL, true, 31, 0); + bool rc_flag; + assert(enum_type->range->size() == 2); + NetExpr*msb_ex = enum_type->range->front()->elaborate_pexpr(des, scope); + NetExpr*lsb_ex = enum_type->range->back() ->elaborate_pexpr(des, scope); + + long msb = 0; + rc_flag = eval_as_long(msb, msb_ex); + assert(rc_flag); + long lsb = 0; + rc_flag = eval_as_long(lsb, lsb_ex); + assert(rc_flag); + + netenum_t*use_enum = new netenum_t(enum_type->base_type, enum_type->signed_flag, msb, lsb); scope->add_enumeration_set(use_enum); - for (map::const_iterator cur = enum_set->begin() - ; cur != enum_set->end() ; ++ cur) { + for (list::const_iterator cur = enum_type->names->begin() + ; cur != enum_type->names->end() ; ++ cur) { - bool rc = use_enum->insert_name(cur->first, cur->second); - rc &= scope->add_enumeration_name(use_enum, cur->first); - if (! rc) { - cerr << "<>:0: error: Duplicate enumeration name " << cur->first << endl; + rc_flag = use_enum->insert_name(cur->name, cur->parm); + rc_flag &= scope->add_enumeration_name(use_enum, cur->name); + if (! rc_flag) { + cerr << "<>:0: error: Duplicate enumeration name " << cur->name << endl; des->errors += 1; } } } static void elaborate_scope_enumerations(Design*des, NetScope*scope, - const list&enum_sets) + const list&enum_types) { - for (list::const_iterator cur = enum_sets.begin() - ; cur != enum_sets.end() ; ++ cur) { + for (list::const_iterator cur = enum_types.begin() + ; cur != enum_types.end() ; ++ cur) { elaborate_scope_enumeration(des, scope, *cur); } } diff --git a/elab_sig.cc b/elab_sig.cc index c6ea862e7..7ce32ca43 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1100,10 +1100,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const // If this is an enumeration, then set the enumeration set for // the new signal. This turns it into an enumeration. - if (enum_set_) { - ivl_assert(*this, enum_set_->size() > 0); - enum_set_m::const_iterator sample_name = enum_set_->begin(); - netenum_t*use_enum = scope->enumeration_for_name(sample_name->first); + if (enum_type_) { + ivl_assert(*this, enum_type_->names->size() > 0); + list::const_iterator sample_name = enum_type_->names->begin(); + netenum_t*use_enum = scope->enumeration_for_name(sample_name->name); sig->set_enumeration(use_enum); } diff --git a/net_expr.cc b/net_expr.cc index 0b910d39f..b855e0737 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -438,7 +438,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) +: NetEConst(v), scope_(s), enum_set_(eset), name_(n) { } diff --git a/net_scope.cc b/net_scope.cc index 2ae098089..5535715f1 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -461,7 +461,7 @@ void NetScope::add_enumeration_set(netenum_t*enum_set) bool NetScope::add_enumeration_name(netenum_t*enum_set, perm_string name) { - enum_set_m::const_iterator enum_val = enum_set->find_name(name); + netenum_t::iterator enum_val = enum_set->find_name(name); assert(enum_val != enum_set->end_name()); NetEConstEnum*val = new NetEConstEnum(this, name, enum_set, enum_val->second); diff --git a/pform.cc b/pform.cc index 24e5d9c5a..6e957918d 100644 --- a/pform.cc +++ b/pform.cc @@ -378,7 +378,7 @@ static void pform_put_wire_in_scope(perm_string name, PWire*net) lexical_scope->wires[name] = net; } -static void pform_put_enum_set_in_scope(enum_set_t enum_set) +static void pform_put_enum_type_in_scope(enum_type_t*enum_set) { lexical_scope->enum_sets.push_back(enum_set); } @@ -2462,7 +2462,7 @@ void pform_set_integer_2atom(uint64_t width, bool signed_flag, list } static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, - enum_set_t enum_set, perm_string name) + perm_string name) { PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, enum_type->base_type); assert(cur); @@ -2472,7 +2472,7 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, assert(enum_type->range.get() != 0); assert(enum_type->range->size() == 2); cur->set_range(enum_type->range->front(), enum_type->range->back(), SR_NET, false); - cur->set_enumeration(enum_set); + cur->set_enumeration(enum_type); } void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list*names) @@ -2487,7 +2487,6 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list::iterator cur = enum_type->names->begin() @@ -2505,6 +2504,9 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, listparm - next_value; + } else { if (enum_type->base_type==IVL_VT_BOOL && ! next_value.is_defined()) { cerr << li.text << ":" << li.first_line << ": " @@ -2514,32 +2516,20 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list::iterator map_name = enum_map->find(cur->name); - if (map_name == enum_map->end()) { - enum_map->insert(make_pair(cur->name, next_value));; - - } else { - cerr << li.text << ":" << li.first_line << ": " - << "error: Enumeration name " << cur->name - << " is already defined." << endl; - error_count += 1; - } } // Attach the enumeration to the current scope. - pform_put_enum_set_in_scope(enum_map); + pform_put_enum_type_in_scope(enum_type); // Now apply the checked enumeration type to the variables // that are being declared with this type. for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { perm_string txt = *cur; - pform_set_enum(li, enum_type, enum_map, txt); + pform_set_enum(li, enum_type, txt); } delete names; - delete enum_type; } svector* pform_make_udp_input_ports(list*names) diff --git a/pform.h b/pform.h index e263946be..77d77042d 100644 --- a/pform.h +++ b/pform.h @@ -86,8 +86,6 @@ extern bool pform_library_flag; typedef named named_pexpr_t; -typedef named named_number_t; - struct parmvalue_t { list*by_order; svector*by_name; @@ -102,13 +100,6 @@ struct net_decl_assign_t { struct net_decl_assign_t*next; }; -struct enum_type_t { - ivl_variable_type_t base_type; - bool signed_flag; - auto_ptr< list > range; - auto_ptr< list > names; -}; - /* The lgate is gate instantiation information. */ struct lgate { lgate(int =0) diff --git a/pform_dump.cc b/pform_dump.cc index dc071f27b..31d6db5f3 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -1108,14 +1108,14 @@ void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const { - for (list::const_iterator cur = enum_sets.begin() + for (list::const_iterator cur = enum_sets.begin() ; cur != enum_sets.end() ; ++ cur) { out << setw(indent) << "" << "enum {" << endl; - for (map::const_iterator idx = (*cur)->begin() - ; idx != (*cur)->end() ; ++ idx) { - out << setw(indent+4) << "" << idx->first - << " = " << idx->second << endl; + for (list::const_iterator idx = (*cur)->names->begin() + ; idx != (*cur)->names->end() ; ++ idx) { + out << setw(indent+4) << "" << idx->name + << " = " << idx->parm << endl; } out << setw(indent) << "" << "}" << endl; diff --git a/pform_types.h b/pform_types.h index 94eb516bd..e6d5f6d01 100644 --- a/pform_types.h +++ b/pform_types.h @@ -22,6 +22,8 @@ // This for the perm_string type. # include "StringHeap.h" # include "verinum.h" +# include "named.h" +# include "ivl_target.h" # include # include # include @@ -30,6 +32,8 @@ * parse-form types. */ +typedef named named_number_t; + struct index_component_t { enum ctype_t { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO }; @@ -50,11 +54,17 @@ struct name_component_t { }; /* - * The enum_map_t holds the values that represent the enumeration. An - * enumeration, then, is defined by its pointer to the set. + * The enum_type_t holds the parsed declaration to represent an + * enumeration. Since this is in the pform, it represents the type + * before elaboration to the range, for example, man not be complete + * until it is elaborated in a scope. */ -typedef map enum_set_m; -typedef enum_set_m *enum_set_t; +struct enum_type_t { + ivl_variable_type_t base_type; + bool signed_flag; + auto_ptr< list > range; + auto_ptr< list > names; +}; /*