From f24d6b055d598e3699e81bdbc6829e99ccc98bbc Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 3 Sep 2012 09:13:52 -0700 Subject: [PATCH] Use data_type_t instead of raw type bits. --- parse.y | 88 ++++++++++----------- pform.cc | 178 ++++++++++++++++++++++++------------------- pform.h | 14 +--- pform_string_type.cc | 8 +- pform_struct_type.cc | 12 +-- 5 files changed, 158 insertions(+), 142 deletions(-) diff --git a/parse.y b/parse.y index a3a8919b1..552b7d6db 100644 --- a/parse.y +++ b/parse.y @@ -1842,11 +1842,11 @@ block_item_decl recovering from an error. */ | data_type register_variable_list ';' - { if ($1) pform_set_data_type(@1, $1, $2, attributes_in_context); + { if ($1) pform_set_data_type(@1, $1, $2, NetNet::REG, attributes_in_context); } | K_reg data_type register_variable_list ';' - { if ($2) pform_set_data_type(@2, $2, $3, attributes_in_context); + { if ($2) pform_set_data_type(@2, $2, $3, NetNet::REG, attributes_in_context); } | K_event list_of_identifiers ';' @@ -3902,10 +3902,8 @@ module_item delay3_opt net_variable_list ';' - { ivl_variable_type_t dtype = $3; - if (dtype == IVL_VT_NO_TYPE) - dtype = IVL_VT_LOGIC; - pform_makewire(@2, $5, $4, $7, $2, NetNet::NOT_A_PORT, dtype, $1); + { vector_type_t*tmp = new vector_type_t($3, $4, $5); + pform_set_data_type(@2, tmp, $7, $2, $1); if ($6 != 0) { yyerror(@6, "sorry: net delays not supported."); delete $6; @@ -3914,19 +3912,19 @@ module_item } | attribute_list_opt K_wreal delay3 net_variable_list ';' - { pform_makewire(@2, 0, true, $4, NetNet::WIRE, - NetNet::NOT_A_PORT, IVL_VT_REAL, $1); - if ($3 != 0) { - yyerror(@3, "sorry: net delays not supported."); - delete $3; - } - delete $1; + { real_type_t*tmpt = new real_type_t(real_type_t::REAL); + pform_set_data_type(@2, tmpt, $4, NetNet::WIRE, $1); + if ($3 != 0) { + yyerror(@3, "sorry: net delays not supported."); + delete $3; + } + delete $1; } | attribute_list_opt K_wreal net_variable_list ';' - { pform_makewire(@2, 0, true, $3, NetNet::WIRE, - NetNet::NOT_A_PORT, IVL_VT_REAL, $1); - delete $1; + { real_type_t*tmpt = new real_type_t(real_type_t::REAL); + pform_set_data_type(@2, tmpt, $3, NetNet::WIRE, $1); + delete $1; } /* Very similar to the rule above, but this takes a list of @@ -3940,8 +3938,8 @@ module_item { ivl_variable_type_t dtype = $3; if (dtype == IVL_VT_NO_TYPE) dtype = IVL_VT_LOGIC; - pform_makewire(@2, $5, $4, $6, - str_strength, $7, $2, dtype); + vector_type_t*data_type = new vector_type_t(dtype, $4, $5); + pform_makewire(@2, $6, str_strength, $7, $2, data_type); if ($1) { yyerror(@2, "sorry: Attributes not supported " "on net declaration assignments."); @@ -3953,7 +3951,7 @@ module_item | attribute_list_opt net_type struct_data_type net_variable_list ';' - { pform_makewire(@2, $3, NetNet::NOT_A_PORT, $4, $1); + { pform_set_data_type(@2, $3, $4, $2, $1); delete $1; } @@ -3968,29 +3966,31 @@ module_item /* This form doesn't have the range, but does have strengths. This gives strength to the assignment drivers. */ - | attribute_list_opt net_type - primitive_type_opt unsigned_signed_opt - drive_strength net_decl_assigns ';' + | attribute_list_opt net_type + primitive_type_opt unsigned_signed_opt + drive_strength net_decl_assigns ';' - { ivl_variable_type_t dtype = $3; - if (dtype == IVL_VT_NO_TYPE) - dtype = IVL_VT_LOGIC; - pform_makewire(@2, 0, $4, 0, $5, $6, $2, dtype); - if ($1) { - yyerror(@2, "sorry: Attributes not supported " - "on net declaration assignments."); - delete $1; - } - } - | attribute_list_opt K_wreal net_decl_assigns ';' - { pform_makewire(@2, 0, true, 0, str_strength, $3, - NetNet::WIRE, IVL_VT_REAL); - if ($1) { - yyerror(@2, "sorry: Attributes not supported " - "on net declaration assignments."); - delete $1; - } - } + { ivl_variable_type_t dtype = $3; + if (dtype == IVL_VT_NO_TYPE) + dtype = IVL_VT_LOGIC; + vector_type_t*data_type = new vector_type_t(dtype, $4, 0); + pform_makewire(@2, 0, $5, $6, $2, data_type); + if ($1) { + yyerror(@2, "sorry: Attributes not supported " + "on net declaration assignments."); + delete $1; + } + } + + | attribute_list_opt K_wreal net_decl_assigns ';' + { real_type_t*data_type = new real_type_t(real_type_t::REAL); + pform_makewire(@2, 0, str_strength, $3, NetNet::WIRE, data_type); + if ($1) { + yyerror(@2, "sorry: Attributes not supported " + "on net declaration assignments."); + delete $1; + } + } | K_trireg charge_strength_opt range_opt delay3_opt list_of_identifiers ';' { yyerror(@1, "sorry: trireg nets not supported."); @@ -4890,10 +4890,10 @@ function_range_or_type_opt so that bit ranges can be assigned. */ register_variable : IDENTIFIER dimensions_opt - { perm_string ident_name = lex_strings.make($1); - pform_makewire(@1, ident_name, NetNet::REG, + { perm_string name = lex_strings.make($1); + pform_makewire(@1, name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0); - pform_set_reg_idx(ident_name, $2); + pform_set_reg_idx(name, $2); $$ = $1; } | IDENTIFIER '=' expression diff --git a/pform.cc b/pform.cc index 657f6049f..fb5d8650b 100644 --- a/pform.cc +++ b/pform.cc @@ -1563,6 +1563,7 @@ void pform_make_udp(perm_string name, bool synchronous_flag, * and the name that I receive only has the tail component. */ static void pform_set_net_range(perm_string name, + NetNet::Type net_type, const list*range, bool signed_flag, ivl_variable_type_t dt, @@ -1574,6 +1575,19 @@ static void pform_set_net_range(perm_string name, VLerror("error: name is not a valid net."); return; } + // If this is not implicit ("implicit" meaning we don't + // know what the type is yet) then set the type now. + if (net_type != NetNet::IMPLICIT && net_type != NetNet::NONE) { + bool rc = cur->set_wire_type(net_type); + if (rc == false) { + ostringstream msg; + msg << name << " " << net_type + << " definition conflicts with " << cur->get_wire_type() + << " definition at " << cur->get_fileline() + << "."; + VLerror(msg.str().c_str()); + } + } if (range == 0) { /* This is the special case that we really mean a @@ -1595,12 +1609,13 @@ static void pform_set_net_range(list*names, list*range, bool signed_flag, ivl_variable_type_t dt, + NetNet::Type net_type, std::list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_net_range(txt, range, signed_flag, dt, SR_NET, attr); + pform_set_net_range(txt, net_type, range, signed_flag, dt, SR_NET, attr); } delete names; @@ -2144,7 +2159,7 @@ void pform_makewire(const vlltype&li, pform_makewire(li, txt, type, pt, dt, attr); /* This has already been done for real variables. */ if (dt != IVL_VT_REAL) { - pform_set_net_range(txt, range, signed_flag, dt, rt, 0); + pform_set_net_range(txt, type, range, signed_flag, dt, rt, 0); } } @@ -2156,27 +2171,31 @@ void pform_makewire(const vlltype&li, * This form makes nets with delays and continuous assignments. */ void pform_makewire(const vlltype&li, - list*range, - bool signed_flag, list*delay, str_pair_t str, net_decl_assign_t*decls, NetNet::Type type, - ivl_variable_type_t dt) + data_type_t*data_type) { + // The decls pointer is a circularly linked list. net_decl_assign_t*first = decls->next; - decls->next = 0; + list*names = new list; + + // Go through the circularly linked list non-destructively. + do { + pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0); + names->push_back(first->name); + first = first->next; + } while (first != decls->next); + + pform_set_data_type(li, data_type, names, type, 0); + + // This time, go through the list, deleting cells as I'm done. + first = decls->next; + decls->next = 0; while (first) { net_decl_assign_t*next = first->next; - - pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, dt, 0); - /* This has already been done for real variables. */ - if (dt != IVL_VT_REAL) { - pform_set_net_range(first->name, range, signed_flag, dt, - SR_NET, 0); - } - PWire*cur = pform_get_wire_in_scope(first->name); if (cur != 0) { PEIdent*lval = new PEIdent(first->name); @@ -2705,7 +2724,7 @@ void pform_set_port_type(const struct vlltype&li, ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; pform_set_port_type(txt, pt, li.text, li.first_line); - pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE, + pform_set_net_range(txt, NetNet::NONE, range, signed_flag, IVL_VT_NO_TYPE, SR_PORT, 0); } @@ -2764,9 +2783,9 @@ void pform_set_reg_time(list*names, list*attr) delete names; } -static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, list*attr) +static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list*attr) { - PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_BOOL); + PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_BOOL); assert(cur); cur->set_signed(signed_flag); @@ -2780,92 +2799,42 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_strin pform_bind_attributes(cur->attributes, attr, true); } -static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names, list*attr) +static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names, NetNet::Type net_type, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_integer_2atom(width, signed_flag, txt, attr); + pform_set_integer_2atom(width, signed_flag, txt, net_type, attr); } delete names; } -template static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, list*attr) +template static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, NetNet::Type net_type, list*attr) { ivl_variable_type_t base_type = data_type->figure_packed_base_type(); if (base_type == IVL_VT_NO_TYPE) { VLerror(li, "Compound type is not PACKED in this context."); } - PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type); + PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type); net->set_packed_type(data_type); pform_bind_attributes(net->attributes, attr, true); } -template static void pform_set2_data_type(const struct vlltype&li, T*data_type, list*names, list*attr) +template static void pform_set2_data_type(const struct vlltype&li, T*data_type, list*names, NetNet::Type net_type, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { - pform_set2_data_type(li, data_type, *cur, attr); + pform_set2_data_type(li, data_type, *cur, net_type, attr); } } -/* - * This function detects the derived class for the given type and - * dispatches the type to the proper subtype function. - */ -void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names, list*attr) -{ - if (atom2_type_t*atom2_type = dynamic_cast (data_type)) { - pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, attr); - return; - } - - if (struct_type_t*struct_type = dynamic_cast (data_type)) { - pform_set_struct_type(struct_type, names, attr); - return; - } - - if (enum_type_t*enum_type = dynamic_cast (data_type)) { - pform_set_enum(li, enum_type, names, attr); - return; - } - - if (vector_type_t*vec_type = dynamic_cast (data_type)) { - pform_set_net_range(names, vec_type->pdims.get(), - vec_type->signed_flag, - vec_type->base_type, attr); - return; - } - - if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { - pform_set_net_range(names, 0, true, IVL_VT_REAL, attr); - return; - } - - if (/*class_type_t*class_type =*/ dynamic_cast (data_type)) { - VLerror(li, "sorry: Class types not supported."); - return; - } - - if (parray_type_t*array_type = dynamic_cast (data_type)) { - pform_set2_data_type(li, array_type, names, attr); - return; - } - - if (string_type_t*string_type = dynamic_cast (data_type)) { - pform_set_string_type(string_type, names, attr); - return; - } - - assert(0); -} - static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, - perm_string name, std::list*attr) + perm_string name, NetNet::Type net_type, + std::list*attr) { (void) li; // The line information is not currently needed. - PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, enum_type->base_type); + PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, enum_type->base_type); assert(cur); cur->set_signed(enum_type->signed_flag); @@ -2877,7 +2846,9 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, pform_bind_attributes(cur->attributes, attr, true); } -void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list*names, std::list*attr) +static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, + list*names, NetNet::Type net_type, + std::list*attr) { // By definition, the base type can only be IVL_VT_LOGIC or // IVL_VT_BOOL. @@ -2897,12 +2868,63 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { perm_string txt = *cur; - pform_set_enum(li, enum_type, txt, attr); + pform_set_enum(li, enum_type, txt, net_type, attr); } delete names; } +/* + * This function detects the derived class for the given type and + * dispatches the type to the proper subtype function. + */ +void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names, NetNet::Type net_type, list*attr) +{ + if (atom2_type_t*atom2_type = dynamic_cast (data_type)) { + pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, net_type, attr); + return; + } + + if (struct_type_t*struct_type = dynamic_cast (data_type)) { + pform_set_struct_type(struct_type, names, net_type, attr); + return; + } + + if (enum_type_t*enum_type = dynamic_cast (data_type)) { + pform_set_enum(li, enum_type, names, net_type, attr); + return; + } + + if (vector_type_t*vec_type = dynamic_cast (data_type)) { + pform_set_net_range(names, vec_type->pdims.get(), + vec_type->signed_flag, + vec_type->base_type, net_type, attr); + return; + } + + if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { + pform_set_net_range(names, 0, true, IVL_VT_REAL, net_type, attr); + return; + } + + if (/*class_type_t*class_type =*/ dynamic_cast (data_type)) { + VLerror(li, "sorry: Class types not supported."); + return; + } + + if (parray_type_t*array_type = dynamic_cast (data_type)) { + pform_set2_data_type(li, array_type, names, net_type, attr); + return; + } + + if (string_type_t*string_type = dynamic_cast (data_type)) { + pform_set_string_type(string_type, names, net_type, attr); + return; + } + + assert(0); +} + svector* pform_make_udp_input_ports(list*names) { svector*out = new svector(names->size()); diff --git a/pform.h b/pform.h index 9fd0a408c..d4fbb4e53 100644 --- a/pform.h +++ b/pform.h @@ -265,13 +265,11 @@ extern void pform_makewire(const struct vlltype&li, /* This form handles assignment declarations. */ extern void pform_makewire(const struct vlltype&li, - list*range, - bool signed_flag, list*delay, str_pair_t str, net_decl_assign_t*assign_list, NetNet::Type type, - ivl_variable_type_t); + data_type_t*data_type); /* This form handles nets declared as structures. (See pform_struct_type.cc) */ extern void pform_makewire(const struct vlltype&li, @@ -297,15 +295,11 @@ extern void pform_set_reg_idx(perm_string name, extern void pform_set_reg_integer(list*names, list*attr); extern void pform_set_reg_time(list*names, list*attr); -//XXXXextern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names); +extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list*names, NetNet::Type net_type, list*attr); -extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list*names, list*attr); +extern void pform_set_struct_type(struct_type_t*struct_type, std::list*names, NetNet::Type net_type, std::list*attr); -extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list*names, std::list*attr); - -extern void pform_set_struct_type(struct_type_t*struct_type, std::list*names, std::list*attr); - -extern void pform_set_string_type(string_type_t*string_type, std::list*names, std::list*attr); +extern void pform_set_string_type(string_type_t*string_type, std::list*names, NetNet::Type net_type, std::list*attr); /* pform_set_attrib and pform_set_type_attrib exist to support the $attribute syntax, which can only set string values to diff --git a/pform_string_type.cc b/pform_string_type.cc index 88f376445..593950af5 100644 --- a/pform_string_type.cc +++ b/pform_string_type.cc @@ -21,17 +21,17 @@ # include "parse_misc.h" # include "ivl_assert.h" -static void pform_set_string_type(string_type_t*string_type, perm_string name, list*attr) +static void pform_set_string_type(string_type_t*string_type, perm_string name, NetNet::Type net_type, list*attr) { - PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_STRING); + PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_STRING); pform_bind_attributes(net->attributes, attr, true); } -void pform_set_string_type(string_type_t*string_type, list*names, list*attr) +void pform_set_string_type(string_type_t*string_type, list*names, NetNet::Type net_type, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { - pform_set_string_type(string_type, *cur, attr); + pform_set_string_type(string_type, *cur, net_type, attr); } } diff --git a/pform_struct_type.cc b/pform_struct_type.cc index eab6dc40f..248ce7fb7 100644 --- a/pform_struct_type.cc +++ b/pform_struct_type.cc @@ -51,19 +51,19 @@ ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const * out the base type of the packed variable. Elaboration, later on, * well figure out the rest. */ -static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, list*attr) +static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list*attr) { ivl_variable_type_t base_type = struct_type->figure_packed_base_type(); - PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type); + PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type); net->set_packed_type(struct_type); pform_bind_attributes(net->attributes, attr, true); } -static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, list*attr) +static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list*attr) { if (struct_type->packed_flag) { - pform_set_packed_struct(struct_type, name, attr); + pform_set_packed_struct(struct_type, name, net_type, attr); return; } @@ -71,11 +71,11 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, l ivl_assert(*struct_type, 0); } -void pform_set_struct_type(struct_type_t*struct_type, list*names, list*attr) +void pform_set_struct_type(struct_type_t*struct_type, list*names, NetNet::Type net_type, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { - pform_set_struct_type(struct_type, *cur, attr); + pform_set_struct_type(struct_type, *cur, net_type, attr); } }