Merge branch 'master' into vvp-net-out-rework

This commit is contained in:
Stephen Williams 2009-06-07 18:00:55 -07:00
commit 307121d1af
23 changed files with 724 additions and 433 deletions

View File

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

View File

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

View File

@ -65,8 +65,11 @@ void PDelays::set_delays(const svector<PExpr*>*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);

View File

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

View File

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

View File

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

View File

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

View File

@ -978,6 +978,28 @@ static bool need_bufz_for_input_port(const vector<NetNet*>&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<PEIdent*> 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<PEIdent*> 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;
}
}
}

View File

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

320
lexor.lex
View File

@ -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<int> 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); }
<PPUCDRIVE>.* { process_ucdrive(yytext); }
<PPUCDRIVE>\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;

View File

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

View File

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

View File

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

View File

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

140
parse.y
View File

@ -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 <flag> from_exclude
%type <number> 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

View File

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

View File

@ -467,12 +467,14 @@ void pform_module_set_ports(vector<Module::port_t*>*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<perm_string,Module*>::const_iterator test =
pform_modules.find(mod_name);

View File

@ -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<perm_string>*parms,
svector<PWire*>*decl, list<string>*table,

View File

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

View File

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

View File

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

View File

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

View File

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