Parse port_declaration_lists from the 2001 Standard.
This commit is contained in:
parent
ca9abaf0c5
commit
bf10c5762a
24
Module.cc
24
Module.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: Module.cc,v 1.18 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -27,12 +27,9 @@
|
|||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
Module::Module(const char*name, const svector<Module::port_t*>*pp)
|
||||
Module::Module(const char*name)
|
||||
: name_(strdup(name))
|
||||
{
|
||||
if (pp)
|
||||
ports_ = *pp;
|
||||
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
|
|
@ -72,7 +69,7 @@ void Module::add_behavior(PProcess*b)
|
|||
|
||||
unsigned Module::port_count() const
|
||||
{
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -82,11 +79,11 @@ unsigned Module::port_count() const
|
|||
*/
|
||||
const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
{
|
||||
assert(idx < ports_.count());
|
||||
assert(idx < ports.count());
|
||||
static svector<PEIdent*> zero;
|
||||
|
||||
if (ports_[idx])
|
||||
return ports_[idx]->expr;
|
||||
if (ports[idx])
|
||||
return ports[idx]->expr;
|
||||
else
|
||||
return zero;
|
||||
}
|
||||
|
|
@ -94,11 +91,11 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
|||
unsigned Module::find_port(const string&name) const
|
||||
{
|
||||
assert(name != "");
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1)
|
||||
if (ports_[idx]->name == name)
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1)
|
||||
if (ports[idx]->name == name)
|
||||
return idx;
|
||||
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -142,6 +139,9 @@ const list<PProcess*>& Module::get_behaviors() const
|
|||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.18 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
|
|
|||
15
Module.h
15
Module.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: Module.h,v 1.25 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
|
|
@ -60,7 +60,7 @@ class Module : public LineInfo {
|
|||
};
|
||||
|
||||
public:
|
||||
explicit Module(const char*name, const svector<port_t*>*);
|
||||
explicit Module(const char*name);
|
||||
~Module();
|
||||
|
||||
|
||||
|
|
@ -84,6 +84,10 @@ class Module : public LineInfo {
|
|||
a parameter-index to its name. */
|
||||
list<string> param_names;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports;
|
||||
|
||||
/* Keep a table of named events declared in the module. */
|
||||
map<string,PEvent*>events;
|
||||
|
||||
|
|
@ -127,10 +131,6 @@ class Module : public LineInfo {
|
|||
private:
|
||||
char* name_;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports_;
|
||||
|
||||
map<hname_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
|
|
@ -145,6 +145,9 @@ class Module : public LineInfo {
|
|||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.25 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.24 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
|
|
|||
98
README.txt
98
README.txt
|
|
@ -244,102 +244,8 @@ command. This program invokes the preprocessor (ivlpp) and the
|
|||
compiler (ivl) with the proper command line options to get the job
|
||||
done in a friendly way. See the iverilog(1) man page for usage details.
|
||||
|
||||
4.1 Running IVL Directly (not recommended)
|
||||
|
||||
NOTE: The preferred method of running Icarus Verilog is the
|
||||
iverilog command described above. The instructions below may
|
||||
change at any time without notice.
|
||||
|
||||
The ivl command is the compiler driver, that invokes the parser,
|
||||
optimization functions and the code generator, but not the preprocessor.
|
||||
|
||||
Usage: ivl <options>... file
|
||||
ivl -h
|
||||
ivl -V
|
||||
|
||||
-F <name>
|
||||
Use this flag to request an optimization function be applied
|
||||
to the netlist before it is sent to the target output
|
||||
stage. Any number of -F options may be given, to specify a
|
||||
variety of processing steps. The steps will be applied in
|
||||
order, with the output of one uses as the input to the next.
|
||||
|
||||
The function is specified by name. Use the "ivl -h" command to
|
||||
get a list of configured function names.
|
||||
|
||||
-h
|
||||
Print usage information, and exit.
|
||||
|
||||
-m <module>
|
||||
Cause a named VPI module to be included in the module
|
||||
list. This parameter appends the named module to the end of
|
||||
the VPI_MODULE_LIST. This is an ordered list of modules to be
|
||||
loaded into the simulation at runtime.
|
||||
|
||||
This list can also be set with -fVPI_MODULE_LIST=<list> which
|
||||
sets the list completely. Then, -m after this will append
|
||||
module names to the list specified. The default list
|
||||
includes "system".
|
||||
|
||||
-N <file>
|
||||
Dump the elaborated netlist to the named file. The netlist is
|
||||
the folly elaborated netlist, after all the function modules
|
||||
are applied and right before the output generator is
|
||||
called. This is an aid for debugging the compiler, and the
|
||||
output generator in particular.
|
||||
|
||||
-o <file>
|
||||
Normally, the generated result is sent to standard
|
||||
output. Use the -o flag to specify an output file for the
|
||||
generated result.
|
||||
|
||||
-P <file>
|
||||
Write the PForm of the parsed input to the specified file.
|
||||
The pform is the compiler's understanding of the input after
|
||||
parsing and before elaboration. This is an aid for debugging
|
||||
the compiler.
|
||||
|
||||
-p <assign>
|
||||
Use this flag to set a parameter value. The format of the
|
||||
assignment is <key>=<value> where key is any string up to the
|
||||
first '=', and <value> is the rest of the option. If the '='
|
||||
is omitted, then the key is assigned the empty string.
|
||||
|
||||
The useful keys are defined by the functions and the target in
|
||||
use. These assignments are specifically useful for passing
|
||||
target specific information to the target back-end, or
|
||||
options/parameters to optimization functions, if any are defined.
|
||||
|
||||
-s <module>
|
||||
Normally, ivl will locate all the modules that are defined but
|
||||
never instantiated, and use these as the design roots for
|
||||
elaboration. This flag allows the choice of root module(s) to
|
||||
be manually overridden. It can be used more than once on the
|
||||
command line if multiple root modules are needed.
|
||||
|
||||
-T [min|typ|max]
|
||||
Normally, ivl will select typ values from min:type:max
|
||||
expressions and print a warning. This flag tells the compiler
|
||||
exactly which value to choose, and suppresses the warning.
|
||||
|
||||
-t <name>
|
||||
Select the output format for the compiled result. Use the
|
||||
"ivl -h" command to get a list of configured targets.
|
||||
|
||||
-v Print progress indications, and (if supported by the system)
|
||||
executions times in ivl precessing steps.
|
||||
|
||||
-V
|
||||
Print version and copyright information for ivl, and exit.
|
||||
|
||||
-y <dir>
|
||||
Add the specified directory to the library search path. If
|
||||
missing modules are discovered during elaboration, ivl will
|
||||
attempt to locate an implementation by searching the library
|
||||
directories for a Verilog source file with the same name as
|
||||
the module.
|
||||
|
||||
4.2 EXAMPLES
|
||||
4.1 EXAMPLES
|
||||
|
||||
Example: Compiling "hello.vl"
|
||||
|
||||
|
|
@ -405,7 +311,7 @@ constructs.
|
|||
- force to nets are not supported. Force to variables, and
|
||||
assign/deassign, are supported.
|
||||
|
||||
5.0 Nonstandard Constructs
|
||||
5.1 Nonstandard Constructs
|
||||
|
||||
Icarus Verilog includes some features that are not part of the
|
||||
IEEE1364 standard, but have well defined meaning. These are extensions
|
||||
|
|
|
|||
11
elab_sig.cc
11
elab_sig.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_sig.cc,v 1.20 2002/01/26 05:28:28 steve Exp $"
|
||||
#ident "$Id: elab_sig.cc,v 1.21 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -71,8 +71,8 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
// Scan all the ports of the module, and make sure that each
|
||||
// is connected to wires that have port declarations.
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||
Module::port_t*pp = ports_[idx];
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
Module::port_t*pp = ports[idx];
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports_, name)) {
|
||||
if (! signal_is_in_port(ports, name)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: Signal "
|
||||
<< name << " has a declared direction "
|
||||
|
|
@ -519,6 +519,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.21 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.20 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
|
|
|
|||
176
parse.y
176
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.149 2002/04/21 17:43:13 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.150 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -129,12 +129,12 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
|||
|
||||
%type <hier> identifier
|
||||
%type <text> register_variable
|
||||
%type <texts> register_variable_list list_of_variables
|
||||
%type <texts> register_variable_list list_of_identifiers
|
||||
|
||||
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
||||
|
||||
%type <mport> port port_opt port_reference port_reference_list
|
||||
%type <mports> list_of_ports list_of_ports_opt
|
||||
%type <mport> port port_opt port_reference port_reference_list port_declaration
|
||||
%type <mports> list_of_ports list_of_ports_opt list_of_port_declarations
|
||||
|
||||
%type <wires> task_item task_item_list task_item_list_opt
|
||||
%type <wires> function_item function_item_list
|
||||
|
|
@ -156,7 +156,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
|||
%type <exprs> assign assign_list
|
||||
|
||||
%type <exprs> range range_opt
|
||||
%type <nettype> net_type
|
||||
%type <nettype> net_type var_type
|
||||
%type <gatetype> gatetype
|
||||
%type <porttype> port_type
|
||||
%type <parmvalue> parameter_value_opt
|
||||
|
|
@ -222,11 +222,11 @@ block_item_decl
|
|||
| K_time register_variable_list ';'
|
||||
{ pform_set_reg_time($2);
|
||||
}
|
||||
| K_real list_of_variables ';'
|
||||
| K_real list_of_identifiers ';'
|
||||
{ delete $2;
|
||||
yyerror(@1, "sorry: real variables not supported.");
|
||||
}
|
||||
| K_realtime list_of_variables ';'
|
||||
| K_realtime list_of_identifiers ';'
|
||||
{ delete $2;
|
||||
yyerror(@1, "sorry: reatime variables not supported.");
|
||||
}
|
||||
|
|
@ -894,20 +894,20 @@ expr_primary
|
|||
declaration) or an input declaration. There are no output or
|
||||
inout ports. */
|
||||
function_item
|
||||
: K_input range_opt list_of_variables ';'
|
||||
: K_input range_opt list_of_identifiers ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_output range_opt list_of_variables ';'
|
||||
| K_output range_opt list_of_identifiers ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
yyerror(@1, "Functions may not have output ports.");
|
||||
}
|
||||
| K_inout range_opt list_of_variables ';'
|
||||
| K_inout range_opt list_of_identifiers ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
|
|
@ -1034,7 +1034,7 @@ gatetype
|
|||
|
||||
/* A general identifier is a hierarchical name, with the right most
|
||||
name the base of the identifier. This rule builds up a
|
||||
hierarchical name from left to right. */
|
||||
hierarchical name from left to right, forming a list of names. */
|
||||
identifier
|
||||
: IDENTIFIER
|
||||
{ $$ = new hname_t($1);
|
||||
|
|
@ -1048,6 +1048,39 @@ identifier
|
|||
}
|
||||
;
|
||||
|
||||
/* This is a list of identifiers. The result is a list of strings,
|
||||
each one of the identifiers in the list. These are simple,
|
||||
non-hierarchical names separated by ',' characters. */
|
||||
list_of_identifiers
|
||||
: IDENTIFIER
|
||||
{ list<char*>*tmp = new list<char*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| list_of_identifiers ',' IDENTIFIER
|
||||
{ list<char*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/* The list_of_ports and list_of_port_declarations rules are the
|
||||
port list formats for module ports. The lost_of_ports_opt rule is
|
||||
only used by the module start rule.
|
||||
|
||||
The first, the list_of_ports, is the 1364-1995 format, a list of
|
||||
port names, including .name() syntax.
|
||||
|
||||
The list_of_port_declaractions the 1364-2001 format, an in-line
|
||||
declaration of the ports.
|
||||
|
||||
In both cases, the lost_of_ports and lost_of_port_declarations
|
||||
returns an array of Module::port_t* items that include the name
|
||||
of the port internally and externally. The actual creation of the
|
||||
nets/variables is done in the declaration, whether internal to
|
||||
the port list or in amongst the module items. */
|
||||
|
||||
list_of_ports
|
||||
: port_opt
|
||||
{ svector<Module::port_t*>*tmp
|
||||
|
|
@ -1063,23 +1096,62 @@ list_of_ports
|
|||
}
|
||||
;
|
||||
|
||||
list_of_port_declarations
|
||||
: port_declaration
|
||||
{ svector<Module::port_t*>*tmp
|
||||
= new svector<Module::port_t*>(1);
|
||||
(*tmp)[0] = $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| list_of_port_declarations ',' port_declaration
|
||||
{ svector<Module::port_t*>*tmp
|
||||
= new svector<Module::port_t*>(*$1, $3);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
port_declaration
|
||||
: K_input net_type IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($3, @1.text,
|
||||
@1.first_line);
|
||||
pform_makewire(@1, $3, $2, NetNet::PINPUT);
|
||||
delete $3;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| K_inout net_type IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($3, @1.text,
|
||||
@1.first_line);
|
||||
pform_makewire(@1, $3, $2, NetNet::PINOUT);
|
||||
delete $3;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| K_output net_type IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($3, @1.text,
|
||||
@1.first_line);
|
||||
pform_makewire(@1, $3, $2, NetNet::POUTPUT);
|
||||
delete $3;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| K_output var_type IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($3, @1.text,
|
||||
@1.first_line);
|
||||
pform_makewire(@1, $3, $2, NetNet::POUTPUT);
|
||||
delete $3;
|
||||
$$ = ptmp;
|
||||
}
|
||||
;
|
||||
|
||||
list_of_ports_opt
|
||||
: '(' list_of_ports ')' { $$ = $2; }
|
||||
| '(' list_of_port_declarations ')' { $$ = $2; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
list_of_variables
|
||||
: IDENTIFIER
|
||||
{ list<char*>*tmp = new list<char*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| list_of_variables ',' IDENTIFIER
|
||||
{ list<char*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
/* An lavalue is the expression that can go on the left side of a
|
||||
continuous assign statement. This checks (where it can) that the
|
||||
|
|
@ -1184,22 +1256,21 @@ assign_list
|
|||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
module
|
||||
: module_start IDENTIFIER list_of_ports_opt ';'
|
||||
{ pform_startmodule($2, $3, @1.text, @1.first_line);
|
||||
}
|
||||
module_item_list
|
||||
K_endmodule
|
||||
{ pform_endmodule($2);
|
||||
delete $2;
|
||||
}
|
||||
| module_start IDENTIFIER list_of_ports_opt ';'
|
||||
{ pform_startmodule($2, $3, @1.text, @1.first_line);
|
||||
}
|
||||
|
||||
/* This is the global structure of a module. A module in a start
|
||||
section, with optional ports, then an opetional list of module
|
||||
items, and finally an end marker. */
|
||||
|
||||
module : module_start IDENTIFIER
|
||||
{ pform_startmodule($2, @1.text, @1.first_line); }
|
||||
list_of_ports_opt ';'
|
||||
{ pform_module_set_ports($4); }
|
||||
module_item_list_opt
|
||||
K_endmodule
|
||||
{ pform_endmodule($2);
|
||||
delete $2;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
module_start : K_module | K_macromodule ;
|
||||
|
|
@ -1210,7 +1281,7 @@ range_delay : range_opt delay3_opt
|
|||
|
||||
|
||||
module_item
|
||||
: net_type range_delay list_of_variables ';'
|
||||
: net_type range_delay list_of_identifiers ';'
|
||||
{ pform_makewire(@1, $2.range, $3, $1);
|
||||
if ($2.delay != 0) {
|
||||
yyerror(@2, "sorry: net delays not supported.");
|
||||
|
|
@ -1224,13 +1295,13 @@ module_item
|
|||
| net_type drive_strength net_decl_assigns ';'
|
||||
{ pform_makewire(@1, 0, 0, $2, $3, $1);
|
||||
}
|
||||
| K_trireg charge_strength_opt range_delay list_of_variables ';'
|
||||
| K_trireg charge_strength_opt range_delay list_of_identifiers ';'
|
||||
{ yyerror(@1, "sorry: trireg nets not supported.");
|
||||
delete $3.range;
|
||||
delete $3.delay;
|
||||
}
|
||||
|
||||
| port_type range_delay list_of_variables ';'
|
||||
| port_type range_delay list_of_identifiers ';'
|
||||
{ pform_set_port_type(@1, $3, $2.range, $1);
|
||||
}
|
||||
| port_type range_delay error ';'
|
||||
|
|
@ -1242,7 +1313,7 @@ module_item
|
|||
}
|
||||
| block_item_decl
|
||||
| K_defparam defparam_assign_list ';'
|
||||
| K_event list_of_variables ';'
|
||||
| K_event list_of_identifiers ';'
|
||||
{ pform_make_events($2, @1.text, @1.first_line);
|
||||
}
|
||||
|
||||
|
|
@ -1408,6 +1479,11 @@ module_item_list
|
|||
| module_item
|
||||
;
|
||||
|
||||
module_item_list_opt
|
||||
: module_item_list
|
||||
|
|
||||
;
|
||||
|
||||
|
||||
/* A net declaration assignment allows the programmer to combine the
|
||||
net declaration and the continuous assignment into a single
|
||||
|
|
@ -1451,6 +1527,10 @@ net_type
|
|||
| K_trior { $$ = NetNet::TRIOR; }
|
||||
;
|
||||
|
||||
var_type
|
||||
: K_reg { $$ = NetNet::REG; }
|
||||
;
|
||||
|
||||
parameter_assign
|
||||
: IDENTIFIER '=' expression
|
||||
{ PExpr*tmp = $3;
|
||||
|
|
@ -1655,13 +1735,9 @@ port_opt
|
|||
port_reference
|
||||
|
||||
: IDENTIFIER
|
||||
{ Module::port_t*ptmp = new Module::port_t;
|
||||
PEIdent*tmp = new PEIdent(hname_t($1));
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
ptmp->name = $1;
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = tmp;
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($1, @1.text,
|
||||
@1.first_line);
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
|
|
@ -2394,19 +2470,19 @@ statement_opt
|
|||
task_item
|
||||
: block_item_decl
|
||||
{ $$ = new svector<PWire*>(0); }
|
||||
| K_input range_opt list_of_variables ';'
|
||||
| K_input range_opt list_of_identifiers ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINPUT, $2,
|
||||
$3, @1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_output range_opt list_of_variables ';'
|
||||
| K_output range_opt list_of_identifiers ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::POUTPUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_inout range_opt list_of_variables ';'
|
||||
| K_inout range_opt list_of_identifiers ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINOUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
|
|
@ -2568,7 +2644,7 @@ udp_output_sym
|
|||
;
|
||||
|
||||
udp_port_decl
|
||||
: K_input list_of_variables ';'
|
||||
: K_input list_of_identifiers ';'
|
||||
{ $$ = pform_make_udp_input_ports($2); }
|
||||
| K_output IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT);
|
||||
|
|
|
|||
62
pform.cc
62
pform.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.cc,v 1.93 2002/04/18 18:38:37 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.94 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -147,28 +147,18 @@ static unsigned long evaluate_delay(PExpr*delay)
|
|||
return pp->value().as_ulong();
|
||||
}
|
||||
|
||||
void pform_startmodule(const char*name, svector<Module::port_t*>*ports,
|
||||
const char*file, unsigned lineno)
|
||||
void pform_startmodule(const char*name, const char*file, unsigned lineno)
|
||||
{
|
||||
assert( pform_cur_module == 0 );
|
||||
|
||||
/* The parser parses ``module foo()'' as having one
|
||||
unconnected port, but it is really a module with no
|
||||
ports. Fix it up here. */
|
||||
if (ports && (ports->count() == 1) && ((*ports)[0] == 0)) {
|
||||
delete ports;
|
||||
ports = 0;
|
||||
}
|
||||
|
||||
pform_cur_module = new Module(name, ports);
|
||||
pform_cur_module = new Module(name);
|
||||
pform_cur_module->time_unit = pform_time_unit;
|
||||
pform_cur_module->time_precision = pform_time_prec;
|
||||
|
||||
pform_cur_module->set_file(file);
|
||||
pform_cur_module->set_lineno(lineno);
|
||||
|
||||
delete ports;
|
||||
|
||||
if (warn_timescale && pform_timescale_file
|
||||
&& (strcmp(pform_timescale_file,file) != 0)) {
|
||||
|
||||
|
|
@ -180,6 +170,44 @@ void pform_startmodule(const char*name, svector<Module::port_t*>*ports,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called by the parser to make a simple port
|
||||
* reference. This is a name without a .X(...), so the internal name
|
||||
* should be generated to be the same as the X.
|
||||
*/
|
||||
Module::port_t* pform_module_port_reference(char*name,
|
||||
const char*file,
|
||||
unsigned lineno)
|
||||
{
|
||||
Module::port_t*ptmp = new Module::port_t;
|
||||
PEIdent*tmp = new PEIdent(hname_t(name));
|
||||
tmp->set_file(file);
|
||||
tmp->set_lineno(lineno);
|
||||
ptmp->name = name;
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = tmp;
|
||||
|
||||
return ptmp;
|
||||
}
|
||||
|
||||
void pform_module_set_ports(svector<Module::port_t*>*ports)
|
||||
{
|
||||
assert(pform_cur_module);
|
||||
|
||||
/* The parser parses ``module foo()'' as having one
|
||||
unconnected port, but it is really a module with no
|
||||
ports. Fix it up here. */
|
||||
if (ports && (ports->count() == 1) && ((*ports)[0] == 0)) {
|
||||
delete ports;
|
||||
ports = 0;
|
||||
}
|
||||
|
||||
if (ports != 0) {
|
||||
pform_cur_module->ports = *ports;
|
||||
delete ports;
|
||||
}
|
||||
}
|
||||
|
||||
void pform_endmodule(const char*name)
|
||||
{
|
||||
assert(pform_cur_module);
|
||||
|
|
@ -774,7 +802,8 @@ void pform_make_reginit(const struct vlltype&li,
|
|||
* function is called for every declaration.
|
||||
*/
|
||||
void pform_makewire(const vlltype&li, const char*nm,
|
||||
NetNet::Type type)
|
||||
NetNet::Type type,
|
||||
NetNet::PortType port_type)
|
||||
{
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
|
|
@ -801,7 +830,7 @@ void pform_makewire(const vlltype&li, const char*nm,
|
|||
return;
|
||||
}
|
||||
|
||||
cur = new PWire(name, type, NetNet::NOT_A_PORT);
|
||||
cur = new PWire(name, type, port_type);
|
||||
cur->set_file(li.text);
|
||||
cur->set_lineno(li.first_line);
|
||||
pform_cur_module->add_wire(cur);
|
||||
|
|
@ -1233,6 +1262,9 @@ int pform_parse(const char*path, FILE*file)
|
|||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.94 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.93 2002/04/18 18:38:37 steve
|
||||
* Fix first_file test for timescale warning.
|
||||
*
|
||||
|
|
|
|||
22
pform.h
22
pform.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.h,v 1.55 2002/01/12 04:03:39 steve Exp $"
|
||||
#ident "$Id: pform.h,v 1.56 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -117,8 +117,11 @@ struct lgate {
|
|||
* are to apply to the scope of that module. The endmodule causes the
|
||||
* pform to close up and finish the named module.
|
||||
*/
|
||||
extern void pform_startmodule(const char*, svector<Module::port_t*>*,
|
||||
const char*file, unsigned lineno);
|
||||
extern void pform_startmodule(const char*, const char*file, unsigned lineno);
|
||||
extern void pform_module_set_ports(svector<Module::port_t*>*);
|
||||
extern Module::port_t* pform_module_port_reference(char*name,
|
||||
const char*file,
|
||||
unsigned lineno);
|
||||
extern void pform_endmodule(const char*);
|
||||
|
||||
extern void pform_make_udp(const char*name, list<string>*parms,
|
||||
|
|
@ -139,7 +142,8 @@ extern void pform_pop_scope();
|
|||
* go into a module that is currently opened.
|
||||
*/
|
||||
extern void pform_makewire(const struct vlltype&li, const char*name,
|
||||
NetNet::Type type = NetNet::IMPLICIT);
|
||||
NetNet::Type type = NetNet::IMPLICIT,
|
||||
NetNet::PortType =NetNet::NOT_A_PORT);
|
||||
extern void pform_makewire(const struct vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
list<char*>*names,
|
||||
|
|
@ -152,9 +156,16 @@ extern void pform_makewire(const struct vlltype&li,
|
|||
NetNet::Type type);
|
||||
extern void pform_make_reginit(const struct vlltype&li,
|
||||
const char*name, PExpr*expr);
|
||||
|
||||
/* Look up the names of the wires, and set the port type,
|
||||
i.e. input, output or inout. If the wire does not exist, create
|
||||
it. The second form takes a single name. */
|
||||
extern void pform_set_port_type(const struct vlltype&li,
|
||||
list<char*>*names, svector<PExpr*>*,
|
||||
NetNet::PortType);
|
||||
extern void pform_set_port_type(const char*nm, NetNet::PortType pt,
|
||||
const char*file, unsigned lineno);
|
||||
|
||||
extern void pform_set_net_range(list<char*>*names, svector<PExpr*>*, bool);
|
||||
extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r);
|
||||
extern void pform_set_reg_integer(list<char*>*names);
|
||||
|
|
@ -219,6 +230,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
|||
|
||||
/*
|
||||
* $Log: pform.h,v $
|
||||
* Revision 1.56 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.55 2002/01/12 04:03:39 steve
|
||||
* Drive strengths for continuous assignments.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform_dump.cc,v 1.70 2002/04/21 04:59:08 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.71 2002/05/19 23:37:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -679,8 +679,8 @@ void Module::dump(ostream&out) const
|
|||
{
|
||||
out << "module " << name_ << ";" << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||
port_t*cur = ports_[idx];
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
port_t*cur = ports[idx];
|
||||
|
||||
if (cur == 0) {
|
||||
out << " unconnected" << endl;
|
||||
|
|
@ -824,6 +824,9 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.71 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.70 2002/04/21 04:59:08 steve
|
||||
* Add support for conbinational events by finding
|
||||
* the inputs to expressions and some statements.
|
||||
|
|
|
|||
Loading…
Reference in New Issue