diff --git a/vhdlpp/Makefile.in b/vhdlpp/Makefile.in index e9d36b68b..0a0f264d2 100644 --- a/vhdlpp/Makefile.in +++ b/vhdlpp/Makefile.in @@ -57,7 +57,7 @@ LIBS = @LIBS@ @EXTRALIBS@ M = StringHeap.o LineInfo.o -O = main.o architec.o compiler.o entity.o std_funcs.o \ +O = main.o architec.o compiler.o entity.o std_funcs.o std_types.o \ expression.o package.o scope.o sequential.o subprogram.o vsignal.o vtype.o \ vtype_match.o \ architec_elaborate.o entity_elaborate.o expression_elaborate.o \ diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index 8b3eed90f..fd1814fcd 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -25,6 +25,7 @@ # include "vsignal.h" # include "subprogram.h" # include "library.h" +# include "std_types.h" # include # include # include "parse_types.h" @@ -980,7 +981,7 @@ const VType* ExpNameALL::probe_type(Entity*, ScopeBase*) const const VType* ExpRelation::probe_type(Entity*, ScopeBase*) const { - return &primitive_BOOLEAN; + return &type_BOOLEAN; } int ExpRelation::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) diff --git a/vhdlpp/library.cc b/vhdlpp/library.cc index be3649005..c6d9d0b31 100644 --- a/vhdlpp/library.cc +++ b/vhdlpp/library.cc @@ -22,6 +22,7 @@ # include "parse_misc.h" # include "compiler.h" # include "package.h" +# include "std_types.h" # include # include # include @@ -318,14 +319,10 @@ static void import_ieee_use_numeric_bit(ActiveScope*res, perm_string name) bool all_flag = name=="all"; if (all_flag || name == "signed") { - vector dims (1); - res->use_name(perm_string::literal("signed"), - new VTypeArray(&primitive_STDLOGIC, dims, true)); + res->use_name(perm_string::literal("signed"), &primitive_SIGNED); } if (all_flag || name == "unsigned") { - vector dims (1); - res->use_name(perm_string::literal("unsigned"), - new VTypeArray(&primitive_BIT, dims, false)); + res->use_name(perm_string::literal("unsigned"), &primitive_UNSIGNED); } } @@ -334,14 +331,10 @@ static void import_ieee_use_numeric_std(ActiveScope*res, perm_string name) bool all_flag = name=="all"; if (all_flag || name == "signed") { - vector dims (1); - res->use_name(perm_string::literal("signed"), - new VTypeArray(&primitive_STDLOGIC, dims, true)); + res->use_name(perm_string::literal("signed"), &primitive_SIGNED); } if (all_flag || name == "unsigned") { - vector dims (1); - res->use_name(perm_string::literal("unsigned"), - new VTypeArray(&primitive_STDLOGIC, dims, false)); + res->use_name(perm_string::literal("unsigned"), &primitive_UNSIGNED); } } @@ -382,60 +375,6 @@ static void import_std_use(const YYLTYPE&loc, ActiveScope*/*res*/, perm_string p } } -const VTypePrimitive primitive_BOOLEAN(VTypePrimitive::BOOLEAN, true); -const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true); -const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER); -const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL); -const VTypePrimitive primitive_REAL(VTypePrimitive::REAL); -const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true); -const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER); -const VTypePrimitive primitive_TIME(VTypePrimitive::TIME); - -const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector (1)); -const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector (1)); -const VTypeArray primitive_STDLOGIC_VECTOR(&primitive_STDLOGIC, vector (1)); -const VTypeArray primitive_STRING(&primitive_CHARACTER, vector (1)); - -void generate_global_types(ActiveScope*res) -{ - res->use_name(perm_string::literal("boolean"), &primitive_BOOLEAN); - res->use_name(perm_string::literal("bit"), &primitive_BIT); - res->use_name(perm_string::literal("bit_vector"), &primitive_BIT_VECTOR); - res->use_name(perm_string::literal("integer"), &primitive_INTEGER); - res->use_name(perm_string::literal("real"), &primitive_REAL); - res->use_name(perm_string::literal("std_logic"), &primitive_STDLOGIC); - res->use_name(perm_string::literal("character"), &primitive_CHARACTER); - res->use_name(perm_string::literal("string"), &primitive_STRING); - res->use_name(perm_string::literal("natural"), &primitive_NATURAL); - res->use_name(perm_string::literal("time"), &primitive_TIME); -} - -void emit_std_types(ostream&out) -{ - out << "`ifndef __VHDL_STD_TYPES" << endl; - out << "`define __VHDL_STD_TYPES" << endl; - out << "typedef enum bit { \\false , \\true } boolean ;" << endl; - out << "`endif" << endl; -} - -bool is_global_type(perm_string name) -{ - if (name == "boolean") return true; - if (name == "bit") return true; - if (name == "bit_vector") return true; - if (name == "integer") return true; - if (name == "real") return true; - if (name == "std_logic") return true; - if (name == "std_logic_vector") return true; - if (name == "character") return true; - if (name == "string") return true; - if (name == "natural") return true; - if (name == "signed") return true; - if (name == "unsigned") return true; - if (name == "time") return true; - return false; -} - void library_set_work_path(const char*path) { assert(library_work_path == 0); diff --git a/vhdlpp/library.h b/vhdlpp/library.h index a161f1cd0..68009a39a 100644 --- a/vhdlpp/library.h +++ b/vhdlpp/library.h @@ -26,8 +26,5 @@ extern void library_add_directory(const char*directory); extern SubprogramHeader*library_find_subprogram(perm_string name); -extern void emit_std_types(ostream&out); -extern int emit_packages(void); - #endif /* IVL_library_H */ diff --git a/vhdlpp/main.cc b/vhdlpp/main.cc index 5d4ad7951..10d901250 100644 --- a/vhdlpp/main.cc +++ b/vhdlpp/main.cc @@ -77,6 +77,7 @@ const char NOTICE[] = # include "compiler.h" # include "library.h" # include "std_funcs.h" +# include "std_types.h" # include "parse_api.h" # include "vtype.h" # include diff --git a/vhdlpp/package.cc b/vhdlpp/package.cc index cf6e74652..64d20fc80 100644 --- a/vhdlpp/package.cc +++ b/vhdlpp/package.cc @@ -22,6 +22,7 @@ # include "entity.h" # include "subprogram.h" # include "parse_misc.h" +# include "std_types.h" # include "ivl_assert.h" Package::Package(perm_string n, const ActiveScope&ref) @@ -57,6 +58,11 @@ void Package::write_to_stream(ostream&fd) const const VTypeDef*def = dynamic_cast (cur->second); if (def == 0) continue; + + // Do not include global types in types dump + if (is_global_type(cur->first)) + continue; + fd << "type " << cur->first << ";" << endl; } for (map::const_iterator cur = cur_types_.begin() @@ -64,6 +70,11 @@ void Package::write_to_stream(ostream&fd) const const VTypeDef*def = dynamic_cast (cur->second); if (def == 0) continue; + + // Do not include global types in types dump + if (is_global_type(cur->first)) + continue; + fd << "type " << cur->first << ";" << endl; } diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index ab344751f..9b107833a 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -40,6 +40,7 @@ # include "vsignal.h" # include "vtype.h" # include "std_funcs.h" +# include "std_types.h" # include # include # include @@ -1607,14 +1608,7 @@ mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ; name /* IEEE 1076-2008 P8.1 */ : IDENTIFIER /* simple_name (IEEE 1076-2008 P8.2) */ - { Expression*tmp; - if(!strcasecmp($1, "true")) - tmp = new ExpBitstring("1"); - else if(!strcasecmp($1, "false")) - tmp = new ExpBitstring("0"); - else - tmp = new ExpName(lex_strings.make($1)); - + { Expression*tmp = new ExpName(lex_strings.make($1)); FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; diff --git a/vhdlpp/parse_misc.h b/vhdlpp/parse_misc.h index e4aa9e644..a18335245 100644 --- a/vhdlpp/parse_misc.h +++ b/vhdlpp/parse_misc.h @@ -63,8 +63,4 @@ extern void library_import(const YYLTYPE&loc, const std::list*names extern void library_use(const YYLTYPE&loc, ActiveScope*res, const char*libname, const char*pack, const char*ident); -extern void generate_global_types(ActiveScope*res); - -extern bool is_global_type(perm_string type_name); - #endif /* IVL_parse_misc_H */ diff --git a/vhdlpp/std_funcs.cc b/vhdlpp/std_funcs.cc index e93debc2d..ec843dd13 100644 --- a/vhdlpp/std_funcs.cc +++ b/vhdlpp/std_funcs.cc @@ -19,7 +19,7 @@ */ #include "std_funcs.h" -#include "vtype.h" +#include "std_types.h" #include "scope.h" static std::map std_subprograms; @@ -160,7 +160,7 @@ void preload_std_funcs(void) fn_rising_edge_args->push_back(new InterfacePort(&primitive_STDLOGIC)); fn_rising_edge = new SubprogramBuiltin(perm_string::literal("rising_edge"), perm_string::literal("$ivlh_rising_edge"), - fn_rising_edge_args, &primitive_BOOLEAN); + fn_rising_edge_args, &type_BOOLEAN); std_subprograms[fn_rising_edge->name()] = fn_rising_edge; /* std_logic_1164 library @@ -170,7 +170,7 @@ void preload_std_funcs(void) fn_falling_edge_args->push_back(new InterfacePort(&primitive_STDLOGIC)); fn_falling_edge = new SubprogramBuiltin(perm_string::literal("falling_edge"), perm_string::literal("$ivlh_falling_edge"), - fn_falling_edge_args, &primitive_BOOLEAN); + fn_falling_edge_args, &type_BOOLEAN); std_subprograms[fn_falling_edge->name()] = fn_falling_edge; /* reduce_pack library diff --git a/vhdlpp/std_types.cc b/vhdlpp/std_types.cc new file mode 100644 index 000000000..9085741ff --- /dev/null +++ b/vhdlpp/std_types.cc @@ -0,0 +1,118 @@ +/* + * Copyright CERN 2015 + * @author Maciej Suminski (maciej.suminski@cern.ch) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "std_types.h" +#include "scope.h" + +static std::map std_types; +// this list contains enums used by typedefs in the std_types map +static std::list std_enums; + +const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true); +const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER); +const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL); +const VTypePrimitive primitive_REAL(VTypePrimitive::REAL); +const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true); +const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER); +const VTypePrimitive primitive_TIME(VTypePrimitive::TIME); + +VTypeDef type_BOOLEAN(perm_string::literal("boolean")); + +const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector (1)); +const VTypeArray primitive_BOOL_VECTOR(&type_BOOLEAN, vector (1)); +const VTypeArray primitive_STDLOGIC_VECTOR(&primitive_STDLOGIC, vector (1)); +const VTypeArray primitive_STRING(&primitive_CHARACTER, vector (1)); +const VTypeArray primitive_SIGNED(&primitive_STDLOGIC, vector (1), true); +const VTypeArray primitive_UNSIGNED(&primitive_STDLOGIC, vector (1), false); + +void generate_global_types(ActiveScope*res) +{ + // boolean + std::list*enum_BOOLEAN_vals = new std::list; + enum_BOOLEAN_vals->push_back(perm_string::literal("false")); + enum_BOOLEAN_vals->push_back(perm_string::literal("true")); + VTypeEnum*enum_BOOLEAN = new VTypeEnum(enum_BOOLEAN_vals); + type_BOOLEAN.set_definition(enum_BOOLEAN); + std_types[type_BOOLEAN.peek_name()] = &type_BOOLEAN; + + res->use_name(type_BOOLEAN.peek_name(), &type_BOOLEAN); + res->use_name(perm_string::literal("bit"), &primitive_BIT); + res->use_name(perm_string::literal("bit_vector"), &primitive_BIT_VECTOR); + res->use_name(perm_string::literal("integer"), &primitive_INTEGER); + res->use_name(perm_string::literal("real"), &primitive_REAL); + res->use_name(perm_string::literal("std_logic"), &primitive_STDLOGIC); + res->use_name(perm_string::literal("character"), &primitive_CHARACTER); + res->use_name(perm_string::literal("string"), &primitive_STRING); + res->use_name(perm_string::literal("natural"), &primitive_NATURAL); + res->use_name(perm_string::literal("time"), &primitive_TIME); +} + +void delete_global_types() +{ + typedef_context_t typedef_ctx; + for(map::iterator cur = std_types.begin(); + cur != std_types.end() ; ++ cur) { + delete cur->second->peek_definition(); + delete cur->second; + } +} + +const VTypeEnum*find_std_enum_name(perm_string name) +{ + for(list::iterator it = std_enums.begin(); + it != std_enums.end(); ++it) { + if((*it)->has_name(name)) + return *it; + } + + return NULL; +} + +void emit_std_types(ostream&fd) +{ + fd << "`ifndef __VHDL_STD_TYPES" << endl; + fd << "`define __VHDL_STD_TYPES" << endl; + typedef_context_t typedef_ctx; + for(map::iterator cur = std_types.begin(); + cur != std_types.end() ; ++ cur) { + cur->second->emit_typedef(fd, typedef_ctx); + } + fd << "`endif" << endl; +} + +bool is_global_type(perm_string name) +{ + if (name == "boolean") return true; + if (name == "bit") return true; + if (name == "bit_vector") return true; + if (name == "integer") return true; + if (name == "real") return true; + if (name == "std_logic") return true; + if (name == "std_logic_vector") return true; + if (name == "character") return true; + if (name == "string") return true; + if (name == "natural") return true; + if (name == "signed") return true; + if (name == "unsigned") return true; + if (name == "time") return true; + + return std_types.count(name) > 0; +} + diff --git a/vhdlpp/std_types.h b/vhdlpp/std_types.h new file mode 100644 index 000000000..6715a4358 --- /dev/null +++ b/vhdlpp/std_types.h @@ -0,0 +1,47 @@ +/* + * Copyright CERN 2015 + * @author Maciej Suminski (maciej.suminski@cern.ch) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "vtype.h" + +class ActiveScope; + +void emit_std_types(ostream&out); +int emit_packages(void); +void generate_global_types(ActiveScope*res); +bool is_global_type(perm_string type_name); +void delete_global_types(); + +extern const VTypePrimitive primitive_BOOLEAN; +extern const VTypePrimitive primitive_BIT; +extern const VTypePrimitive primitive_INTEGER; +extern const VTypePrimitive primitive_NATURAL; +extern const VTypePrimitive primitive_REAL; +extern const VTypePrimitive primitive_STDLOGIC; +extern const VTypePrimitive primitive_CHARACTER; +extern const VTypePrimitive primitive_TIME; + +extern VTypeDef type_BOOLEAN; + +extern const VTypeArray primitive_BIT_VECTOR; +extern const VTypeArray primitive_BOOL_VECTOR; +extern const VTypeArray primitive_STDLOGIC_VECTOR; +extern const VTypeArray primitive_STRING; +extern const VTypeArray primitive_SIGNED; +extern const VTypeArray primitive_UNSIGNED; diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index d2f6ad6dc..0e6c1b47d 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -55,9 +55,6 @@ VTypePrimitive::~VTypePrimitive() void VTypePrimitive::show(ostream&out) const { switch (type_) { - case BOOLEAN: - out << "BOOLEAN"; - break; case BIT: out << "BIT"; break; @@ -85,7 +82,6 @@ void VTypePrimitive::show(ostream&out) const int VTypePrimitive::get_width(ScopeBase*) const { switch(type_) { - case BOOLEAN: case BIT: case STDLOGIC: return 1; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index adf4cea12..6703a86f6 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -156,7 +156,7 @@ class VTypeERROR : public VType { class VTypePrimitive : public VType { public: - enum type_t { BOOLEAN, BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER, TIME }; + enum type_t { BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER, TIME }; public: VTypePrimitive(type_t tt, bool packed = false); @@ -256,6 +256,8 @@ class VTypeArray : public VType { private: int emit_with_dims_(std::ostream&out, bool packed, perm_string name) const; + // Handles a few special types of array (*_vector, string types). + bool write_special_case(std::ostream&out) const; void write_range_to_stream_(std::ostream&fd) const; const VType*etype_; @@ -382,18 +384,4 @@ class VTypeDef : public VType { const VType*type_; }; -extern const VTypePrimitive primitive_BOOLEAN; -extern const VTypePrimitive primitive_BIT; -extern const VTypePrimitive primitive_INTEGER; -extern const VTypePrimitive primitive_NATURAL; -extern const VTypePrimitive primitive_REAL; -extern const VTypePrimitive primitive_STDLOGIC; -extern const VTypePrimitive primitive_CHARACTER; -extern const VTypePrimitive primitive_TIME; - -extern const VTypeArray primitive_BIT_VECTOR; -extern const VTypeArray primitive_BOOL_VECTOR; -extern const VTypeArray primitive_STDLOGIC_VECTOR; -extern const VTypeArray primitive_STRING; - #endif /* IVL_vtype_H */ diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index cfb8f6390..c9fd3649a 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -148,9 +148,6 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const { int errors = 0; switch (type_) { - case BOOLEAN: - out << "boolean"; - break; case BIT: out << "bit"; break; diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index 9f8b6c689..1394ccd06 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -18,7 +18,7 @@ */ # define __STDC_LIMIT_MACROS -# include "vtype.h" +# include "std_types.h" # include "expression.h" # include # include @@ -38,20 +38,8 @@ void VType::write_type_to_stream(ostream&fd) const void VTypeArray::write_to_stream(ostream&fd) const { - // Special cases: std_logic_vector & string - if (etype_ == &primitive_STDLOGIC) { - fd << "std_logic_vector"; - if (!ranges_.empty() && !ranges_[0].is_box()) { - write_range_to_stream_(fd); - } - return; - } else if (etype_ == &primitive_CHARACTER) { - fd << "string"; - if (!ranges_.empty() && !ranges_[0].is_box()) { - write_range_to_stream_(fd); - } - return; - } + if(write_special_case(fd)) + return; bool typedefed = false; if(const VTypeDef*tdef = dynamic_cast(etype_)) { @@ -96,26 +84,37 @@ void VTypeArray::write_range_to_stream_(std::ostream&fd) const fd << ") "; } +bool VTypeArray::write_special_case(std::ostream&fd) const +{ + if(this == &primitive_SIGNED) { + fd << "signed"; + } else if(this == &primitive_UNSIGNED) { + fd << "unsigned"; + } else if(etype_ == &primitive_STDLOGIC) { + fd << "std_logic_vector"; + } else if(etype_ == &primitive_BIT) { + fd << "bit_vector"; + } else if(etype_ == &primitive_CHARACTER) { + fd << "string"; + } else { + return false; + } + + if(!ranges_.empty() && !ranges_[0].is_box()) { + write_range_to_stream_(fd); + } + + return true; +} + void VTypeArray::write_type_to_stream(ostream&fd) const { - // Special case: std_logic_vector - if (etype_ == &primitive_STDLOGIC) { - fd << "std_logic_vector"; - if (! ranges_.empty() && ! ranges_[0].is_box()) { - write_range_to_stream_(fd); - } - return; - } - else if (etype_ == &primitive_CHARACTER) { - fd << "string"; - if (! ranges_.empty() && ! ranges_[0].is_box()) { - write_range_to_stream_(fd); - } - return; - } + if(write_special_case(fd)) + return; fd << "array "; + // Unbounded array if (! ranges_.empty()) { assert(ranges_.size() < 2); if (ranges_[0].is_box()) { @@ -165,9 +164,6 @@ void VTypePrimitive::write_to_stream(ostream&fd) const case CHARACTER: fd << "character"; break; - case BOOLEAN: - fd << "boolean"; - break; case TIME: fd << "time"; break; @@ -183,7 +179,7 @@ void VTypeRange::write_to_stream(ostream&fd) const // Detect some special cases that can be written as ieee or // standard types. if (const VTypePrimitive*tmp = dynamic_cast (base_)) { - if (start_==0 && end_==INT64_MAX && tmp->type()==VTypePrimitive::INTEGER) { + if (tmp->type()==VTypePrimitive::NATURAL) { fd << "natural"; return; }