diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index ea84b86e0..5a95e4f6a 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -950,6 +950,11 @@ static size_t magic_cnt = 0; #define _STR1(x) #x #define _STR2(x) _STR1(x) +static int is_id_char(char c) +{ + return isalnum((int)c) || c == '_' || c == '$'; +} + /* * Find an argument, but only if it is not directly preceded by something * that would make it part of another simple identifier ([a-zA-Z0-9_$]). @@ -964,12 +969,8 @@ static char *find_arg(char*ptr, char*head, char*arg) cp = strstr(cp, arg); if (!cp) break; - /* If we are not at the start of the string verify that this - * match is not in the middle of another identifier. - */ - if (cp != head && - (isalnum((int)*(cp-1)) || *(cp-1) == '_' || *(cp-1) == '$' || - isalnum((int)*(cp+len)) || *(cp+len) == '_' || *(cp+len) == '$')) { + /* Verify that this match is not in the middle of another identifier. */ + if ((cp != head && is_id_char(cp[-1])) || is_id_char(cp[len])) { cp++; continue; } diff --git a/parse.y b/parse.y index 948437000..787f409cb 100644 --- a/parse.y +++ b/parse.y @@ -1044,7 +1044,11 @@ data_type /* IEEE1800-2005: A.2.2.1 */ $$ = tmp; } | struct_data_type - { $$ = $1; } + { if (!$1->packed_flag) { + yyerror(@1, "sorry: Unpacked structs not supported."); + } + $$ = $1; + } | enum_data_type { $$ = $1; } | atom2_type signed_unsigned_opt diff --git a/pform.cc b/pform.cc index 79cc05cf5..61965ef70 100644 --- a/pform.cc +++ b/pform.cc @@ -2422,7 +2422,10 @@ static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name, ivl_variable_type_t dtype) { PWire*cur = pform_get_wire_in_scope(name); - if (cur) { + + // If the wire already exists but isn't yet fully defined, + // carry on adding details. + if (cur && cur->get_data_type() == IVL_VT_NO_TYPE) { // If this is not implicit ("implicit" meaning we don't // know what the type is yet) then set the type now. if (type != NetNet::IMPLICIT) { @@ -2440,6 +2443,18 @@ static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name, return cur; } + // If the wire already exists and is fully defined, this + // must be a redeclaration. Start again with a new wire. + if (cur) { + LineInfo tloc; + FILE_NAME(&tloc, li); + cerr << tloc.get_fileline() << ": error: duplicate declaration " + "for net or variable '" << name << "' in '" + << pform_cur_module.front()->mod_name() << "'." << endl; + error_count += 1; + delete cur; + } + cur = new PWire(name, type, ptype, dtype); FILE_NAME(cur, li.text, li.first_line); @@ -3224,18 +3239,12 @@ template static void pform_set2_data_type(const struct vlltype&li, T*d } } -static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, +static void pform_set_enum(enum_type_t*enum_type, perm_string name, NetNet::Type net_type, std::list*attr) { PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, enum_type->base_type); - // A NULL is returned for a duplicate enumeration. - if (! cur) { - cerr << li.get_fileline() << ": error: Found duplicate " - << "enumeration named " << name << "." << endl; - error_count += 1; - return; - } + assert(cur); cur->set_signed(enum_type->signed_flag); @@ -3273,7 +3282,7 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { perm_string txt = *cur; - pform_set_enum(li, enum_type, txt, net_type, attr); + pform_set_enum(enum_type, txt, net_type, attr); } } diff --git a/pform_struct_type.cc b/pform_struct_type.cc index 766fc77e3..433e66a91 100644 --- a/pform_struct_type.cc +++ b/pform_struct_type.cc @@ -79,8 +79,8 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, N return; } - // For now, can only handle packed structs. - ivl_assert(*struct_type, 0); + // For now, can only handle packed structs. The parser generates + // a "sorry" message, so no need to do anything here. } void pform_set_struct_type(struct_type_t*struct_type, list*names, NetNet::Type net_type, list*attr) diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index e5043fa77..1f939d8d2 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2010-2015 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -432,10 +432,13 @@ static void emit_sig_type(ivl_signal_t sig) } /* Check to see if we have a variable (reg) or a net. */ if (type == IVL_SIT_REG) { + /* The variable data type will be declared later, so here + we just want to declare the range and whether or not it + is signed. */ if (ivl_signal_integer(sig)) { - fprintf(vlog_out, " integer"); + /* nothing to do */ } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { - fprintf(vlog_out, " real"); + /* nothing to do */ } else { int msb, lsb; get_sig_msb_lsb(sig, &msb, &lsb); diff --git a/vvp/main.cc b/vvp/main.cc index 94909d076..917f6322f 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -316,12 +316,13 @@ int main(int argc, char*argv[]) /* For non-interactive runs we do not want to run the interactive * debugger, so make $stop just execute a $finish. */ stop_is_finish = false; - while ((opt = getopt(argc, argv, "+hl:M:m:nNsvV")) != EOF) switch (opt) { + while ((opt = getopt(argc, argv, "+hil:M:m:nNsvV")) != EOF) switch (opt) { case 'h': fprintf(stderr, "Usage: vvp [options] input-file [+plusargs...]\n" "Options:\n" " -h Print this help message.\n" + " -i Interactive mode (unbuffered stdio).\n" " -l file Logfile, '-' for \n" " -M path VPI module directory\n" " -M - Clear VPI module path\n" @@ -332,6 +333,9 @@ int main(int argc, char*argv[]) " -v Verbose progress messages.\n" " -V Print the version information.\n" ); exit(0); + case 'i': + setvbuf(stdout, 0, _IONBF, 0); + break; case 'l': logfile_name = optarg; break; diff --git a/vvp/schedule.cc b/vvp/schedule.cc index a3dc7800f..9ed169fab 100644 --- a/vvp/schedule.cc +++ b/vvp/schedule.cc @@ -531,6 +531,12 @@ bool schedule_stopped(void) */ extern "C" void signals_handler(int) { +#ifdef __MINGW32__ + // Windows implements the original UNIX semantics for signal, + // so we have to re-establish the signal handler each time a + // signal is caught. + signal(SIGINT, &signals_handler); +#endif schedule_stopped_flag = true; } diff --git a/vvp/vvp.man.in b/vvp/vvp.man.in index 37a5bcb7c..650e853c4 100644 --- a/vvp/vvp.man.in +++ b/vvp/vvp.man.in @@ -4,7 +4,7 @@ vvp - Icarus Verilog vvp runtime engine .SH SYNOPSIS .B vvp -[\-nNsvV] [\-Mpath] [\-mmodule] [\-llogfile] inputfile [extended-args...] +[\-inNsvV] [\-Mpath] [\-mmodule] [\-llogfile] inputfile [extended-args...] .SH DESCRIPTION .PP @@ -16,6 +16,9 @@ command is not by itself executable on any platform. Instead, the .SH OPTIONS \fIvvp\fP accepts the following options: .TP 8 +.B -i +This flag causes all output to to be unbuffered. +.TP 8 .B -l\fIlogfile\fP This flag specifies a logfile where all MCI output goes. Specify logfile as '\-' to send log output to . $display and