vhdlpp: Basic support for std.textio & ieee.std_logic_textio.
This commit is contained in:
parent
7b483e69d8
commit
2f40c96527
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue