diff --git a/vhdlpp/library.cc b/vhdlpp/library.cc index c6d9d0b31..03f0ff9df 100644 --- a/vhdlpp/library.cc +++ b/vhdlpp/library.cc @@ -361,13 +361,15 @@ static void import_ieee_use(ActiveScope*res, perm_string package, perm_string na } } -static void import_std_use(const YYLTYPE&loc, ActiveScope*/*res*/, perm_string package, perm_string name) +static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name) { if (package == "standard") { // do nothing return; } else if (package == "textio") { - cerr << "warning: textio package not really supported" << endl; + res->use_name(perm_string::literal("text"), &primitive_INTEGER); + res->use_name(perm_string::literal("line"), &primitive_STRING); + res->use_name(type_FILE_OPEN_KIND.peek_name(), &type_FILE_OPEN_KIND); return; } else { sorrymsg(loc, "package %s of library %s not yet supported", package.str(), name.str()); diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 90e62f23b..6a210f057 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -1235,6 +1235,26 @@ factor } ; +file_declaration + : K_file identifier_list ':' IDENTIFIER ';' + { + if (strcasecmp($4, "TEXT")) + errormsg(@1, "file declaration expected TEXT type\n"); + + for (std::list::iterator cur = $2->begin() + ; cur != $2->end() ; ++cur) { + Variable*var = new Variable(*cur, &primitive_INTEGER); + FILE_NAME(var, @1); + active_scope->bind_name(*cur, var); + } + delete $2; + } + | K_file error ';' + { errormsg(@2, "Syntax error in file declaration.\n"); + yyerrok; + } + ; + for_generate_statement : IDENTIFIER ':' K_for IDENTIFIER K_in range K_generate generate_statement_body @@ -1961,6 +1981,7 @@ procedure_specification /* IEEE 1076-2008 P4.2.1 */ process_declarative_item : variable_declaration + | file_declaration ; process_declarative_part @@ -2506,6 +2527,7 @@ subprogram_declaration subprogram_declarative_item /* IEEE 1079-2008 P4.3 */ : variable_declaration + | file_declaration ; subprogram_declarative_item_list diff --git a/vhdlpp/std_funcs.cc b/vhdlpp/std_funcs.cc index b75aa1ae0..5b875d98f 100644 --- a/vhdlpp/std_funcs.cc +++ b/vhdlpp/std_funcs.cc @@ -92,6 +92,78 @@ static class SubprogramSizeCast : public SubprogramHeader { } }*fn_conv_std_logic_vector, *fn_resize; +static class SubprogramReadWrite : public SubprogramBuiltin { + public: + SubprogramReadWrite(perm_string nam, perm_string newnam) + : SubprogramBuiltin(nam, newnam, NULL, NULL) { + ports_ = new std::list(); + ports_->push_back(new InterfacePort(&primitive_STRING, PORT_INOUT)); + ports_->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR, PORT_INOUT)); + ports_->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + } + + bool is_std() const { return true; } + + // Format types handled by $ivlh_read/write (see vpi/vhdl_textio.c) + enum format_t { FORMAT_STD, FORMAT_BOOL, FORMAT_TIME, FORMAT_HEX, FORMAT_STRING }; + + int emit_args(const std::vector&argv, + std::ostream&out, Entity*ent, ScopeBase*scope) const { + + int errors = 0; + + for(int i = 0; i < 2; ++i) { + errors += argv[i]->emit(out, ent, scope); + out << ", "; + } + + const VType*arg_type = argv[1]->probe_type(ent, scope); + const VTypeArray*arr = dynamic_cast(arg_type); + const VTypePrimitive*prim = dynamic_cast(arg_type); + + // Pick the right format + if(prim && prim->type() == VTypePrimitive::TIME) + out << FORMAT_TIME; + else if(arg_type && arg_type->type_match(&type_BOOLEAN)) + out << FORMAT_BOOL; + else if((arg_type && arg_type->type_match(&primitive_CHARACTER)) || + (arr && arr->element_type() == &primitive_CHARACTER)) + out << FORMAT_STRING; + else + out << FORMAT_STD; + + return errors; + } +}*fn_read, *fn_write; + +static class SubprogramHexReadWrite : public SubprogramBuiltin { + public: + SubprogramHexReadWrite(perm_string nam, perm_string newnam) + : SubprogramBuiltin(nam, newnam, NULL, NULL) { + ports_ = new std::list(); + ports_->push_back(new InterfacePort(&primitive_STRING, PORT_INOUT)); + ports_->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR, PORT_INOUT)); + ports_->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + } + + bool is_std() const { return true; } + + int emit_args(const std::vector&argv, + std::ostream&out, Entity*ent, ScopeBase*scope) const { + + int errors = 0; + + for(int i = 0; i < 2; ++i) { + errors += argv[i]->emit(out, ent, scope); + out << ", "; + } + + out << SubprogramReadWrite::FORMAT_HEX; + + return errors; + } +}*fn_hread, *fn_hwrite; + static SubprogramBuiltin*fn_std_logic_vector; static SubprogramBuiltin*fn_to_unsigned; static SubprogramBuiltin*fn_unsigned; @@ -103,6 +175,13 @@ static SubprogramBuiltin*fn_falling_edge; static SubprogramBuiltin*fn_and_reduce; static SubprogramBuiltin*fn_or_reduce; +static SubprogramBuiltin*fn_file_open; +static SubprogramBuiltin*fn_file_close; +static SubprogramBuiltin*fn_endfile; + +static SubprogramBuiltin*fn_readline; +static SubprogramBuiltin*fn_writeline; + void preload_std_funcs(void) { /* numeric_std library @@ -207,6 +286,86 @@ void preload_std_funcs(void) perm_string::literal("$ivlh_to_unsigned"), fn_to_unsigned_args, &primitive_UNSIGNED); std_subprograms[fn_to_unsigned->name()] = fn_to_unsigned; + + /* procedure file_open (file f: text; filename: in string, file_open_kind: in mode); + */ + std::list*fn_file_open_args = new std::list(); + fn_file_open_args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + fn_file_open_args->push_back(new InterfacePort(&primitive_STRING, PORT_IN)); + fn_file_open_args->push_back(new InterfacePort(&type_FILE_OPEN_KIND, PORT_IN)); + fn_file_open = new SubprogramBuiltin(perm_string::literal("file_open"), + perm_string::literal("$ivlh_file_open"), + fn_file_open_args, NULL); + std_subprograms[fn_file_open->name()] = fn_file_open; + + /* std.textio library + * procedure file_close (file f: text); + */ + std::list*fn_file_close_args = new std::list(); + fn_file_close_args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + fn_file_close = new SubprogramBuiltin(perm_string::literal("file_close"), + perm_string::literal("$fclose"), + fn_file_close_args, NULL); + std_subprograms[fn_file_close->name()] = fn_file_close; + + /* std.textio library + * procedure read (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); + */ + fn_read = new SubprogramReadWrite(perm_string::literal("read"), + perm_string::literal("$ivlh_read")); + std_subprograms[fn_read->name()] = fn_read; + + /* std.textio library + * procedure write (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); + */ + fn_write = new SubprogramReadWrite(perm_string::literal("write"), + perm_string::literal("$ivlh_write")); + std_subprograms[fn_write->name()] = fn_write; + + /* std.textio library + * procedure hread (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); + */ + fn_hread = new SubprogramHexReadWrite(perm_string::literal("hread"), + perm_string::literal("$ivlh_read")); + std_subprograms[fn_hread->name()] = fn_hread; + + /* std.textio library + * procedure hwrite (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); + */ + fn_hwrite = new SubprogramHexReadWrite(perm_string::literal("hwrite"), + perm_string::literal("$ivlh_write")); + std_subprograms[fn_hwrite->name()] = fn_hwrite; + + /* std.textio library + * procedure readline (file f: text; l: inout line); + */ + std::list*fn_readline_args = new std::list(); + fn_readline_args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + fn_readline_args->push_back(new InterfacePort(&primitive_STRING, PORT_OUT)); + fn_readline = new SubprogramBuiltin(perm_string::literal("readline"), + perm_string::literal("$ivlh_readline"), + fn_readline_args, NULL); + std_subprograms[fn_readline->name()] = fn_readline; + + /* std.textio library + * procedure writeline (file f: text; l: inout line); + */ + std::list*fn_writeline_args = new std::list(); + fn_writeline_args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + fn_writeline_args->push_back(new InterfacePort(&primitive_STRING, PORT_IN)); + fn_writeline = new SubprogramBuiltin(perm_string::literal("writeline"), + perm_string::literal("$ivlh_writeline"), + fn_writeline_args, NULL); + std_subprograms[fn_writeline->name()] = fn_writeline; + + /* function endline (file f: text) return boolean; + */ + std::list*fn_endfile_args = new std::list(); + fn_endfile_args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); + fn_endfile = new SubprogramBuiltin(perm_string::literal("endfile"), + perm_string::literal("$feof"), + fn_endfile_args, &type_BOOLEAN); + std_subprograms[fn_endfile->name()] = fn_endfile; } void delete_std_funcs() diff --git a/vhdlpp/std_types.cc b/vhdlpp/std_types.cc index 0454a65e0..516b6ac17 100644 --- a/vhdlpp/std_types.cc +++ b/vhdlpp/std_types.cc @@ -33,6 +33,7 @@ const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true); const VTypePrimitive primitive_TIME(VTypePrimitive::TIME); VTypeDef type_BOOLEAN(perm_string::literal("boolean")); +VTypeDef type_FILE_OPEN_KIND(perm_string::literal("file_open_kind")); const VTypeArray primitive_CHARACTER(&primitive_BIT, 7, 0); const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector (1)); @@ -53,6 +54,16 @@ void generate_global_types(ActiveScope*res) std_types[type_BOOLEAN.peek_name()] = &type_BOOLEAN; std_enums.push_back(enum_BOOLEAN); + // file_open_kind + list*enum_FILE_OPEN_KIND_vals = new list; + enum_FILE_OPEN_KIND_vals->push_back(perm_string::literal("read_mode")); + enum_FILE_OPEN_KIND_vals->push_back(perm_string::literal("write_mode")); + enum_FILE_OPEN_KIND_vals->push_back(perm_string::literal("append_mode")); + VTypeEnum*enum_FILE_OPEN_KIND = new VTypeEnum(enum_FILE_OPEN_KIND_vals); + type_FILE_OPEN_KIND.set_definition(enum_FILE_OPEN_KIND); + std_types[type_FILE_OPEN_KIND.peek_name()] = &type_FILE_OPEN_KIND; + std_enums.push_back(enum_FILE_OPEN_KIND); + 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); diff --git a/vhdlpp/std_types.h b/vhdlpp/std_types.h index 80aef1e17..033ac2167 100644 --- a/vhdlpp/std_types.h +++ b/vhdlpp/std_types.h @@ -35,8 +35,11 @@ extern const VTypePrimitive primitive_NATURAL; extern const VTypePrimitive primitive_REAL; extern const VTypePrimitive primitive_STDLOGIC; extern const VTypePrimitive primitive_TIME; +extern const VTypePrimitive primitive_TEXT; +extern const VTypePrimitive primitive_LINE; extern VTypeDef type_BOOLEAN; +extern VTypeDef type_FILE_OPEN_KIND; extern const VTypeArray primitive_CHARACTER; extern const VTypeArray primitive_BIT_VECTOR;