diff --git a/parse.y b/parse.y index 2406d7c16..fe6ba14c1 100644 --- a/parse.y +++ b/parse.y @@ -903,11 +903,13 @@ data_type_or_implicit /* IEEE1800-2005: A.2.2.1 */ { $$ = $1; } | signing range_opt { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $1, $2); + tmp->implicit_flag = true; FILE_NAME(tmp, @1); $$ = tmp; } | range { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, $1); + tmp->implicit_flag = true; FILE_NAME(tmp, @1); $$ = tmp; } @@ -3549,62 +3551,32 @@ port_declaration delete[]$4; $$ = ptmp; } - | attribute_list_opt - K_output net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER - { Module::port_t*ptmp; - perm_string name = lex_strings.make($7); - ptmp = pform_module_port_reference(name, @2.text, - @2.first_line); - vector_type_t*tmp = new vector_type_t($4, $5, $6); - pform_module_define_port(@2, name, NetNet::POUTPUT, $3, IVL_VT_NO_TYPE, - false, tmp, 0, $1); - port_declaration_context.port_type = NetNet::POUTPUT; - port_declaration_context.port_net_type = $3; - port_declaration_context.var_type = IVL_VT_NO_TYPE; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = 0; - port_declaration_context.data_type = tmp; - delete[]$7; - $$ = ptmp; - } - | attribute_list_opt - K_output K_reg primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER - { Module::port_t*ptmp; - perm_string name = lex_strings.make($7); - ptmp = pform_module_port_reference(name, @2.text, - @2.first_line); - vector_type_t*tmp = new vector_type_t($4, $5, $6); - tmp->reg_flag = true; - pform_module_define_port(@2, name, NetNet::POUTPUT, NetNet::REG, IVL_VT_NO_TYPE, - false, tmp, 0, $1); - port_declaration_context.port_type = NetNet::POUTPUT; - port_declaration_context.port_net_type = NetNet::REG; - port_declaration_context.var_type = IVL_VT_NO_TYPE; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = 0; - port_declaration_context.data_type = tmp; - delete[]$7; - $$ = ptmp; - } - | attribute_list_opt - K_output atom2_type signed_unsigned_opt IDENTIFIER + | attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($5); - ptmp = pform_module_port_reference(name, @2.text, - @2.first_line); - atom2_type_t*tmp = new atom2_type_t($3, $4); - pform_module_define_port(@2, name, NetNet::POUTPUT, - NetNet::IMPLICIT_REG, IVL_VT_NO_TYPE, - false, tmp, 0, $1); + NetNet::Type use_type = $3; + if (use_type == NetNet::IMPLICIT) { + if (vector_type_t*dtype = dynamic_cast ($4)) { + if (dtype->reg_flag) + use_type = NetNet::REG; + else if (dtype->implicit_flag) + use_type = NetNet::IMPLICIT; + else + use_type = NetNet::IMPLICIT_REG; + } else if (dynamic_cast ($4)) { + use_type = NetNet::IMPLICIT_REG; + } + } + ptmp = pform_module_port_reference(name, @2.text, @2.first_line); + pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, IVL_VT_NO_TYPE, + false, $4, 0, $1); port_declaration_context.port_type = NetNet::POUTPUT; - port_declaration_context.port_net_type = NetNet::IMPLICIT_REG; + port_declaration_context.port_net_type = use_type; port_declaration_context.var_type = IVL_VT_NO_TYPE; port_declaration_context.sign_flag = false; delete port_declaration_context.range; port_declaration_context.range = 0; - port_declaration_context.data_type = tmp; + port_declaration_context.data_type = $4; delete[]$5; $$ = ptmp; } @@ -3626,68 +3598,30 @@ port_declaration delete[]$4; $$ = ptmp; } - | attribute_list_opt - K_output K_reg primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER '=' expression - { Module::port_t*ptmp; - perm_string name = lex_strings.make($7); - ptmp = pform_module_port_reference(name, @2.text, - @2.first_line); - vector_type_t*tmp = new vector_type_t($4, $5, $6); - pform_module_define_port(@2, name, NetNet::POUTPUT, NetNet::REG, IVL_VT_NO_TYPE, - false, tmp, 0, $1); - port_declaration_context.port_type = NetNet::POUTPUT; - port_declaration_context.port_net_type = NetNet::REG; - port_declaration_context.var_type = IVL_VT_NO_TYPE; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = 0; - port_declaration_context.data_type = tmp; - - pform_make_reginit(@7, name, $9); - - delete[]$7; - $$ = ptmp; - } - | attribute_list_opt - K_output net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER '=' expression - { Module::port_t*ptmp; - perm_string name = lex_strings.make($7); - NetNet::Type t = ($3 == NetNet::IMPLICIT) ? NetNet::IMPLICIT_REG : $3; - ptmp = pform_module_port_reference(name, @2.text, - @2.first_line); - vector_type_t*tmp = new vector_type_t($4, $5, $6); - pform_module_define_port(@2, name, NetNet::POUTPUT, t, IVL_VT_NO_TYPE, - false, tmp, 0, $1); - port_declaration_context.port_type = NetNet::POUTPUT; - port_declaration_context.port_net_type = t; - port_declaration_context.var_type = IVL_VT_NO_TYPE; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = 0; - port_declaration_context.data_type = tmp; - - pform_make_reginit(@7, name, $9); - - delete[]$7; - $$ = ptmp; - } - | attribute_list_opt - K_output atom2_type signed_unsigned_opt IDENTIFIER '=' expression + | attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER '=' expression { Module::port_t*ptmp; perm_string name = lex_strings.make($5); - ptmp = pform_module_port_reference(name, @2.text, - @2.first_line); - atom2_type_t*tmp = new atom2_type_t($3, $4); - pform_module_define_port(@2, name, NetNet::POUTPUT, - NetNet::IMPLICIT_REG, IVL_VT_NO_TYPE, - false, tmp, 0, $1); - port_declaration_context.port_type = NetNet::POUTPUT; - port_declaration_context.port_net_type = NetNet::IMPLICIT_REG; + NetNet::Type use_type = $3; + if (use_type == NetNet::IMPLICIT) { + if (vector_type_t*dtype = dynamic_cast ($4)) { + if (dtype->reg_flag) + use_type = NetNet::REG; + else + use_type = NetNet::IMPLICIT_REG; + } else { + use_type = NetNet::IMPLICIT_REG; + } + } + ptmp = pform_module_port_reference(name, @2.text, @2.first_line); + pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, IVL_VT_NO_TYPE, + false, $4, 0, $1); + port_declaration_context.port_type = NetNet::PINOUT; + port_declaration_context.port_net_type = use_type; port_declaration_context.var_type = IVL_VT_NO_TYPE; port_declaration_context.sign_flag = false; delete port_declaration_context.range; port_declaration_context.range = 0; - port_declaration_context.data_type = tmp; + port_declaration_context.data_type = $4; pform_make_reginit(@5, name, $7); diff --git a/pform_types.h b/pform_types.h index 04ee7a0bd..08f4fced2 100644 --- a/pform_types.h +++ b/pform_types.h @@ -108,13 +108,33 @@ struct atom2_type_t : public data_type_t { bool signed_flag; }; +/* + * The vector_type_t class represents types in the old Verilog + * way. Some typical examples: + * + * logic signed [7:0] foo + * bit unsigned foo + * reg foo + * + * There are a few special cases: + * + * For the most part, Verilog treats "logic" and "reg" as synonyms, + * but there are a few cases where the parser needs to know the + * difference. So "reg_flag" is set to true if the IVL_VT_LOGIC type + * is due to the "reg" keyword. + * + * If there are no reg/logic/bit/bool keywords, then Verilog will + * assume the type is logic, but the context may need to know about + * this case, so the implicit_flag member is set to true in that case. + */ struct vector_type_t : public data_type_t { inline explicit vector_type_t(ivl_variable_type_t bt, bool sf, std::list*pd) - : base_type(bt), signed_flag(sf), reg_flag(false), pdims(pd) { } + : base_type(bt), signed_flag(sf), reg_flag(false), implicit_flag(false), pdims(pd) { } ivl_variable_type_t base_type; bool signed_flag; - bool reg_flag; + bool reg_flag; // True if "reg" was used + bool implicit_flag; // True if this type is implicitly logic/reg std::auto_ptr< list > pdims; }; diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index 1e06916ea..41c6dcc3b 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -72,9 +72,7 @@ int VTypeArray::emit_decl(ostream&out, perm_string name, bool reg_flag) const int errors = 0; assert(dimensions() == 1); - if (reg_flag) - out << "reg "; - else + if (!reg_flag) out << "wire "; errors += emit_def(out, name); @@ -135,9 +133,7 @@ int VTypePrimitive::emit_def(ostream&out, perm_string name) const int VTypePrimitive::emit_decl(ostream&out, perm_string name, bool reg_flag) const { int errors = 0; - if (reg_flag) - out << "reg "; - else + if (!reg_flag) out << "wire "; errors += emit_def(out, name);