vhdlpp: Basic support for std.textio & ieee.std_logic_textio.

This commit is contained in:
Maciej Suminski 2015-09-23 16:25:35 +02:00
parent 7b483e69d8
commit 2f40c96527
5 changed files with 199 additions and 2 deletions

View File

@ -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());

View File

@ -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<perm_string>::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

View File

@ -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<InterfacePort*>();
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<Expression*>&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<const VTypeArray*>(arg_type);
const VTypePrimitive*prim = dynamic_cast<const VTypePrimitive*>(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<InterfacePort*>();
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<Expression*>&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<InterfacePort*>*fn_file_open_args = new std::list<InterfacePort*>();
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<InterfacePort*>*fn_file_close_args = new std::list<InterfacePort*>();
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<InterfacePort*>*fn_readline_args = new std::list<InterfacePort*>();
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<InterfacePort*>*fn_writeline_args = new std::list<InterfacePort*>();
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<InterfacePort*>*fn_endfile_args = new std::list<InterfacePort*>();
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()

View File

@ -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<VTypeArray::range_t> (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<perm_string>*enum_FILE_OPEN_KIND_vals = new list<perm_string>;
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);

View File

@ -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;