diff --git a/Module.cc b/Module.cc index e608a6401..774dfdbf7 100644 --- a/Module.cc +++ b/Module.cc @@ -30,6 +30,7 @@ Module::Module(perm_string n) { library_flag = false; is_cell = false; + uc_drive = UCD_NONE; default_nettype = NetNet::NONE; timescale_warn_done = false; } diff --git a/Module.h b/Module.h index a2960bc74..80d43031a 100644 --- a/Module.h +++ b/Module.h @@ -76,6 +76,9 @@ class Module : public PScope, public LineInfo { bool is_cell; + enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 }; + UCDriveType uc_drive; + NetNet::Type default_nettype; /* specparams are simpler then other params, in that they have diff --git a/PDelays.cc b/PDelays.cc index 06729fe3d..efbc36861 100644 --- a/PDelays.cc +++ b/PDelays.cc @@ -65,8 +65,11 @@ void PDelays::set_delays(const svector*del, bool df) delete_flag_ = df; } -static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr) +static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr) { + ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE; + bool tmp_flag = false; + expr->test_width(des, scope, 0, 0, tmp_type, tmp_flag); NetExpr*dex = expr->elaborate_expr(des, scope, -1, false); eval_expr(dex); diff --git a/compiler.h b/compiler.h index e604e4da2..5ced0b0b0 100644 --- a/compiler.h +++ b/compiler.h @@ -113,9 +113,10 @@ extern int build_library_index(const char*path, bool key_case_sensitive); specific language features. */ enum generation_t { GN_VER1995 = 1, - GN_VER2001 = 2, - GN_VER2005 = 3, - GN_DEFAULT = 3 + GN_VER2001_NOCONFIG = 2, + GN_VER2001 = 3, + GN_VER2005 = 4, + GN_DEFAULT = 4 }; extern generation_t generation_flag; diff --git a/driver/iverilog.man b/driver/iverilog.man index a7a4f743e..e739aed2f 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -1,4 +1,4 @@ -.TH iverilog 1 "April 17th, 2009" "" "Version 0.10.devel" +.TH iverilog 1 "May 28th, 2009" "" "Version 0.10.devel" .SH NAME iverilog - Icarus Verilog compiler @@ -55,20 +55,20 @@ is the Verilog input, but with file inclusions and macro references expanded and removed. This is useful, for example, to preprocess Verilog source for use by other compilers. .TP 8 -.B -g1995\fI|\fP-g2001\fI|\fP-g2005 +.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005 Select the Verilog language \fIgeneration\fP to support in the compiler. This selects between \fIIEEE1364-1995\fP, -\fIIEEE1364-2001\fP(2), or \fIIEEE1364-2005\fP. Normally, +\fIIEEE1364-2001\fP, or \fIIEEE1364-2005\fP. Normally, Icarus Verilog defaults to the latest known generation of the language. This flag is most useful to restrict the language to a set supported by tools of specific generations, for compatibility with other tools. .TP 8 -.B -gverilog-ams\fI|-fP-gno-verilog-ams +.B -gverilog-ams\fI|\fP-gno-verilog-ams Enable or disable (default) support for Verilog-AMS. Very little Verilog-AMS specific functionality is currently supported. .TP 8 -.B -gsystem-verilog\fI|-fP-gno-system-verilog +.B -gsystem-verilog\fI|\fP-gno-system-verilog Enable or disable (default) support for SystemVerilog. Very little SystemVerilog specific functionality is currently supported. .TP 8 @@ -115,9 +115,9 @@ expression changes value, the entire expression is re-evaluated. By default, parts of the expression that do not depend on the changed input value(s) are not re-evaluated. If an expression contains a call to a function that doesn't depend solely on its input values or that -has side effects, the resulting behaviour will differ from that +has side effects, the resulting behavior will differ from that required by the standard. Using \fI-gstrict-ca-eval\fP will force -standard compliant behaviour (with some loss in performance). +standard compliant behavior (with some loss in performance). .TP 8 .B -I\fIincludedir\fP Append directory \fIincludedir\fP to list of directories searched @@ -203,6 +203,11 @@ all the requested classes. Append the directory to the library module search path. When the compiler finds an undefined module, it looks in these directories for files with the right name. +.TP 8 +.B -Y\fIsuffix\fP +Add suffix to the list of accepted file name suffixes used when +searching a library for cells. The list defaults to the single +entry \fI.v\fP. .SH MODULE LIBRARIES @@ -448,7 +453,7 @@ Tips on using, debugging, and developing the compiler can be found at .SH COPYRIGHT .nf -Copyright \(co 2002-2008 Stephen Williams +Copyright \(co 2002-2009 Stephen Williams This document can be freely redistributed according to the terms of the GNU General Public License version 2.0 diff --git a/driver/main.c b/driver/main.c index 66e451397..bf322d77d 100644 --- a/driver/main.c +++ b/driver/main.c @@ -557,6 +557,9 @@ int process_generation(const char*name) else if (strcmp(name,"2001") == 0) generation = "2001"; + else if (strcmp(name,"2001-noconfig") == 0) + generation = "2001-noconfig"; + else if (strcmp(name,"2005") == 0) generation = "2005"; diff --git a/elab_net.cc b/elab_net.cc index 143674c6e..719173b69 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -179,7 +179,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const assert(nettype != NetNet::NONE); NetNet*sig = new NetNet(scope, peek_tail_name(path_), - NetNet::IMPLICIT, 1); + nettype, 1); sig->set_line(*this); /* Implicit nets are always scalar logic. */ sig->data_type(IVL_VT_LOGIC); diff --git a/elaborate.cc b/elaborate.cc index e5674c474..3dec83463 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -978,6 +978,28 @@ static bool need_bufz_for_input_port(const vector&prts) return false; } +/* + * Convert a wire or tri to a tri0 or tri1 as needed to make + * an unconnected drive pull for floating inputs. + */ +static void convert_net(Design*des, const LineInfo *line, + NetNet *net, NetNet::Type type) +{ + // If the types already match just return. + if (net->type() == type) return; + + // We can only covert a wire or tri to have a default pull. + if (net->type() == NetNet::WIRE || net->type() == NetNet::TRI) { + net->type(type); + return; + } + + // We may have to support this at some point in time! + cerr << line->get_fileline() << ": sorry: Can not pull floating " + "input type '" << net->type() << "'." << endl; + des->errors += 1; +} + /* * Instantiate a module by recursively elaborating it. Set the path of * the recursive elaboration so that signal names get properly @@ -1105,28 +1127,50 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const // null parameter is passed in. if (pins[idx] == 0) { + // We need this information to support the + // unconnected_drive directive and for a + // unconnected input warning when asked for. + vector mport = rmod->get_port(idx); + if (mport.size() == 0) continue; - // While we're here, look to see if this - // unconnected (from the outside) port is an - // input. If so, consider printing a port binding - // warning. - if (warn_portbinding) { - vector mport = rmod->get_port(idx); - if (mport.size() == 0) - continue; + perm_string pname = peek_tail_name(mport[0]->path()); - perm_string pname = peek_tail_name(mport[0]->path()); + NetNet*tmp = instance[0]->find_signal(pname); + assert(tmp); - NetNet*tmp = instance[0]->find_signal(pname); - assert(tmp); + if (tmp->port_type() == NetNet::PINPUT) { + // If we have an unconnected input convert it + // as needed if an unconnected_drive directive + // was given. This only works for tri or wire! + switch (rmod->uc_drive) { + case Module::UCD_PULL0: + convert_net(des, this, tmp, NetNet::TRI0); + break; + case Module::UCD_PULL1: + convert_net(des, this, tmp, NetNet::TRI1); + break; + case Module::UCD_NONE: + break; + } - if (tmp->port_type() == NetNet::PINPUT) { + // Print a waring for an unconnected input. + if (warn_portbinding) { cerr << get_fileline() << ": warning: " << "Instantiating module " << rmod->mod_name() - << " with dangling input port " - << rmod->ports[idx]->name - << "." << endl; + << " with dangling input port '" + << rmod->ports[idx]->name; + switch (rmod->uc_drive) { + case Module::UCD_PULL0: + cerr << "' (pulled low)." << endl; + break; + case Module::UCD_PULL1: + cerr << "' (pulled high)." << endl; + break; + case Module::UCD_NONE: + cerr << "' (floating)." << endl; + break; + } } } diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index 875e40050..e96ecf3e7 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -64,13 +64,8 @@ struct include_stack_t /* If we are reparsing a macro expansion, file is 0 and this * member points to the string in progress */ - const char* str; - - /* If we are reparsing a macro expansion, this member indicates - * the amount of space it occupies in the macro expansion buffer. - * This will be zero for macros without arguments. - */ - int ebs; + char* str; + char* orig_str; int stringify_flag; @@ -1372,6 +1367,7 @@ static void do_expand(int use_args) head = exp_buf_size - exp_buf_free; expand_using_args(); tail = exp_buf_size - exp_buf_free; + exp_buf_free += tail - head; if (tail == head) return; @@ -1384,12 +1380,10 @@ static void do_expand(int use_args) if (use_args) { isp->str = &exp_buf[head]; - isp->ebs = tail - head; } else { isp->str = cur_macro->value; - isp->ebs = 0; } /* Escape some characters if we are making a string version. */ @@ -1419,16 +1413,14 @@ static void do_expand(int use_args) } str_buf[idx] = 0; idx += 1; - if (use_args) exp_buf_free += isp->ebs; - exp_buf_grow_to_fit(idx); - head = exp_buf_size - exp_buf_free; - exp_buf_free -= idx; - strcpy(&exp_buf[head], str_buf); - isp->str = &exp_buf[head]; - isp->ebs = idx; - free(str_buf); - } + exp_buf_free -= idx; + + isp->str = str_buf; + } else + isp->str = strdup(isp->str); + + isp->orig_str = isp->str; isp->next = istack; istack->yybs = YY_CURRENT_BUFFER; istack = isp; @@ -1617,7 +1609,7 @@ static int load_next_input() else line_mask_flag = 1; - exp_buf_free += isp->ebs; + free(isp->orig_str); } if (isp->stringify_flag) { @@ -1794,7 +1786,6 @@ void reset_lexor(FILE* out, char* paths[]) isp->path = strdup(paths[0]); isp->file = fopen(paths[0], "r"); isp->str = 0; - isp->ebs = 0; isp->lineno = 0; isp->stringify_flag = 0; isp->comment = NULL; @@ -1824,7 +1815,6 @@ void reset_lexor(FILE* out, char* paths[]) isp->path = strdup(paths[idx]); isp->file = 0; isp->str = 0; - isp->ebs = 0; isp->next = 0; isp->lineno = 0; isp->stringify_flag = 0; diff --git a/lexor.lex b/lexor.lex index ad0df6906..d62325d87 100644 --- a/lexor.lex +++ b/lexor.lex @@ -80,6 +80,7 @@ static verinum*make_unsized_hex(const char*txt); static int dec_buf_div2(char *buf); static void process_timescale(const char*txt); +static void process_ucdrive(const char*txt); static list keyword_mask_stack; @@ -87,6 +88,7 @@ static int comment_enter; static bool in_module = false; static bool in_UDP = false; bool in_celldefine = false; +UCDriveType uc_drive = UCD_NONE; %} %x CCOMMENT @@ -95,6 +97,7 @@ bool in_celldefine = false; %x CSTRING %s UDPTABLE %x PPTIMESCALE +%x PPUCDRIVE %x PPDEFAULT_NETTYPE %x PPBEGIN_KEYWORDS %s EDGES @@ -271,22 +274,35 @@ S [afpnumkKMGT] return IDENTIFIER; } \$([a-zA-Z0-9$_]+) { - if (strcmp(yytext,"$setuphold") == 0) - return K_Ssetuphold; - if (strcmp(yytext,"$attribute") == 0) - return KK_attribute; + /* The 1364-1995 timing checks. */ if (strcmp(yytext,"$hold") == 0) return K_Shold; + if (strcmp(yytext,"$nochange") == 0) + return K_Snochange; if (strcmp(yytext,"$period") == 0) return K_Speriod; if (strcmp(yytext,"$recovery") == 0) return K_Srecovery; - if (strcmp(yytext,"$recrem") == 0) - return K_Srecrem; if (strcmp(yytext,"$setup") == 0) return K_Ssetup; + if (strcmp(yytext,"$setuphold") == 0) + return K_Ssetuphold; + if (strcmp(yytext,"$skew") == 0) + return K_Sskew; if (strcmp(yytext,"$width") == 0) return K_Swidth; + /* The new 1364-2001 timing checks. */ + if (strcmp(yytext,"$fullskew") == 0) + return K_Sfullskew; + if (strcmp(yytext,"$recrem") == 0) + return K_Srecrem; + if (strcmp(yytext,"$removal") == 0) + return K_Sremoval; + if (strcmp(yytext,"$timeskew") == 0) + return K_Stimeskew; + + if (strcmp(yytext,"$attribute") == 0) + return KK_attribute; yylval.text = strdupnew(yytext); return SYSTEM_IDENTIFIER; } @@ -392,16 +408,36 @@ S [afpnumkKMGT] pform_set_default_nettype(NetNet::WIRE, yylloc.text, yylloc.first_line); in_celldefine = false; + uc_drive = UCD_NONE; pform_set_timescale(def_ts_units, def_ts_prec, 0, 0); - /* Add `nounconnected_drive when implemented. */ } } + /* Notice and handle the `unconnected_drive directive. */ +^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); } +.* { process_ucdrive(yytext); } +\n { + if (in_module) { + cerr << yylloc.text << ":" << yylloc.first_line << ": error: " + "`unconnected_drive directive can not be inside a " + "module definition." << endl; + error_count += 1; + } + yylloc.first_line += 1; + BEGIN(0); } + +^{W}?`nounconnected_drive{W}? { + if (in_module) { + cerr << yylloc.text << ":" << yylloc.first_line << ": error: " + "`nounconnected_drive directive can not be inside a " + "module definition." << endl; + error_count += 1; + } + uc_drive = UCD_NONE; } + /* These are directives that I do not yet support. I think that IVL should handle these, not an external preprocessor. */ /* From 1364-2005 Chapter 19. */ -^{W}?`nounconnected_drive{W}?.* { } ^{W}?`pragme{W}?.* { } -^{W}?`unconnected_drive{W}?.* { } /* From 1364-2005 Annex D. */ ^{W}?`default_decay_time{W}?.* { } @@ -481,16 +517,38 @@ S [afpnumkKMGT] NetNet::Type net_type; size_t wordlen = strcspn(yytext, " \t\f\r\n"); yytext[wordlen] = 0; + /* Add support for other wire types and better error detection. */ if (strcmp(yytext,"wire") == 0) { net_type = NetNet::WIRE; + } else if (strcmp(yytext,"tri") == 0) { + net_type = NetNet::TRI; + + } else if (strcmp(yytext,"tri0") == 0) { + net_type = NetNet::TRI0; + + } else if (strcmp(yytext,"tri1") == 0) { + net_type = NetNet::TRI1; + + } else if (strcmp(yytext,"wand") == 0) { + net_type = NetNet::WAND; + + } else if (strcmp(yytext,"triand") == 0) { + net_type = NetNet::TRIAND; + + } else if (strcmp(yytext,"wor") == 0) { + net_type = NetNet::WOR; + + } else if (strcmp(yytext,"trior") == 0) { + net_type = NetNet::TRIOR; + } else if (strcmp(yytext,"none") == 0) { net_type = NetNet::NONE; } else { cerr << yylloc.text << ":" << yylloc.first_line << ": error: Net type " << yytext - << " is not a valid (and supported)" + << " is not a valid (or supported)" << " default net type." << endl; net_type = NetNet::WIRE; error_count += 1; @@ -982,6 +1040,128 @@ static verinum*make_unsized_dec(const char*ptr) return res; } +/* + * Convert the string to a time unit or precision. + * Returns true on failure. + */ +static bool get_timescale_const(const char *&cp, int &res, bool is_unit) +{ + /* Check for the 1 digit. */ + if (*cp != '1') { + if (is_unit) { + VLerror(yylloc, "Invalid `timescale unit constant " + "(1st digit)"); + } else { + VLerror(yylloc, "Invalid `timescale precision constant " + "(1st digit)"); + } + return true; + } + cp += 1; + + /* Check the number of zeros after the 1. */ + res = strspn(cp, "0"); + if (res > 2) { + if (is_unit) { + VLerror(yylloc, "Invalid `timescale unit constant " + "(number of zeros)"); + } else { + VLerror(yylloc, "Invalid `timescale precision constant " + "(number of zeros)"); + } + return true; + } + cp += res; + + /* Skip any space between the digits and the scaling string. */ + cp += strspn(cp, " \t"); + + /* Now process the scaling string. */ + if (strncmp("s", cp, 1) == 0) { + res -= 0; + cp += 1; + return false; + + } else if (strncmp("ms", cp, 2) == 0) { + res -= 3; + cp += 2; + return false; + + } else if (strncmp("us", cp, 2) == 0) { + res -= 6; + cp += 2; + return false; + + } else if (strncmp("ns", cp, 2) == 0) { + res -= 9; + cp += 2; + return false; + + } else if (strncmp("ps", cp, 2) == 0) { + res -= 12; + cp += 2; + return false; + + } else if (strncmp("fs", cp, 2) == 0) { + res -= 15; + cp += 2; + return false; + + } + + if (is_unit) { + VLerror(yylloc, "Invalid `timescale unit scale"); + } else { + VLerror(yylloc, "Invalid `timescale precision scale"); + } + return true; +} + + +/* + * process either a pull0 or a pull1. + */ +static void process_ucdrive(const char*txt) +{ + UCDriveType ucd = UCD_NONE; + const char*cp = txt + strspn(txt, " \t"); + + /* Skip the space after the `unconnected_drive directive. */ + if (cp == txt) { + VLerror(yylloc, "Space required after `unconnected_drive " + "directive."); + return; + } + + /* Check for the pull keyword. */ + if (strncmp("pull", cp, 4) != 0) { + VLerror(yylloc, "pull required for `unconnected_drive " + "directive."); + return; + } + cp += 4; + if (*cp == '0') ucd = UCD_PULL0; + else if (*cp == '1') ucd = UCD_PULL1; + else { + cerr << yylloc.text << ":" << yylloc.first_line << ": error: " + "`unconnected_drive does not support 'pull" << *cp + << "'." << endl; + error_count += 1; + return; + } + cp += 1; + + /* Verify that only space and/or a single line comment is left. */ + cp += strspn(cp, " \t"); + if (strncmp(cp, "//", 2) != 0 && + (size_t)(cp-yytext) != strlen(yytext)) { + VLerror(yylloc, "Invalid `unconnected_dirve directive (extra " + "garbage after precision)."); + return; + } + + uc_drive = ucd; +} /* * The timescale parameter has the form: @@ -989,98 +1169,39 @@ static verinum*make_unsized_dec(const char*ptr) */ static void process_timescale(const char*txt) { - unsigned num; const char*cp = txt + strspn(txt, " \t"); - char*tmp; - const char*ctmp; + + /* Skip the space after the `timescale directive. */ + if (cp == txt) { + VLerror(yylloc, "Space required after `timescale directive."); + return; + } int unit = 0; int prec = 0; - num = strtoul(cp, &tmp, 10); - if (num == 0) { - VLerror(yylloc, "Invalid timescale string."); - return; - } + /* Get the time units. */ + if (get_timescale_const(cp, unit, true)) return; - while (num >= 10) { - unit += 1; - num /= 10; - } - if (num != 1) { - VLerror(yylloc, "Invalid timescale unit number."); - return; - } - - cp = tmp; + /* Skip any space after the time units, the '/' and any + * space after the '/'. */ cp += strspn(cp, " \t"); - ctmp = cp + strcspn(cp, " \t/"); - - if (strncmp("s", cp, ctmp-cp) == 0) { - unit -= 0; - - } else if (strncmp("ms", cp, ctmp-cp) == 0) { - unit -= 3; - - } else if (strncmp("us", cp, ctmp-cp) == 0) { - unit -= 6; - - } else if (strncmp("ns", cp, ctmp-cp) == 0) { - unit -= 9; - - } else if (strncmp("ps", cp, ctmp-cp) == 0) { - unit -= 12; - - } else if (strncmp("fs", cp, ctmp-cp) == 0) { - unit -= 15; - - } else { - VLerror(yylloc, "Invalid timescale unit of measurement"); + if (*cp != '/') { + VLerror(yylloc, "`timescale separator '/' appears to be missing."); return; } - - cp = ctmp; - cp += strspn(cp, " \t/"); - - num = strtoul(cp, &tmp, 10); - if (num == 0) { - VLerror(yylloc, "Invalid timescale string."); - return; - } - assert(num); - while (num >= 10) { - prec += 1; - num /= 10; - } - if (num != 1) { - VLerror(yylloc, "Invalid timescale precision number."); - return; - } - - cp = tmp; + cp += 1; cp += strspn(cp, " \t"); - ctmp = cp + strcspn(cp, " \t\r"); - if (strncmp("s", cp, ctmp-cp) == 0) { - prec -= 0; + /* Get the time precision. */ + if (get_timescale_const(cp, prec, false)) return; - } else if (strncmp("ms", cp, ctmp-cp) == 0) { - prec -= 3; - - } else if (strncmp("us", cp, ctmp-cp) == 0) { - prec -= 6; - - } else if (strncmp("ns", cp, ctmp-cp) == 0) { - prec -= 9; - - } else if (strncmp("ps", cp, ctmp-cp) == 0) { - prec -= 12; - - } else if (strncmp("fs", cp, ctmp-cp) == 0) { - prec -= 15; - - } else { - VLerror(yylloc, "Invalid timescale precision units of measurement"); + /* Verify that only space and/or a single line comment is left. */ + cp += strspn(cp, " \t"); + if (strncmp(cp, "//", 2) != 0 && + (size_t)(cp-yytext) != strlen(yytext)) { + VLerror(yylloc, "Invalid `timescale directive (extra garbage " + "after precision)."); return; } @@ -1101,7 +1222,7 @@ static void line_directive() { char *cpr; /* Skip any leading space. */ - char *cp = index(yytext, '#'); + char *cp = strchr(yytext, '#'); /* Skip the #line directive. */ assert(strncmp(cp, "#line", 5) == 0); cp += 5; @@ -1170,7 +1291,7 @@ static void line_directive2() { char *cpr; /* Skip any leading space. */ - char *cp = index(yytext, '`'); + char *cp = strchr(yytext, '`'); /* Skip the `line directive. */ assert(strncmp(cp, "`line", 5) == 0); cp += 5; @@ -1209,8 +1330,7 @@ static void line_directive2() } /* Skip the space after the file name. */ - cp = fn_end; - cp += 1; + cp = fn_end + 1; cpr = cp; cpr += strspn(cp, " \t"); if (cp == cpr) { @@ -1221,16 +1341,16 @@ static void line_directive2() cp = cpr; /* Check that the level is correct, we do not need the level. */ - strtoul(cp, &cpr, 10); - if (cp == cpr) { + if (strspn(cp, "012") != 1) { VLerror(yylloc, "Invalid level for `line directive."); return; } - cp = cpr; + cp += 1; - /* Verify that only space is left. */ - cpr += strspn(cp, " \t"); - if ((size_t)(cpr-yytext) != strlen(yytext)) { + /* Verify that only space and/or a single line comment is left. */ + cp += strspn(cp, " \t"); + if (strncmp(cp, "//", 2) != 0 && + (size_t)(cp-yytext) != strlen(yytext)) { VLerror(yylloc, "Invalid `line directive (extra garbage after " "level)."); return; diff --git a/lexor_keyword.gperf b/lexor_keyword.gperf index c58be638f..5ba577a71 100644 --- a/lexor_keyword.gperf +++ b/lexor_keyword.gperf @@ -11,165 +11,183 @@ %} struct lexor_keyword { const char*name; int mask; int tokenType; }; %% -abs, GN_KEYWORDS_VAMS_2_3, K_abs -abstol, GN_KEYWORDS_VAMS_2_3, K_abstol -access, GN_KEYWORDS_VAMS_2_3, K_access -acos, GN_KEYWORDS_VAMS_2_3, K_acos -acosh, GN_KEYWORDS_VAMS_2_3, K_acosh -always, GN_KEYWORDS_1364_1995, K_always -always_comb, GN_KEYWORDS_1800_2005, K_always_comb -always_ff, GN_KEYWORDS_1800_2005, K_always_ff -always_latch, GN_KEYWORDS_1800_2005, K_always_latch -analog, GN_KEYWORDS_VAMS_2_3, K_analog -and, GN_KEYWORDS_1364_1995, K_and -asin, GN_KEYWORDS_VAMS_2_3, K_asin -asinh, GN_KEYWORDS_VAMS_2_3, K_asinh -assert, GN_KEYWORDS_1800_2005, K_assert -assign, GN_KEYWORDS_1364_1995, K_assign -atan, GN_KEYWORDS_VAMS_2_3, K_atan -atan2, GN_KEYWORDS_VAMS_2_3, K_atan2 -atanh, GN_KEYWORDS_VAMS_2_3, K_atanh -automatic, GN_KEYWORDS_1364_2001, K_automatic -begin, GN_KEYWORDS_1364_1995, K_begin -bool, GN_KEYWORDS_ICARUS, K_bool -buf, GN_KEYWORDS_1364_1995, K_buf -bufif0, GN_KEYWORDS_1364_1995, K_bufif0 -bufif1, GN_KEYWORDS_1364_1995, K_bufif1 -case, GN_KEYWORDS_1364_1995, K_case -casex, GN_KEYWORDS_1364_1995, K_casex -casez, GN_KEYWORDS_1364_1995, K_casez -ceil, GN_KEYWORDS_VAMS_2_3, K_ceil -cmos, GN_KEYWORDS_1364_1995, K_cmos -continuous, GN_KEYWORDS_VAMS_2_3, K_continuous -cos, GN_KEYWORDS_VAMS_2_3, K_cos -cosh, GN_KEYWORDS_VAMS_2_3, K_cosh -ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature -deassign, GN_KEYWORDS_1364_1995, K_deassign -default, GN_KEYWORDS_1364_1995, K_default -defparam, GN_KEYWORDS_1364_1995, K_defparam -disable, GN_KEYWORDS_1364_1995, K_disable -discipline, GN_KEYWORDS_VAMS_2_3, K_discipline -discrete, GN_KEYWORDS_VAMS_2_3, K_discrete -domain, GN_KEYWORDS_VAMS_2_3, K_domain -edge, GN_KEYWORDS_1364_1995, K_edge -else, GN_KEYWORDS_1364_1995, K_else -end, GN_KEYWORDS_1364_1995, K_end -endcase, GN_KEYWORDS_1364_1995, K_endcase -enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline -endfunction, GN_KEYWORDS_1364_1995, K_endfunction -endgenerate, GN_KEYWORDS_1364_1995, K_endgenerate -endmodule, GN_KEYWORDS_1364_1995, K_endmodule -endnature, GN_KEYWORDS_VAMS_2_3, K_endnature -endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive -endspecify, GN_KEYWORDS_1364_1995, K_endspecify -endtable, GN_KEYWORDS_1364_1995, K_endtable -endtask, GN_KEYWORDS_1364_1995, K_endtask -event, GN_KEYWORDS_1364_1995, K_event -exclude, GN_KEYWORDS_VAMS_2_3, K_exclude -exp, GN_KEYWORDS_VAMS_2_3, K_exp -floor, GN_KEYWORDS_VAMS_2_3, K_floor -flow, GN_KEYWORDS_VAMS_2_3, K_flow -for, GN_KEYWORDS_1364_1995, K_for -force, GN_KEYWORDS_1364_1995, K_force -forever, GN_KEYWORDS_1364_1995, K_forever -fork, GN_KEYWORDS_1364_1995, K_fork -from, GN_KEYWORDS_VAMS_2_3, K_from -function, GN_KEYWORDS_1364_1995, K_function -generate, GN_KEYWORDS_1364_2001, K_generate -genvar, GN_KEYWORDS_1364_2001, K_genvar -ground, GN_KEYWORDS_VAMS_2_3, K_ground -highz0, GN_KEYWORDS_1364_1995, K_highz0 -highz1, GN_KEYWORDS_1364_1995, K_highz1 -hypot, GN_KEYWORDS_VAMS_2_3, K_hypot -idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature -if, GN_KEYWORDS_1364_1995, K_if -ifnone, GN_KEYWORDS_1364_1995, K_ifnone -inf, GN_KEYWORDS_VAMS_2_3, K_inf -initial, GN_KEYWORDS_1364_1995, K_initial -inout, GN_KEYWORDS_1364_1995, K_inout -input, GN_KEYWORDS_1364_1995, K_input -integer, GN_KEYWORDS_1364_1995, K_integer -join, GN_KEYWORDS_1364_1995, K_join -large, GN_KEYWORDS_1364_1995, K_large -ln, GN_KEYWORDS_VAMS_2_3, K_ln -localparam, GN_KEYWORDS_1364_2001, K_localparam -log, GN_KEYWORDS_VAMS_2_3, K_log -logic, GN_KEYWORDS_ICARUS, K_logic -macromodule, GN_KEYWORDS_1364_1995, K_macromodule -max, GN_KEYWORDS_VAMS_2_3, K_max -medium, GN_KEYWORDS_1364_1995, K_medium -min, GN_KEYWORDS_VAMS_2_3, K_min -module, GN_KEYWORDS_1364_1995, K_module -nand, GN_KEYWORDS_1364_1995, K_nand -nature, GN_KEYWORDS_VAMS_2_3, K_nature -negedge, GN_KEYWORDS_1364_1995, K_negedge -nmos, GN_KEYWORDS_1364_1995, K_nmos -nor, GN_KEYWORDS_1364_1995, K_nor -not, GN_KEYWORDS_1364_1995, K_not -notif0, GN_KEYWORDS_1364_1995, K_notif0 -notif1, GN_KEYWORDS_1364_1995, K_notif1 -or, GN_KEYWORDS_1364_1995, K_or -output, GN_KEYWORDS_1364_1995, K_output -parameter, GN_KEYWORDS_1364_1995, K_parameter -pmos, GN_KEYWORDS_1364_1995, K_pmos -posedge, GN_KEYWORDS_1364_1995, K_posedge -potential, GN_KEYWORDS_VAMS_2_3, K_potential -pow, GN_KEYWORDS_VAMS_2_3, K_pow -primitive, GN_KEYWORDS_1364_1995, K_primitive -pull0, GN_KEYWORDS_1364_1995, K_pull0 -pull1, GN_KEYWORDS_1364_1995, K_pull1 -pulldown, GN_KEYWORDS_1364_1995, K_pulldown -pullup, GN_KEYWORDS_1364_1995, K_pullup -rcmos, GN_KEYWORDS_1364_1995, K_rcmos -real, GN_KEYWORDS_1364_1995, K_real -realtime, GN_KEYWORDS_1364_1995, K_realtime -reg, GN_KEYWORDS_1364_1995, K_reg -release, GN_KEYWORDS_1364_1995, K_release -repeat, GN_KEYWORDS_1364_1995, K_repeat -rnmos, GN_KEYWORDS_1364_1995, K_rnmos -rpmos, GN_KEYWORDS_1364_1995, K_rpmos -rtran, GN_KEYWORDS_1364_1995, K_rtran -rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0 -rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1 -scalared, GN_KEYWORDS_1364_1995, K_scalared -signed, GN_KEYWORDS_1364_2001, K_signed -sin, GN_KEYWORDS_VAMS_2_3, K_sin -sinh, GN_KEYWORDS_VAMS_2_3, K_sinh -small, GN_KEYWORDS_1364_1995, K_small -specify, GN_KEYWORDS_1364_1995, K_specify -specparam, GN_KEYWORDS_1364_1995, K_specparam -sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt -string, GN_KEYWORDS_VAMS_2_3, K_string -strong0, GN_KEYWORDS_1364_1995, K_strong0 -strong1, GN_KEYWORDS_1364_1995, K_strong1 -supply0, GN_KEYWORDS_1364_1995, K_supply0 -supply1, GN_KEYWORDS_1364_1995, K_supply1 -table, GN_KEYWORDS_1364_1995, K_table -tan, GN_KEYWORDS_VAMS_2_3, K_tan -tanh, GN_KEYWORDS_VAMS_2_3, K_tanh -task, GN_KEYWORDS_1364_1995, K_task -time, GN_KEYWORDS_1364_1995, K_time -tran, GN_KEYWORDS_1364_1995, K_tran -tranif0, GN_KEYWORDS_1364_1995, K_tranif0 -tranif1, GN_KEYWORDS_1364_1995, K_tranif1 -tri, GN_KEYWORDS_1364_1995, K_tri -tri0, GN_KEYWORDS_1364_1995, K_tri0 -tri1, GN_KEYWORDS_1364_1995, K_tri1 -triand, GN_KEYWORDS_1364_1995, K_triand -trior, GN_KEYWORDS_1364_1995, K_trior -trireg, GN_KEYWORDS_1364_1995, K_trireg -units, GN_KEYWORDS_VAMS_2_3, K_units -vectored, GN_KEYWORDS_1364_1995, K_vectored -wait, GN_KEYWORDS_1364_1995, K_wait -wand, GN_KEYWORDS_1364_1995, K_wand -weak0, GN_KEYWORDS_1364_1995, K_weak0 -weak1, GN_KEYWORDS_1364_1995, K_weak1 -while, GN_KEYWORDS_1364_1995, K_while -wire, GN_KEYWORDS_1364_1995, K_wire -wone, GN_KEYWORDS_1364_1995, K_wone -wor, GN_KEYWORDS_1364_1995, K_wor -xnor, GN_KEYWORDS_1364_1995, K_xnor -xor, GN_KEYWORDS_1364_1995, K_xor +abs, GN_KEYWORDS_VAMS_2_3, K_abs +abstol, GN_KEYWORDS_VAMS_2_3, K_abstol +access, GN_KEYWORDS_VAMS_2_3, K_access +acos, GN_KEYWORDS_VAMS_2_3, K_acos +acosh, GN_KEYWORDS_VAMS_2_3, K_acosh +always, GN_KEYWORDS_1364_1995, K_always +always_comb, GN_KEYWORDS_1800_2005, K_always_comb +always_ff, GN_KEYWORDS_1800_2005, K_always_ff +always_latch, GN_KEYWORDS_1800_2005, K_always_latch +analog, GN_KEYWORDS_VAMS_2_3, K_analog +and, GN_KEYWORDS_1364_1995, K_and +asin, GN_KEYWORDS_VAMS_2_3, K_asin +asinh, GN_KEYWORDS_VAMS_2_3, K_asinh +assert, GN_KEYWORDS_1800_2005, K_assert +assign, GN_KEYWORDS_1364_1995, K_assign +atan, GN_KEYWORDS_VAMS_2_3, K_atan +atan2, GN_KEYWORDS_VAMS_2_3, K_atan2 +atanh, GN_KEYWORDS_VAMS_2_3, K_atanh +automatic, GN_KEYWORDS_1364_2001, K_automatic +begin, GN_KEYWORDS_1364_1995, K_begin +bool, GN_KEYWORDS_ICARUS, K_bool +buf, GN_KEYWORDS_1364_1995, K_buf +bufif0, GN_KEYWORDS_1364_1995, K_bufif0 +bufif1, GN_KEYWORDS_1364_1995, K_bufif1 +case, GN_KEYWORDS_1364_1995, K_case +casex, GN_KEYWORDS_1364_1995, K_casex +casez, GN_KEYWORDS_1364_1995, K_casez +ceil, GN_KEYWORDS_VAMS_2_3, K_ceil +cell, GN_KEYWORDS_1364_2001_CONFIG, K_cell +cmos, GN_KEYWORDS_1364_1995, K_cmos +config, GN_KEYWORDS_1364_2001_CONFIG, K_config +continuous, GN_KEYWORDS_VAMS_2_3, K_continuous +cos, GN_KEYWORDS_VAMS_2_3, K_cos +cosh, GN_KEYWORDS_VAMS_2_3, K_cosh +ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature +deassign, GN_KEYWORDS_1364_1995, K_deassign +default, GN_KEYWORDS_1364_1995, K_default +defparam, GN_KEYWORDS_1364_1995, K_defparam +design, GN_KEYWORDS_1364_2001_CONFIG, K_design +disable, GN_KEYWORDS_1364_1995, K_disable +discipline, GN_KEYWORDS_VAMS_2_3, K_discipline +discrete, GN_KEYWORDS_VAMS_2_3, K_discrete +domain, GN_KEYWORDS_VAMS_2_3, K_domain +edge, GN_KEYWORDS_1364_1995, K_edge +else, GN_KEYWORDS_1364_1995, K_else +end, GN_KEYWORDS_1364_1995, K_end +endcase, GN_KEYWORDS_1364_1995, K_endcase +endconfig, GN_KEYWORDS_1364_2001_CONFIG, K_endconfig +enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline +endfunction, GN_KEYWORDS_1364_1995, K_endfunction +endgenerate, GN_KEYWORDS_1364_2001, K_endgenerate +endmodule, GN_KEYWORDS_1364_1995, K_endmodule +endnature, GN_KEYWORDS_VAMS_2_3, K_endnature +endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive +endspecify, GN_KEYWORDS_1364_1995, K_endspecify +endtable, GN_KEYWORDS_1364_1995, K_endtable +endtask, GN_KEYWORDS_1364_1995, K_endtask +event, GN_KEYWORDS_1364_1995, K_event +exclude, GN_KEYWORDS_VAMS_2_3, K_exclude +exp, GN_KEYWORDS_VAMS_2_3, K_exp +floor, GN_KEYWORDS_VAMS_2_3, K_floor +flow, GN_KEYWORDS_VAMS_2_3, K_flow +for, GN_KEYWORDS_1364_1995, K_for +force, GN_KEYWORDS_1364_1995, K_force +forever, GN_KEYWORDS_1364_1995, K_forever +fork, GN_KEYWORDS_1364_1995, K_fork +from, GN_KEYWORDS_VAMS_2_3, K_from +function, GN_KEYWORDS_1364_1995, K_function +generate, GN_KEYWORDS_1364_2001, K_generate +genvar, GN_KEYWORDS_1364_2001, K_genvar +ground, GN_KEYWORDS_VAMS_2_3, K_ground +highz0, GN_KEYWORDS_1364_1995, K_highz0 +highz1, GN_KEYWORDS_1364_1995, K_highz1 +hypot, GN_KEYWORDS_VAMS_2_3, K_hypot +idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature +if, GN_KEYWORDS_1364_1995, K_if +ifnone, GN_KEYWORDS_1364_1995, K_ifnone +incdir, GN_KEYWORDS_1364_2001_CONFIG, K_incdir +include, GN_KEYWORDS_1364_2001_CONFIG, K_include +inf, GN_KEYWORDS_VAMS_2_3, K_inf +initial, GN_KEYWORDS_1364_1995, K_initial +inout, GN_KEYWORDS_1364_1995, K_inout +input, GN_KEYWORDS_1364_1995, K_input +instance, GN_KEYWORDS_1364_2001_CONFIG, K_instance +integer, GN_KEYWORDS_1364_1995, K_integer +join, GN_KEYWORDS_1364_1995, K_join +large, GN_KEYWORDS_1364_1995, K_large +liblist, GN_KEYWORDS_1364_2001_CONFIG, K_liblist +library, GN_KEYWORDS_1364_2001_CONFIG, K_library +ln, GN_KEYWORDS_VAMS_2_3, K_ln +localparam, GN_KEYWORDS_1364_2001, K_localparam +log, GN_KEYWORDS_VAMS_2_3, K_log +logic, GN_KEYWORDS_ICARUS, K_logic +macromodule, GN_KEYWORDS_1364_1995, K_macromodule +max, GN_KEYWORDS_VAMS_2_3, K_max +medium, GN_KEYWORDS_1364_1995, K_medium +min, GN_KEYWORDS_VAMS_2_3, K_min +module, GN_KEYWORDS_1364_1995, K_module +nand, GN_KEYWORDS_1364_1995, K_nand +nature, GN_KEYWORDS_VAMS_2_3, K_nature +negedge, GN_KEYWORDS_1364_1995, K_negedge +nmos, GN_KEYWORDS_1364_1995, K_nmos +nor, GN_KEYWORDS_1364_1995, K_nor +noshowcancelled, GN_KEYWORDS_1364_2001, K_noshowcancelled +not, GN_KEYWORDS_1364_1995, K_not +notif0, GN_KEYWORDS_1364_1995, K_notif0 +notif1, GN_KEYWORDS_1364_1995, K_notif1 +or, GN_KEYWORDS_1364_1995, K_or +output, GN_KEYWORDS_1364_1995, K_output +parameter, GN_KEYWORDS_1364_1995, K_parameter +pmos, GN_KEYWORDS_1364_1995, K_pmos +posedge, GN_KEYWORDS_1364_1995, K_posedge +potential, GN_KEYWORDS_VAMS_2_3, K_potential +pow, GN_KEYWORDS_VAMS_2_3, K_pow +primitive, GN_KEYWORDS_1364_1995, K_primitive +pull0, GN_KEYWORDS_1364_1995, K_pull0 +pull1, GN_KEYWORDS_1364_1995, K_pull1 +pulldown, GN_KEYWORDS_1364_1995, K_pulldown +pullup, GN_KEYWORDS_1364_1995, K_pullup +pulsestyle_onevent, GN_KEYWORDS_1364_2001, K_pulsestyle_onevent +pulsestyle_ondetect, GN_KEYWORDS_1364_2001, K_pulsestyle_ondetect +rcmos, GN_KEYWORDS_1364_1995, K_rcmos +real, GN_KEYWORDS_1364_1995, K_real +realtime, GN_KEYWORDS_1364_1995, K_realtime +reg, GN_KEYWORDS_1364_1995, K_reg +release, GN_KEYWORDS_1364_1995, K_release +repeat, GN_KEYWORDS_1364_1995, K_repeat +rnmos, GN_KEYWORDS_1364_1995, K_rnmos +rpmos, GN_KEYWORDS_1364_1995, K_rpmos +rtran, GN_KEYWORDS_1364_1995, K_rtran +rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0 +rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1 +scalared, GN_KEYWORDS_1364_1995, K_scalared +showcancelled, GN_KEYWORDS_1364_2001, K_showcancelled +signed, GN_KEYWORDS_1364_2001, K_signed +sin, GN_KEYWORDS_VAMS_2_3, K_sin +sinh, GN_KEYWORDS_VAMS_2_3, K_sinh +small, GN_KEYWORDS_1364_1995, K_small +specify, GN_KEYWORDS_1364_1995, K_specify +specparam, GN_KEYWORDS_1364_1995, K_specparam +sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt +string, GN_KEYWORDS_VAMS_2_3, K_string +strong0, GN_KEYWORDS_1364_1995, K_strong0 +strong1, GN_KEYWORDS_1364_1995, K_strong1 +supply0, GN_KEYWORDS_1364_1995, K_supply0 +supply1, GN_KEYWORDS_1364_1995, K_supply1 +table, GN_KEYWORDS_1364_1995, K_table +tan, GN_KEYWORDS_VAMS_2_3, K_tan +tanh, GN_KEYWORDS_VAMS_2_3, K_tanh +task, GN_KEYWORDS_1364_1995, K_task +time, GN_KEYWORDS_1364_1995, K_time +tran, GN_KEYWORDS_1364_1995, K_tran +tranif0, GN_KEYWORDS_1364_1995, K_tranif0 +tranif1, GN_KEYWORDS_1364_1995, K_tranif1 +tri, GN_KEYWORDS_1364_1995, K_tri +tri0, GN_KEYWORDS_1364_1995, K_tri0 +tri1, GN_KEYWORDS_1364_1995, K_tri1 +triand, GN_KEYWORDS_1364_1995, K_triand +trior, GN_KEYWORDS_1364_1995, K_trior +trireg, GN_KEYWORDS_1364_1995, K_trireg +units, GN_KEYWORDS_VAMS_2_3, K_units +# Reserved for future use! +unsigned, GN_KEYWORDS_1364_2001, K_unsigned +use, GN_KEYWORDS_1364_2001_CONFIG, K_use +uwire, GN_KEYWORDS_1364_2005, K_uwire +vectored, GN_KEYWORDS_1364_1995, K_vectored +wait, GN_KEYWORDS_1364_1995, K_wait +wand, GN_KEYWORDS_1364_1995, K_wand +weak0, GN_KEYWORDS_1364_1995, K_weak0 +weak1, GN_KEYWORDS_1364_1995, K_weak1 +while, GN_KEYWORDS_1364_1995, K_while +wire, GN_KEYWORDS_1364_1995, K_wire +# This is the name originally proposed for uwire and is deprecated! +wone, GN_KEYWORDS_1364_2005, K_wone +wor, GN_KEYWORDS_1364_1995, K_wor +xnor, GN_KEYWORDS_1364_1995, K_xnor +xor, GN_KEYWORDS_1364_1995, K_xor %% int lexor_keyword_mask = 0; diff --git a/main.cc b/main.cc index b3f1201c0..ad4de617a 100644 --- a/main.cc +++ b/main.cc @@ -224,6 +224,9 @@ static void process_generation_flag(const char*gen) } else if (strcmp(gen,"2001") == 0) { generation_flag = GN_VER2001; + } else if (strcmp(gen,"2001-noconfig") == 0) { + generation_flag = GN_VER2001_NOCONFIG; + } else if (strcmp(gen,"2005") == 0) { generation_flag = GN_VER2005; @@ -660,9 +663,10 @@ int main(int argc, char*argv[]) lexor_keyword_mask |= GN_KEYWORDS_1364_1995; break; case GN_VER2001: + lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG; + case GN_VER2001_NOCONFIG: lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_2001; - lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG; break; case GN_VER2005: lexor_keyword_mask |= GN_KEYWORDS_1364_1995; @@ -690,6 +694,9 @@ int main(int argc, char*argv[]) case GN_VER1995: cout << "IEEE1364-1995"; break; + case GN_VER2001_NOCONFIG: + cout << "IEEE1364-2001-noconfig"; + break; case GN_VER2001: cout << "IEEE1364-2001"; break; diff --git a/netlist.cc b/netlist.cc index 4a69c5e80..8f2940316 100644 --- a/netlist.cc +++ b/netlist.cc @@ -78,8 +78,8 @@ ostream& operator<< (ostream&o, NetNet::Type t) case NetNet::WIRE: o << "wire"; break; - case NetNet::WONE: - o << "wone"; + case NetNet::UWIRE: + o << "uwire"; } return o; } diff --git a/netlist.h b/netlist.h index 387adffc8..05c57ebfd 100644 --- a/netlist.h +++ b/netlist.h @@ -542,7 +542,7 @@ class NetNet : public NetObj { public: enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1, SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG, - WONE }; + UWIRE }; enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT }; diff --git a/parse.y b/parse.y index e24d67bbc..d25591943 100644 --- a/parse.y +++ b/parse.y @@ -229,40 +229,56 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %token K_PO_POS K_PO_NEG K_POW %token K_PSTAR K_STARP %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER -%token K_abs K_abstol K_access K_acos K_acosh K_asin K_analog K_asinh -%token K_atan K_atanh K_atan2 K_automatic -%token K_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case -%token K_casex K_casez K_ceil K_cmos K_continuous K_cos K_cosh -%token K_ddt_nature K_deassign K_default K_defparam K_disable K_discrete -%token K_domain K_edge K_edge_descriptor K_discipline -%token K_else K_end K_endcase K_enddiscipline K_endfunction K_endgenerate -%token K_endmodule K_endnature -%token K_endprimitive K_endspecify K_endtable K_endtask K_event -%token K_exclude K_exp K_floor K_flow K_from -%token K_for K_force K_forever K_fork K_function K_generate K_genvar -%token K_ground K_highz0 K_highz1 K_hypot K_idt_nature K_if K_ifnone K_inf -%token K_initial K_inout K_input K_integer K_join K_large K_ln K_localparam -%token K_log K_logic K_macromodule K_max -%token K_medium K_min K_module K_nand K_nature K_negedge -%token K_nmos K_nor K_not K_notif0 -%token K_notif1 K_or K_output K_parameter K_pmos K_posedge K_potential -%token K_pow K_primitive -%token K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real K_realtime -%token K_reg K_release K_repeat -%token K_rnmos K_rpmos K_rtran K_rtranif0 K_rtranif1 K_scalared -%token K_signed K_sin K_sinh K_small K_specify -%token K_specparam K_sqrt K_string K_strong0 K_strong1 K_supply0 K_supply1 -%token K_table -%token K_tan K_tanh K_task -%token K_time K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand -%token K_trior K_trireg K_units K_vectored K_wait K_wand K_weak0 K_weak1 -%token K_while K_wire -%token K_wone K_wor K_xnor K_xor -%token K_Shold K_Speriod K_Srecovery K_Srecrem K_Ssetup K_Swidth K_Ssetuphold +%token K_edge_descriptor + /* The base tokens from 1364-1995. */ +%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case +%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable +%token K_edge K_else K_end K_endcase K_endfunction K_endmodule +%token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for +%token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if +%token K_ifnone K_initial K_inout K_input K_integer K_join K_large +%token K_macromodule K_medium K_module K_nand K_negedge K_nmos K_nor +%token K_not K_notif0 K_notif1 K_or K_output K_parameter K_pmos K_posedge +%token K_primitive K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real +%token K_realtime K_reg K_release K_repeat K_rnmos K_rpmos K_rtran +%token K_rtranif0 K_rtranif1 K_scalared K_small K_specify K_specparam +%token K_strong0 K_strong1 K_supply0 K_supply1 K_table K_task K_time +%token K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand K_trior +%token K_trireg K_vectored K_wait K_wand K_weak0 K_weak1 K_while K_wire +%token K_wor K_xnor K_xor + +%token K_Shold K_Snochange K_Speriod K_Srecovery K_Ssetup K_Ssetuphold +%token K_Sskew K_Swidth + + /* Icarus specific tokens. */ +%token KK_attribute K_bool K_logic + + /* The new tokens from 1364-2001. */ +%token K_automatic K_endgenerate K_generate K_genvar K_localparam +%token K_noshowcancelled K_pulsestyle_onevent K_pulsestyle_ondetect +%token K_showcancelled K_signed K_unsigned + +%token K_Sfullskew K_Srecrem K_Sremoval K_Stimeskew + + /* The 1364-2001 configuration tokens. */ +%token K_cell K_config K_design K_endconfig K_incdir K_include K_instance +%token K_liblist K_library K_use + + /* The new tokens from 1364-2005. */ +%token K_wone K_uwire + + /* The new tokens from 1800-2005. */ %token K_always_comb K_always_ff K_always_latch K_assert -%token KK_attribute + /* The new tokens for Verilog-AMS 2.3. */ +%token K_abs K_abstol K_access K_acos K_acosh K_analog K_asin K_asinh +%token K_atan K_atan2 K_atanh K_ceil K_continuous K_cos K_cosh +%token K_ddt_nature K_discipline K_discrete K_domain K_enddiscipline +%token K_endnature K_exclude K_exp K_floor K_flow K_from K_ground +%token K_hypot K_idt_nature K_inf K_ln K_log K_max K_min K_nature +%token K_potential K_pow K_sin K_sinh K_sqrt K_string K_tan K_tanh +%token K_units %type from_exclude %type number @@ -1923,7 +1939,20 @@ module : attribute_list_opt module_start IDENTIFIER { pform_module_set_ports($6); } module_item_list_opt K_endmodule - { pform_endmodule($3, in_celldefine); + { Module::UCDriveType ucd; + switch (uc_drive) { + case UCD_NONE: + default: + ucd = Module::UCD_NONE; + break; + case UCD_PULL0: + ucd = Module::UCD_PULL0; + break; + case UCD_PULL1: + ucd = Module::UCD_PULL1; + break; + } + pform_endmodule($3, in_celldefine, ucd); delete[]$3; } @@ -2481,7 +2510,12 @@ net_type | K_supply1 { $$ = NetNet::SUPPLY1; } | K_wor { $$ = NetNet::WOR; } | K_trior { $$ = NetNet::TRIOR; } - | K_wone { $$ = NetNet::WONE; } + | K_wone { $$ = NetNet::UWIRE; + cerr << @1.text << ":" << @1.first_line << ": warning: " + "'wone' is deprecated, please use 'uwire' " + "instead." << endl; + } + | K_uwire { $$ = NetNet::UWIRE; } ; var_type @@ -3166,10 +3200,20 @@ specify_item } pform_module_specify_path(tmp); } + | K_Sfullskew '(' spec_reference_event ',' spec_reference_event + ',' delay_value ',' delay_value spec_notifier_opt ')' ';' + { delete $7; + delete $9; + } | K_Shold '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } + | K_Snochange '(' spec_reference_event ',' spec_reference_event + ',' delay_value ',' delay_value spec_notifier_opt ')' ';' + { delete $7; + delete $9; + } | K_Speriod '(' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $5; @@ -3178,6 +3222,15 @@ specify_item ',' delay_value spec_notifier_opt ')' ';' { delete $7; } + | K_Srecrem '(' spec_reference_event ',' spec_reference_event + ',' delay_value ',' delay_value spec_notifier_opt ')' ';' + { delete $7; + delete $9; + } + | K_Sremoval '(' spec_reference_event ',' spec_reference_event + ',' delay_value spec_notifier_opt ')' ';' + { delete $7; + } | K_Ssetup '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; @@ -3187,10 +3240,13 @@ specify_item { delete $7; delete $9; } - | K_Srecrem '(' spec_reference_event ',' spec_reference_event - ',' delay_value ',' delay_value spec_notifier_opt ')' ';' + | K_Sskew '(' spec_reference_event ',' spec_reference_event + ',' delay_value spec_notifier_opt ')' ';' + { delete $7; + } + | K_Stimeskew '(' spec_reference_event ',' spec_reference_event + ',' delay_value spec_notifier_opt ')' ';' { delete $7; - delete $9; } | K_Swidth '(' spec_reference_event ',' delay_value ',' expression spec_notifier_opt ')' ';' @@ -3200,6 +3256,18 @@ specify_item | K_Swidth '(' spec_reference_event ',' delay_value ')' ';' { delete $5; } + | K_pulsestyle_onevent specify_path_identifiers ';' + { delete $2; + } + | K_pulsestyle_ondetect specify_path_identifiers ';' + { delete $2; + } + | K_showcancelled specify_path_identifiers ';' + { delete $2; + } + | K_noshowcancelled specify_path_identifiers ';' + { delete $2; + } ; specify_item_list diff --git a/parse_misc.h b/parse_misc.h index 6aa623a13..0a33c6999 100644 --- a/parse_misc.h +++ b/parse_misc.h @@ -66,5 +66,7 @@ extern unsigned error_count, warn_count; extern unsigned long based_size; extern bool in_celldefine; +enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 }; +extern UCDriveType uc_drive; #endif diff --git a/pform.cc b/pform.cc index 52dfed03c..69ca9de36 100644 --- a/pform.cc +++ b/pform.cc @@ -467,12 +467,14 @@ void pform_module_set_ports(vector*ports) } } -void pform_endmodule(const char*name, bool in_celldefine) +void pform_endmodule(const char*name, bool in_celldefine, + Module::UCDriveType uc_drive) { assert(pform_cur_module); perm_string mod_name = pform_cur_module->mod_name(); assert(strcmp(name, mod_name) == 0); pform_cur_module->is_cell = in_celldefine; + pform_cur_module->uc_drive = uc_drive; map::const_iterator test = pform_modules.find(mod_name); diff --git a/pform.h b/pform.h index 92166d41b..53e56f38e 100644 --- a/pform.h +++ b/pform.h @@ -159,7 +159,8 @@ extern void pform_module_define_port(const struct vlltype&li, extern Module::port_t* pform_module_port_reference(perm_string name, const char*file, unsigned lineno); -extern void pform_endmodule(const char*, bool in_celldefine); +extern void pform_endmodule(const char*, bool in_celldefine, + Module::UCDriveType uc_drive); extern void pform_make_udp(perm_string name, list*parms, svector*decl, list*table, diff --git a/t-dll.cc b/t-dll.cc index f1b18f857..1e9a28602 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -2511,6 +2511,10 @@ void dll_target::signal(const NetNet*net) assert(0); break; + case NetNet::UWIRE: + cerr << net->get_fileline() + << ": warning: uwire is not currently supported, converting " + "it to a wire!" << endl; case NetNet::TRI: case NetNet::WIRE: case NetNet::IMPLICIT: diff --git a/vvp/main.cc b/vvp/main.cc index f255d59b3..539e277d3 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -194,7 +194,7 @@ void verify_version(char*ivl_ver, char*commit) unsigned module_cnt = 0; const char*module_tab[64]; -extern void vpi_mcd_init(FILE *log); +extern void vpip_mcd_init(FILE *log); extern void vvp_vpi_init(void); int main(int argc, char*argv[]) @@ -326,7 +326,7 @@ int main(int argc, char*argv[]) } } - vpi_mcd_init(logfile); + vpip_mcd_init(logfile); if (verbose_flag) { my_getrusage(cycles+0); diff --git a/vvp/parse.y b/vvp/parse.y index 03cf2dccf..47e0d5e5b 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -580,6 +580,12 @@ statement T_NUMBER T_NUMBER T_NUMBER ',' T_SYMBOL ';' { compile_scope_decl($1, $3, $5, $6, $14, $7, $8, $10, $11, $12); } + /* Legacy declaration that does not have `celldefine information. */ + + | T_LABEL K_SCOPE T_SYMBOL ',' T_STRING T_STRING T_NUMBER T_NUMBER ',' + T_NUMBER T_NUMBER ',' T_SYMBOL ';' + { compile_scope_decl($1, $3, $5, $6, $13, $7, $8, $10, $11, 0); } + /* XXXX Legacy declaration has no type name. */ | T_LABEL K_SCOPE T_SYMBOL ',' T_STRING ';' diff --git a/vvp/vpi_mcd.cc b/vvp/vpi_mcd.cc index 57cc55557..9a0a71139 100644 --- a/vvp/vpi_mcd.cc +++ b/vvp/vpi_mcd.cc @@ -42,53 +42,65 @@ extern FILE* vpi_trace; */ #define IS_MCD(mcd) !((mcd)>>31&1) #define FD_IDX(fd) ((fd)&~(1U<<31)) -#define FD_MAX 32 +#define FD_INCR 32 -struct mcd_entry { +typedef struct mcd_entry { FILE *fp; char *filename; -}; -static struct mcd_entry mcd_table[31]; -static struct mcd_entry fd_table[FD_MAX]; +} mcd_entry_s; +static mcd_entry_s mcd_table[31]; +static mcd_entry_s *fd_table = NULL; +static unsigned fd_table_len = 0; static FILE* logfile; /* Initialize mcd portion of vpi. Must be called before * any vpi_mcd routines can be used. */ -void vpi_mcd_init(FILE *log) +void vpip_mcd_init(FILE *log) { - mcd_table[0].fp = stdout; - mcd_table[0].filename = strdup("stdout"); + fd_table_len = FD_INCR; + fd_table = (mcd_entry_s *) malloc(fd_table_len*sizeof(mcd_entry_s)); + for (unsigned idx = 0; idx < fd_table_len; idx += 1) { + fd_table[idx].fp = NULL; + fd_table[idx].filename = NULL; + } + + mcd_table[0].fp = stdout; + mcd_table[0].filename = strdup("stdout"); - fd_table[0].fp = stdin; - fd_table[0].filename = strdup("stdin"); - fd_table[1].fp = stdout; - fd_table[1].filename = strdup("stdout"); - fd_table[2].fp = stderr; - fd_table[2].filename = strdup("stderr"); + fd_table[0].fp = stdin; + fd_table[0].filename = strdup("stdin"); + fd_table[1].fp = stdout; + fd_table[1].filename = strdup("stdout"); + fd_table[2].fp = stderr; + fd_table[2].filename = strdup("stderr"); - logfile = log; + logfile = log; } #ifdef CHECK_WITH_VALGRIND void vpi_mcd_delete(void) { free(mcd_table[0].filename); - mcd_table[0].filename = 0; - mcd_table[0].fp = 0; + mcd_table[0].filename = NULL; + mcd_table[0].fp = NULL; free(fd_table[0].filename); - fd_table[0].filename = 0; - fd_table[0].fp = 0; + fd_table[0].filename = NULL; + fd_table[0].fp = NULL; free(fd_table[1].filename); - fd_table[1].filename = 0; - fd_table[1].fp = 0; + fd_table[1].filename = NULL; + fd_table[1].fp = NULL; free(fd_table[2].filename); - fd_table[2].filename = 0; - fd_table[2].fp = 0; + fd_table[2].filename = NULL; + fd_table[2].fp = NULL; + + free(fd_table); + fd_table = NULL; + fd_table_len = 0; } #endif @@ -112,7 +124,7 @@ extern "C" PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) } } else { unsigned idx = FD_IDX(mcd); - if (idx > 2 && idx < FD_MAX && fd_table[idx].fp) { + if (idx > 2 && idx < fd_table_len && fd_table[idx].fp) { rc = fclose(fd_table[idx].fp); free(fd_table[idx].filename); fd_table[idx].fp = NULL; @@ -131,7 +143,7 @@ extern "C" char *vpi_mcd_name(PLI_UINT32 mcd) } } else { unsigned idx = FD_IDX(mcd); - if (idx < FD_MAX) + if (idx < fd_table_len) return fd_table[idx].filename; } return NULL; @@ -222,7 +234,7 @@ extern "C" PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) } } else { unsigned idx = FD_IDX(mcd); - if (idx < FD_MAX) rc = fflush(fd_table[idx].fp); + if (idx < fd_table_len) rc = fflush(fd_table[idx].fp); } return rc; } @@ -240,29 +252,35 @@ extern "C" PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) */ extern "C" PLI_INT32 vpi_fopen(const char*name, const char*mode) { - unsigned i; - for(i = 0; i < FD_MAX; i++) { - if(fd_table[i].filename == NULL) - goto got_entry; - } - return 0; /* too many open fd's */ + unsigned i; + for (i = 0; i < fd_table_len; i += 1) { + if (fd_table[i].filename == NULL) goto got_entry; + } + /* We need to allocate more table entries, but to keep things */ + /* sane we'll hard limit this to 1024 file descriptors total. */ + if (fd_table_len >= 1024) return 0; + fd_table_len += FD_INCR; + fd_table = (mcd_entry_s *) realloc(fd_table, + fd_table_len*sizeof(mcd_entry_s)); + for (unsigned idx = i; idx < fd_table_len; idx += 1) { + fd_table[idx].fp = NULL; + fd_table[idx].filename = NULL; + } got_entry: - fd_table[i].fp = fopen(name, mode); - if(fd_table[i].fp == NULL) - return 0; - fd_table[i].filename = strdup(name); - return ((1U<<31)|i); + fd_table[i].fp = fopen(name, mode); + if (fd_table[i].fp == NULL) return 0; + fd_table[i].filename = strdup(name); + return ((1U<<31)|i); } extern "C" FILE *vpi_get_file(PLI_INT32 fd) { // Only deal with FD's - if (IS_MCD(fd)) return NULL; + if (IS_MCD(fd)) return NULL; - // Only know about FD_MAX indices - if (FD_IDX(fd) >= FD_MAX) return NULL; + // Only know about fd_table_len indices + if (FD_IDX(fd) >= fd_table_len) return NULL; - return fd_table[FD_IDX(fd)].fp; + return fd_table[FD_IDX(fd)].fp; } - diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 205eb2704..c6becdb30 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1184,26 +1184,26 @@ void vvp_vector4_t::invert() vvp_vector4_t& vvp_vector4_t::operator &= (const vvp_vector4_t&that) { - // Make sure that all Z bits are turned into X bits. - change_z2x(); - - // This is sneaky. The truth table is: - // 00 01 11 - // 00 00 00 00 - // 01 00 01 11 - // 11 00 11 11 + // The truth table is: + // 00 01 11 10 + // 00 00 00 00 00 + // 01 00 01 11 11 + // 11 00 11 11 11 + // 10 00 11 11 11 if (size_ <= BITS_PER_WORD) { - // Each tmp bit is true if that is 1, X or Z. - unsigned long tmp = that.abits_val_ | that.bbits_val_; - abits_val_ &= that.abits_val_; - bbits_val_ = (bbits_val_ & tmp) | (abits_val_&that.bbits_val_); - + unsigned long tmp1 = abits_val_ | bbits_val_; + unsigned long tmp2 = that.abits_val_ | that.bbits_val_; + abits_val_ = tmp1 & tmp2; + bbits_val_ = (tmp1 & that.bbits_val_) | (tmp2 & bbits_val_); } else { unsigned words = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD; for (unsigned idx = 0; idx < words ; idx += 1) { - unsigned long tmp = that.abits_ptr_[idx]|that.bbits_ptr_[idx]; - abits_ptr_[idx] &= that.abits_ptr_[idx]; - bbits_ptr_[idx] = (bbits_ptr_[idx]&tmp) | (abits_ptr_[idx]&that.bbits_ptr_[idx]); + unsigned long tmp1 = abits_ptr_[idx] | bbits_ptr_[idx]; + unsigned long tmp2 = that.abits_ptr_[idx] | + that.bbits_ptr_[idx]; + abits_ptr_[idx] = tmp1 & tmp2; + bbits_ptr_[idx] = (tmp1 & that.bbits_ptr_[idx]) | + (tmp2 & bbits_ptr_[idx]); } } @@ -1212,34 +1212,29 @@ vvp_vector4_t& vvp_vector4_t::operator &= (const vvp_vector4_t&that) vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that) { - // Make sure that all Z bits are turned into X bits. - change_z2x(); - - // This is sneaky. - // The OR is 1 if either operand is 1. - // The OR is 0 if both operants are 0. - // Otherwise, the AND is X. The truth table is: - // - // 00 01 11 - // 00 00 01 11 - // 01 01 01 01 - // 11 11 01 11 + // The truth table is: + // 00 01 11 10 + // 00 00 01 11 11 + // 01 01 01 01 01 + // 11 11 01 11 11 + // 10 11 01 11 11 if (size_ <= BITS_PER_WORD) { - // Each tmp bit is true if that is 1, X or Z. - unsigned long tmp1 = abits_val_ | bbits_val_; - unsigned long tmp2 = that.abits_val_ | that.bbits_val_; - bbits_val_ = (bbits_val_& ~(that.abits_val_^that.bbits_val_)) - | (that.bbits_val_& ~abits_val_); - abits_val_ = tmp1 | tmp2; + unsigned long tmp = abits_val_ | bbits_val_ | + that.abits_val_ | that.bbits_val_; + bbits_val_ = (~abits_val_ | bbits_val_) & that.bbits_val_ | + (~that.abits_val_ | that.bbits_val_) & bbits_val_; + abits_val_ = tmp; } else { unsigned words = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD; for (unsigned idx = 0; idx < words ; idx += 1) { - unsigned long tmp1 = abits_ptr_[idx] | bbits_ptr_[idx]; - unsigned long tmp2 = that.abits_ptr_[idx] | that.bbits_ptr_[idx]; - bbits_ptr_[idx] = (bbits_ptr_[idx]& ~(that.abits_ptr_[idx]^that.bbits_ptr_[idx])) - | (that.bbits_ptr_[idx]& ~abits_ptr_[idx]); - abits_ptr_[idx] = tmp1 | tmp2; + unsigned long tmp = abits_ptr_[idx] | bbits_ptr_[idx] | + that.abits_ptr_[idx] | that.bbits_ptr_[idx]; + bbits_ptr_[idx] = (~abits_ptr_[idx] | bbits_ptr_[idx]) & + that.bbits_ptr_[idx] | + (~that.abits_ptr_[idx] | + that.bbits_ptr_[idx]) & bbits_ptr_[idx]; + abits_ptr_[idx] = tmp; } }