Merge branch 'master' into vvp-net-out-rework
This commit is contained in:
commit
307121d1af
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
3
Module.h
3
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
74
elaborate.cc
74
elaborate.cc
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
320
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<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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
9
main.cc
9
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
140
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 <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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
4
pform.cc
4
pform.cc
|
|
@ -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);
|
||||
|
|
|
|||
3
pform.h
3
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<perm_string>*parms,
|
||||
svector<PWire*>*decl, list<string>*table,
|
||||
|
|
|
|||
4
t-dll.cc
4
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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ';'
|
||||
|
|
|
|||
102
vvp/vpi_mcd.cc
102
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue