From 410350ae5a28d907bc9868240cc39cce1cebfc0f Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 25 Feb 2012 22:05:00 -0800 Subject: [PATCH] Rework data_type parsing to bring integer vectors into data_type_t method. This adds the vector_type_t and real_type_t types to handle vector and real types in tf_port items. This cleans up a lot of the parsing for these items. --- parse.y | 221 ++++++++++++-------------------------------------- pform.cc | 46 ++++++++--- pform.h | 5 +- pform_types.h | 13 +++ 4 files changed, 101 insertions(+), 184 deletions(-) diff --git a/parse.y b/parse.y index 81c71d14e..eaf4064d5 100644 --- a/parse.y +++ b/parse.y @@ -157,7 +157,7 @@ static list* list_from_identifier(list*tmp, char*id) return tmp; } -static list* copy_range(list* orig) +list* copy_range(list* orig) { list*copy = 0; @@ -317,7 +317,7 @@ static void current_task_set_statement(vector*s) NetNet::Type nettype; PGBuiltin::Type gatetype; NetNet::PortType porttype; - ivl_variable_type_t datatype; + ivl_variable_type_t vartype; PWire*wire; svector*wires; @@ -461,9 +461,9 @@ static void current_task_set_statement(vector*s) %type udp_initial udp_init_opt %type udp_initial_expr_opt -%type register_variable net_variable real_variable endname_opt +%type register_variable net_variable endname_opt %type register_variable_list net_variable_list -%type real_variable_list list_of_identifiers +%type list_of_identifiers %type list_of_port_identifiers %type net_decl_assign net_decl_assigns @@ -506,7 +506,7 @@ static void current_task_set_statement(vector*s) %type variable_decl_assignment %type list_of_variable_decl_assignments -%type data_type +%type data_type data_type_or_implicit %type struct_union_member %type struct_union_member_list %type struct_data_type @@ -516,7 +516,8 @@ static void current_task_set_statement(vector*s) %type net_type var_type net_type_opt %type gatetype switchtype %type port_direction port_direction_opt -%type primitive_type primitive_type_opt bit_logic +%type primitive_type primitive_type_opt bit_logic +%type integer_vector_type %type parameter_value_opt %type function_range_or_type_opt @@ -536,7 +537,7 @@ static void current_task_set_statement(vector*s) %type specify_simple_path specify_simple_path_decl %type specify_edge_path specify_edge_path_decl -%type atom2_type +%type atom2_type non_integer_type %type module_start module_end %token K_TAND @@ -642,7 +643,17 @@ class_item /* IEEE1800-2005: A.1.8 */ ; data_type /* IEEE1800-2005: A.2.2.1 */ - : struct_data_type + : integer_vector_type unsigned_signed_opt range_opt + { vector_type_t*tmp = new vector_type_t($1, $2, $3); + FILE_NAME(tmp, @1); + $$ = tmp; + } + | non_integer_type + { real_type_t*tmp = new real_type_t($1); + FILE_NAME(tmp, @1); + $$ = tmp; + } + | struct_data_type { $$ = $1; } | enum_data_type { $$ = $1; } @@ -659,6 +670,16 @@ data_type /* IEEE1800-2005: A.2.2.1 */ } ; +data_type_or_implicit /* IEEE1800-2005: A.2.2.1 */ + : data_type + { $$ = $1; } + | unsigned_signed_opt range_opt + { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $1, $2); + FILE_NAME(tmp, @1); + $$ = tmp; + } + ; + endnew_opt : ':' K_new | ; for_step /* IEEE1800-2005: A.6.8 */ @@ -708,6 +729,13 @@ inc_or_dec_expression /* IEEE1800-2005: A.4.3 */ } ; +integer_vector_type /* IEEE1800-2005: A.2.2.1 */ + : K_reg { $$ = IVL_VT_LOGIC; } + | K_bit { $$ = IVL_VT_BOOL; } + | K_logic { $$ = IVL_VT_LOGIC; } + | K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */ + ; + /* Loop statements are kinds of statements. */ loop_statement /* IEEE1800-2005: A.6.8 */ @@ -768,6 +796,12 @@ loop_statement /* IEEE1800-2005: A.6.8 */ ; +non_integer_type /* IEEE1800-2005: A.2.2.1 */ + : K_real { $$ = K_real; } + | K_realtime { $$ = K_real; } + | K_shortreal { $$ = K_shortreal; } + ; + number : BASED_NUMBER { $$ = $1; based_size = 0;} | DEC_NUMBER @@ -954,47 +988,9 @@ task_declaration /* IEEE1800-2005: A.2.7 */ tf_port_item /* IEEE1800-2005: A.2.7 */ - : port_direction K_reg_opt unsigned_signed_opt range_opt IDENTIFIER range_opt tf_port_item_expr_opt - { port_declaration_context.port_type = $1; - port_declaration_context.var_type = IVL_VT_LOGIC; - port_declaration_context.sign_flag = $3; - delete port_declaration_context.range; - port_declaration_context.range = copy_range($4); - svector*tmp = pform_make_task_ports(@5, $1, IVL_VT_LOGIC, $3, - $4, list_from_identifier($5)); - $$ = tmp; - if ($6) { - yyerror(@6, "sorry: Port variable dimensions not supported yet."); - delete $6; - } - if ($7) { - yyerror(@7, "sorry: Port default expressions not supported yet."); - delete $7; - } - } - - | port_direction_opt bit_logic unsigned_signed_opt range_opt IDENTIFIER range_opt tf_port_item_expr_opt - { port_declaration_context.port_type = $1; - port_declaration_context.var_type = $2; - port_declaration_context.sign_flag = $3; - delete port_declaration_context.range; - port_declaration_context.range = copy_range($4); - svector*tmp = pform_make_task_ports(@5, $1, $2, $3, - $4, list_from_identifier($5)); - $$ = tmp; - if ($6) { - yyerror(@6, "sorry: Port variable dimensions not supported yet."); - delete $6; - } - if ($7) { - yyerror(@7, "sorry: Port default expressions not supported yet."); - delete $7; - } - } - /* Ports can be integer with a width of [31:0]. */ - | port_direction_opt K_integer IDENTIFIER range_opt tf_port_item_expr_opt + : port_direction_opt K_integer IDENTIFIER range_opt tf_port_item_expr_opt { list*range_stub = make_range_from_width(integer_width); port_declaration_context.port_type = $1; port_declaration_context.var_type = IVL_VT_LOGIC; @@ -1038,28 +1034,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ } } - /* Ports can be real or realtime. */ - - | port_direction_opt real_or_realtime IDENTIFIER range_opt tf_port_item_expr_opt - { port_declaration_context.port_type = $1; - port_declaration_context.var_type = IVL_VT_REAL; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = 0; - svector*tmp = pform_make_task_ports(@3, $1, IVL_VT_REAL, false, - 0, list_from_identifier($3)); - $$ = tmp; - if ($4) { - yyerror(@4, "sorry: Port variable dimensions not supported yet."); - delete $4; - } - if ($5) { - yyerror(@5, "sorry: Port default expressions not supported yet."); - delete $5; - } - } - - | port_direction_opt data_type IDENTIFIER range_opt tf_port_item_expr_opt + | port_direction data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt { port_declaration_context.port_type = $1; port_declaration_context.var_type = IVL_VT_NO_TYPE; port_declaration_context.sign_flag = false; @@ -1111,7 +1086,7 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ | tf_port_list ',' IDENTIFIER { // The declaration is already parsed, apply it to IDENTIFIER - svector*new_decl; + svector*new_decl; if (port_declaration_context.var_type == IVL_VT_NO_TYPE) { assert(port_declaration_context.data_type); new_decl = pform_make_task_ports(@3, port_declaration_context.port_type, @@ -1226,47 +1201,12 @@ attribute rule has presumably set up the scope. */ block_item_decl - : attribute_list_opt K_reg - primitive_type_opt unsigned_signed_opt range - register_variable_list ';' - { ivl_variable_type_t dtype = $3; - if (dtype == IVL_VT_NO_TYPE) - dtype = IVL_VT_LOGIC; - pform_set_net_range($6, $5, $4, dtype); - if ($1) delete $1; - } - /* This differs from the above pattern only in the absence of the - range. This is the rule for a scalar. */ - - | attribute_list_opt K_reg - primitive_type_opt unsigned_signed_opt - register_variable_list ';' - { ivl_variable_type_t dtype = $3; - if (dtype == IVL_VT_NO_TYPE) - dtype = IVL_VT_LOGIC; - pform_set_net_range($5, 0, $4, dtype); - if ($1) delete $1; - } - - | attribute_list_opt K_bit unsigned_signed_opt range_opt - register_variable_list ';' - { - pform_set_net_range($5, $4, $3, IVL_VT_BOOL); - if ($1) delete $1; - } - - | attribute_list_opt K_logic unsigned_signed_opt range_opt - register_variable_list ';' - { - pform_set_net_range($5, $4, $3, IVL_VT_LOGIC); - if ($1) delete $1; - } /* Integer atom declarations are simpler in that they do not have all the trappings of a general variable declaration. All of that is implicit in the "integer" of the declaration. */ - | attribute_list_opt K_integer signed_unsigned_opt register_variable_list ';' + : attribute_list_opt K_integer signed_unsigned_opt register_variable_list ';' { pform_set_reg_integer($4); if ($1) delete $1; } @@ -1284,15 +1224,10 @@ block_item_decl if ($1) delete $1; } - /* real declarations are fairly simple as there is no range of - signed flag in the declaration. Create the real as a NetNet::REG - with real value. Note that real and realtime are interchangeable - in this context. */ - - | attribute_list_opt K_real real_variable_list ';' - { delete $3; } - | attribute_list_opt K_realtime real_variable_list ';' - { delete $3; } + | attribute_list_opt K_reg data_type register_variable_list ';' + { if ($3) pform_set_data_type(@3, $3, $4); + if ($1) delete $1; + } | K_event list_of_identifiers ';' { pform_make_events($2, @1.text, @1.first_line); @@ -1307,12 +1242,6 @@ block_item_decl /* Recover from errors that happen within variable lists. Use the trailing semi-colon to resync the parser. */ - - | attribute_list_opt K_reg error ';' - { yyerror(@2, "error: syntax error in reg variable list."); - yyerrok; - if ($1) delete $1; - } | attribute_list_opt K_integer error ';' { yyerror(@2, "error: syntax error in integer variable list."); yyerrok; @@ -1322,14 +1251,7 @@ block_item_decl { yyerror(@2, "error: syntax error in time variable list."); yyerrok; } - | attribute_list_opt K_real error ';' - { yyerror(@2, "error: syntax error in real variable list."); - yyerrok; - } - | attribute_list_opt K_realtime error ';' - { yyerror(@2, "error: syntax error in realtime variable list."); - yyerrok; - } + | K_parameter error ';' { yyerror(@1, "error: syntax error in parameter list."); yyerrok; @@ -3531,7 +3453,7 @@ module_item /* block_item_decl rule is shared with task blocks and named begin/end. */ - | block_item_decl + | block_item_decl /* */ @@ -4648,45 +4570,6 @@ variable_decl_assignment } ; -real_variable - : IDENTIFIER dimensions_opt - { perm_string name = lex_strings.make($1); - pform_makewire(@1, name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_REAL, 0); - if ($2 != 0) { - index_component_t index; - if ($2->size() > 1) { - yyerror(@2, "sorry: only 1 dimensional arrays " - "are currently supported."); - } - index = $2->front(); - pform_set_reg_idx(name, index.msb, index.lsb); - delete $2; - } - $$ = $1; - } - | IDENTIFIER '=' expression - { perm_string name = lex_strings.make($1); - pform_makewire(@1, name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_REAL, 0); - pform_make_reginit(@1, name, $3); - $$ = $1; - } - ; - -real_variable_list - : real_variable - { list*tmp = new list; - tmp->push_back(lex_strings.make($1)); - $$ = tmp; - delete[]$1; - } - | real_variable_list ',' real_variable - { list*tmp = $1; - tmp->push_back(lex_strings.make($3)); - $$ = tmp; - delete[]$3; - } - ; - net_variable : IDENTIFIER dimensions_opt { perm_string name = lex_strings.make($1); diff --git a/pform.cc b/pform.cc index cd909fb74..2a8653c60 100644 --- a/pform.cc +++ b/pform.cc @@ -1527,10 +1527,10 @@ static void pform_set_net_range(perm_string name, cur->set_data_type(dt); } -void pform_set_net_range(list*names, - list*range, - bool signed_flag, - ivl_variable_type_t dt) +static void pform_set_net_range(list*names, + list*range, + bool signed_flag, + ivl_variable_type_t dt) { assert((range == 0) || (range->size()%2 == 0)); @@ -2197,15 +2197,27 @@ svector*pform_make_task_ports(const struct vlltype&loc, data_type_t*vtype, list*names) { - atom2_type_t*atype = dynamic_cast (vtype); - if (atype == 0) { - VLerror(loc, "sorry: Given type not supported here."); - return 0; + if (atom2_type_t*atype = dynamic_cast (vtype)) { + list*range_tmp = make_range_from_width(atype->type_code); + return pform_make_task_ports(loc, pt, IVL_VT_BOOL, + atype->signed_flag, + range_tmp, names); } - list*range_tmp = make_range_from_width(atype->type_code); - return pform_make_task_ports(loc, pt, IVL_VT_BOOL, atype->signed_flag, - range_tmp, names); + if (vector_type_t*vec_type = dynamic_cast (vtype)) { + return pform_make_task_ports(loc, pt, vec_type->base_type, + vec_type->signed_flag, + copy_range(vec_type->pdims.get()), + names); + } + + if (real_type_t*real_type = dynamic_cast (vtype)) { + return pform_make_task_ports(loc, pt, IVL_VT_REAL, + true, 0, names); + } + + VLerror(loc, "sorry: Given type not supported here."); + return 0; } /* @@ -2608,6 +2620,18 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list (data_type)) { + pform_set_net_range(names, vec_type->pdims.get(), + vec_type->signed_flag, + vec_type->base_type); + return; + } + + if (real_type_t*real_type = dynamic_cast (data_type)) { + pform_set_net_range(names, 0, true, IVL_VT_REAL); + return; + } + assert(0); } diff --git a/pform.h b/pform.h index addf61c94..0e2613715 100644 --- a/pform.h +++ b/pform.h @@ -118,6 +118,7 @@ struct lgate { }; extern std::list* make_range_from_width(uint64_t wid); +extern list* copy_range(list* orig); /* Use this function to transform the parted form of the attribute list to the attribute map that is used later. */ @@ -286,10 +287,6 @@ extern void pform_set_port_type(const struct vlltype&li, extern void pform_set_port_type(perm_string nm, NetNet::PortType pt, const char*file, unsigned lineno); -extern void pform_set_net_range(list*names, - list*, - bool signed_flag, - ivl_variable_type_t); extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r); extern void pform_set_reg_integer(list*names); extern void pform_set_reg_time(list*names); diff --git a/pform_types.h b/pform_types.h index 047592edf..8ec228eaa 100644 --- a/pform_types.h +++ b/pform_types.h @@ -107,6 +107,19 @@ struct atom2_type_t : public data_type_t { bool signed_flag; }; +struct vector_type_t : public data_type_t { + inline explicit vector_type_t(ivl_variable_type_t bt, bool sf, list*pd) + : base_type(bt), signed_flag(sf), pdims(pd) { } + ivl_variable_type_t base_type; + bool signed_flag; + std::auto_ptr< list > pdims; +}; + +struct real_type_t : public data_type_t { + inline explicit real_type_t(int tc) : type_code(tc) { } + int type_code; +}; + /* * The pform_name_t is the general form for a hierarchical * identifier. It is an ordered list of name components. Each name