diff --git a/Module.h b/Module.h index 7d1f25d87..658c4ea11 100644 --- a/Module.h +++ b/Module.h @@ -19,12 +19,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Module.h,v 1.11 1999/12/11 05:45:41 steve Exp $" +#ident "$Id: Module.h,v 1.12 2000/01/09 05:50:48 steve Exp $" #endif # include # include # include "svector.h" +# include "named.h" # include class PExpr; class PGate; @@ -95,7 +96,9 @@ class Module { const list& get_behaviors() const { return behaviors_; } void dump(ostream&out) const; - bool elaborate(Design*, NetScope*scope, svector*overrides_) const; + bool elaborate(Design*, NetScope*scope, + named*parms, unsigned nparms, + svector*overrides_) const; private: const string name_; @@ -115,6 +118,9 @@ class Module { /* * $Log: Module.h,v $ + * Revision 1.12 2000/01/09 05:50:48 steve + * Support named parameter override lists. + * * Revision 1.11 1999/12/11 05:45:41 steve * Fix support for attaching attributes to primitive gates. * diff --git a/PGate.h b/PGate.h index 91e6a5477..f749126cf 100644 --- a/PGate.h +++ b/PGate.h @@ -19,10 +19,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PGate.h,v 1.11 1999/12/11 05:45:41 steve Exp $" +#ident "$Id: PGate.h,v 1.12 2000/01/09 05:50:48 steve Exp $" #endif # include "svector.h" +# include "named.h" # include "LineInfo.h" # include "PDelays.h" # include @@ -155,18 +156,29 @@ class PGModule : public PGate { // If the binding of ports is by position, this constructor // builds everything all at once. explicit PGModule(const string&type, const string&name, - svector*overrides, svector*pins) - : PGate(name, pins), type_(type), overrides_(overrides), pins_(0), npins_(0) { } + svector*pins) + : PGate(name, pins), type_(type), overrides_(0), pins_(0), + npins_(0), parms_(0), nparms_(0) { } // If the binding of ports is by name, this constructor takes // the bindings and stores them for later elaboration. - struct bind_t { - string name; - PExpr* parm; - }; explicit PGModule(const string&type, const string&name, - svector*overrides, bind_t*pins, unsigned npins) - : PGate(name, 0), type_(type), overrides_(overrides), pins_(pins), npins_(npins) { } + named*pins, unsigned npins) + : PGate(name, 0), type_(type), overrides_(0), pins_(pins), + npins_(npins), parms_(0), nparms_(0) { } + + + // Parameter overrides can come as an ordered list, or a set + // of named expressions. + void set_parameters(svector*o) + { assert(overrides_ == 0); overrides_ = o; } + + void set_parameters(named*pa, unsigned npa) + { assert(parms_ == 0); + assert(overrides_ == 0); + parms_ = pa; + nparms_ = npa; + } virtual void dump(ostream&out) const; @@ -175,15 +187,22 @@ class PGModule : public PGate { private: string type_; svector*overrides_; - bind_t*pins_; + named*pins_; unsigned npins_; + // These members support parameter override by name + named*parms_; + unsigned nparms_; + void elaborate_mod_(Design*, Module*mod, const string&path) const; void elaborate_udp_(Design*, PUdp *udp, const string&path) const; }; /* * $Log: PGate.h,v $ + * Revision 1.12 2000/01/09 05:50:48 steve + * Support named parameter override lists. + * * Revision 1.11 1999/12/11 05:45:41 steve * Fix support for attaching attributes to primitive gates. * diff --git a/elaborate.cc b/elaborate.cc index 4e7fd66a8..49e1a8d30 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.138 2000/01/02 19:39:03 steve Exp $" +#ident "$Id: elaborate.cc,v 1.139 2000/01/09 05:50:48 steve Exp $" #endif /* @@ -325,6 +325,11 @@ void PGBuiltin::elaborate(Design*des, const string&path) const case XOR: cur[idx] = new NetLogic(inm, pin_count(), NetLogic::XOR); break; + default: + cerr << get_line() << ": internal error: unhandled " + "gate type." << endl; + des->errors += 1; + return; } cur[idx]->set_attributes(attributes); @@ -457,7 +462,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const // elaboration causes the module to generate a netlist with // the ports represented by NetNet objects. I will find them // later. - rmod->elaborate(des, my_scope, overrides_); + rmod->elaborate(des, my_scope, parms_, nparms_, overrides_); // Now connect the ports of the newly elaborated designs to // the expressions that are the instantiation parameters. Scan @@ -1765,7 +1770,9 @@ NetProc* PWhile::elaborate(Design*des, const string&path) const return loop; } -bool Module::elaborate(Design*des, NetScope*scope, svector*overrides_) const +bool Module::elaborate(Design*des, NetScope*scope, + named*parms, unsigned nparms, + svector*overrides_) const { const string path = scope->name(); bool result_flag = true; @@ -1797,14 +1804,24 @@ bool Module::elaborate(Design*des, NetScope*scope, svector*overrides_) c // FIXME: need to release the replaced expression. if (overrides_) { + assert(parms == 0); list::const_iterator cur = param_names.begin(); for (unsigned idx = 0 ; idx < overrides_->count(); idx += 1, cur++) { string pname = path + "." + (*cur); NetExpr*expr = (*overrides_)[idx]->elaborate_expr(des, path); des->set_parameter(pname, expr); } + + } else if (parms) { + + for (unsigned idx = 0 ; idx < nparms ; idx += 1) { + string pname = path + "." + parms[idx].name; + NetExpr*expr = parms[idx].parm->elaborate_expr(des, path); + des->set_parameter(pname, expr); + } } + // Finally, evaluate the parameter value. This step collapses // the parameters to NetEConst values. for (mparm_it_t cur = parameters.begin() @@ -1950,7 +1967,7 @@ Design* elaborate(const map&modules, modlist = &modules; udplist = &primitives; - bool rc = rmod->elaborate(des, scope, (svector*)0); + bool rc = rmod->elaborate(des, scope, 0, 0, (svector*)0); modlist = 0; udplist = 0; @@ -1964,6 +1981,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.139 2000/01/09 05:50:48 steve + * Support named parameter override lists. + * * Revision 1.138 2000/01/02 19:39:03 steve * Structural reduction XNOR. * diff --git a/named.h b/named.h new file mode 100644 index 000000000..ee5bdec0c --- /dev/null +++ b/named.h @@ -0,0 +1,43 @@ +#ifndef __named_H +#define __named_H +/* + * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: named.h,v 1.1 2000/01/09 05:50:49 steve Exp $" +#endif + +# include + +/* + * There are lots of places where names are attached to objects. This + * simple template expresses the lot. + */ + +template struct named { + string name; + T parm; +}; + +/* + * $Log: named.h,v $ + * Revision 1.1 2000/01/09 05:50:49 steve + * Support named parameter override lists. + * + */ +#endif diff --git a/parse.y b/parse.y index bcbd50d78..528ca4765 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.81 2000/01/02 01:59:52 steve Exp $" +#ident "$Id: parse.y,v 1.82 2000/01/09 05:50:49 steve Exp $" #endif # include "parse_misc.h" @@ -45,6 +45,7 @@ extern void lex_end_table(); portname_t*portname; svector*portnames; + struct parmvalue_t*parmvalue; PExpr*expr; svector*exprs; @@ -115,8 +116,8 @@ extern void lex_end_table(); %type task_item task_item_list task_item_list_opt %type function_item function_item_list -%type port_name -%type port_name_list +%type port_name parameter_value_byname +%type port_name_list parameter_value_byname_list %type case_item %type case_items @@ -127,7 +128,7 @@ extern void lex_end_table(); %type expression expr_primary %type lavalue lpvalue %type delay_value delay_value_simple -%type delay1 delay3 delay3_opt parameter_value_opt +%type delay1 delay3 delay3_opt %type expression_list %type assign assign_list @@ -135,6 +136,7 @@ extern void lex_end_table(); %type net_type %type gatetype %type port_type +%type parameter_value_opt %type task_body %type func_body @@ -1232,11 +1234,41 @@ parameter_assign_list a list of expressions in a syntax much line a delay list. (The difference being the list can have any length.) The pform that attaches the expression list to the module checks that the - expressions are constant. */ + expressions are constant. + + Although the BNF in IEEE1364-1995 implies that parameter value + lists must be in parentheses, in practice most compilers will + accept simple expressions outside of parentheses if there is only + one value, so I'll accept simple numbers here. + + The parameter value by name syntax is OVI enhancement BTF-B06 as + approved by WG1364 on 6/28/1998. */ parameter_value_opt : '#' '(' expression_list ')' - { $$ = $3; } + { struct parmvalue_t*tmp = new struct parmvalue_t; + tmp->by_order = $3; + tmp->by_name = 0; + $$ = tmp; + } + | '#' '(' parameter_value_byname_list ')' + { struct parmvalue_t*tmp = new struct parmvalue_t; + tmp->by_order = 0; + tmp->by_name = $3; + $$ = tmp; + } + | '#' NUMBER + { assert($2); + PENumber*tmp = new PENumber($2); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + + struct parmvalue_t*lst = new struct parmvalue_t; + lst->by_order = new svector(1); + (*lst->by_order)[0] = tmp; + lst->by_name = 0; + $$ = lst; + } | '#' error { yyerror(@1, "error: syntax error in parameter value " "assignment list."); @@ -1246,7 +1278,37 @@ parameter_value_opt { $$ = 0; } ; - /* The port (of a module) is a fairle complex item. Each port is +parameter_value_byname + : PORTNAME '(' expression ')' + { portname_t*tmp = new portname_t; + tmp->name = $1; + tmp->parm = $3; + free($1); + $$ = tmp; + } + | PORTNAME '(' ')' + { portname_t*tmp = new portname_t; + tmp->name = $1; + tmp->parm = 0; + free($1); + $$ = tmp; + } + ; + +parameter_value_byname_list + : parameter_value_byname + { svector*tmp = new svector(1); + (*tmp)[0] = $1; + $$ = tmp; + } + | parameter_value_byname_list ',' parameter_value_byname + { svector*tmp = new svector(*$1,$3); + delete $1; + $$ = tmp; + } + ; + + /* The port (of a module) is a fairly complex item. Each port is handled as a Module::port_t object. A simple port reference has a name and a PWire object, but more complex constructs are possible where the name can be attached to a list of PWire objects. diff --git a/pform.cc b/pform.cc index 295f41cca..df482db53 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.cc,v 1.51 2000/01/02 01:59:28 steve Exp $" +#ident "$Id: pform.cc,v 1.52 2000/01/09 05:50:49 steve Exp $" #endif # include "compiler.h" @@ -307,7 +307,7 @@ void pform_makegates(PGBuiltin::Type type, */ static void pform_make_modgate(const string&type, const string&name, - svector*overrides, + struct parmvalue_t*overrides, svector*wires, const string&fn, unsigned ln) { @@ -318,15 +318,32 @@ static void pform_make_modgate(const string&type, return; } - PGate*cur = new PGModule(type, name, overrides, wires); + PGModule*cur = new PGModule(type, name, wires); cur->set_file(fn); cur->set_lineno(ln); + + if (overrides && overrides->by_name) { + unsigned cnt = overrides->by_name->count(); + named*byname = new named[cnt]; + + for (unsigned idx = 0 ; idx < cnt ; idx += 1) { + portname_t*curp = (*overrides->by_name)[idx]; + byname[idx].name = curp->name; + byname[idx].parm = curp->parm; + } + + cur->set_parameters(byname, cnt); + + } else if (overrides && overrides->by_order) { + cur->set_parameters(overrides->by_order); + } + pform_cur_module->add_gate(cur); } static void pform_make_modgate(const string&type, const string&name, - svector*overrides, + struct parmvalue_t*overrides, svector*bind, const string&fn, unsigned ln) { @@ -338,26 +355,44 @@ static void pform_make_modgate(const string&type, } unsigned npins = bind->count(); - PGModule::bind_t*pins = new PGModule::bind_t[npins]; + named*pins = new named[npins]; for (unsigned idx = 0 ; idx < npins ; idx += 1) { portname_t*curp = (*bind)[idx]; pins[idx].name = curp->name; pins[idx].parm = curp->parm; } - PGate*cur = new PGModule(type, name, overrides, pins, npins); + PGModule*cur = new PGModule(type, name, pins, npins); cur->set_file(fn); cur->set_lineno(ln); + + if (overrides && overrides->by_name) { + unsigned cnt = overrides->by_name->count(); + named*byname = new named[cnt]; + + for (unsigned idx = 0 ; idx < cnt ; idx += 1) { + portname_t*curp = (*overrides->by_name)[idx]; + byname[idx].name = curp->name; + byname[idx].parm = curp->parm; + } + + cur->set_parameters(byname, cnt); + + } else if (overrides && overrides->by_order) { + + cur->set_parameters(overrides->by_order); + } + pform_cur_module->add_gate(cur); } void pform_make_modgates(const string&type, - svector*overrides, + struct parmvalue_t*overrides, svector*gates) { - if (overrides) - for (unsigned idx = 0 ; idx < overrides->count() ; idx += 1) - if (! pform_expression_is_constant((*overrides)[idx])) { + if (overrides && overrides->by_order) + for (unsigned idx = 0 ; idx < overrides->by_order->count() ; idx += 1) + if (! pform_expression_is_constant((*overrides->by_order)[idx])) { VLerror("error: Parameter override expression" " must be constant."); return; @@ -773,6 +808,9 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * Revision 1.52 2000/01/09 05:50:49 steve + * Support named parameter override lists. + * * Revision 1.51 2000/01/02 01:59:28 steve * Forgot to handle no overrides at all. * @@ -819,155 +857,5 @@ int pform_parse(const char*path, map&modules, * Revision 1.37 1999/08/03 04:14:49 steve * Parse into pform arbitrarily complex module * port declarations. - * - * Revision 1.36 1999/08/01 16:34:50 steve - * Parse and elaborate rise/fall/decay times - * for gates, and handle the rules for partial - * lists of times. - * - * Revision 1.35 1999/07/31 19:15:21 steve - * misspelled comment. - * - * Revision 1.34 1999/07/31 19:14:47 steve - * Add functions up to elaboration (Ed Carter) - * - * Revision 1.33 1999/07/24 02:11:20 steve - * Elaborate task input ports. - * - * Revision 1.32 1999/07/10 01:03:18 steve - * remove string from lexical phase. - * - * Revision 1.31 1999/07/03 02:12:52 steve - * Elaborate user defined tasks. - * - * Revision 1.30 1999/06/24 04:24:18 steve - * Handle expression widths for EEE and NEE operators, - * add named blocks and scope handling, - * add registers declared in named blocks. - * - * Revision 1.29 1999/06/21 01:02:16 steve - * Fix merging of UDP port type in decls. - * - * Revision 1.28 1999/06/17 05:34:42 steve - * Clean up interface of the PWire class, - * Properly match wire ranges. - * - * Revision 1.27 1999/06/15 03:44:53 steve - * Get rid of the STL vector template. - * - * Revision 1.26 1999/06/13 23:51:16 steve - * l-value part select for procedural assignments. - * - * Revision 1.25 1999/06/12 20:35:27 steve - * parse more verilog. - * - * Revision 1.24 1999/06/12 03:42:17 steve - * Assert state of bit range expressions. - * - * Revision 1.23 1999/06/06 20:45:39 steve - * Add parse and elaboration of non-blocking assignments, - * Replace list with an svector version, - * Add integer support. - * - * Revision 1.22 1999/06/02 15:38:46 steve - * Line information with nets. - * - * Revision 1.21 1999/05/31 15:45:59 steve - * makegates infinite loop fixed. - * - * Revision 1.20 1999/05/29 02:36:17 steve - * module parameter bind by name. - * - * Revision 1.19 1999/05/20 04:31:45 steve - * Much expression parsing work, - * mark continuous assigns with source line info, - * replace some assertion failures with Sorry messages. - * - * Revision 1.18 1999/05/16 05:08:42 steve - * Redo constant expression detection to happen - * after parsing. - * - * Parse more operators and expressions. - * - * Revision 1.17 1999/05/10 00:16:58 steve - * Parse and elaborate the concatenate operator - * in structural contexts, Replace vector - * and list with svector, evaluate - * constant expressions with parameters, handle - * memories as lvalues. - * - * Parse task declarations, integer types. - * - * Revision 1.16 1999/05/08 20:19:20 steve - * Parse more things. - * - * Revision 1.15 1999/05/07 04:26:49 steve - * Parse more complex continuous assign lvalues. - * - * Revision 1.14 1999/05/06 04:37:17 steve - * Get rid of list types. - * - * Revision 1.13 1999/05/06 04:09:28 steve - * Parse more constant expressions. - * - * Revision 1.12 1999/05/02 23:25:32 steve - * Enforce module instance names. - * - * Revision 1.11 1999/04/19 01:59:37 steve - * Add memories to the parse and elaboration phases. - * - * Revision 1.10 1999/02/21 17:01:57 steve - * Add support for module parameters. - * - * Revision 1.9 1999/02/15 02:06:15 steve - * Elaborate gate ranges. - * - * Revision 1.8 1999/01/25 05:45:56 steve - * Add the LineInfo class to carry the source file - * location of things. PGate, Statement and PProcess. - * - * elaborate handles module parameter mismatches, - * missing or incorrect lvalues for procedural - * assignment, and errors are propogated to the - * top of the elaboration call tree. - * - * Attach line numbers to processes, gates and - * assignment statements. - * - * Revision 1.7 1998/12/09 04:02:47 steve - * Support the include directive. - * - * Revision 1.6 1998/12/01 00:42:14 steve - * Elaborate UDP devices, - * Support UDP type attributes, and - * pass those attributes to nodes that - * are instantiated by elaboration, - * Put modules into a map instead of - * a simple list. - * - * Revision 1.5 1998/11/25 02:35:53 steve - * Parse UDP primitives all the way to pform. - * - * Revision 1.4 1998/11/23 00:20:23 steve - * NetAssign handles lvalues as pin links - * instead of a signal pointer, - * Wire attributes added, - * Ability to parse UDP descriptions added, - * XNF generates EXT records for signals with - * the PAD attribute. - * - * Revision 1.3 1998/11/11 00:01:51 steve - * Check net ranges in declarations. - * - * Revision 1.2 1998/11/07 17:05:06 steve - * Handle procedural conditional, and some - * of the conditional expressions. - * - * Elaborate signals and identifiers differently, - * allowing the netlist to hold signal information. - * - * Revision 1.1 1998/11/03 23:29:03 steve - * Introduce verilog to CVS. - * */ diff --git a/pform.h b/pform.h index f9943b723..2a8b535dd 100644 --- a/pform.h +++ b/pform.h @@ -19,10 +19,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.h,v 1.32 1999/12/30 19:06:14 steve Exp $" +#ident "$Id: pform.h,v 1.33 2000/01/09 05:50:49 steve Exp $" #endif # include "netlist.h" +# include "named.h" # include "Module.h" # include "Statement.h" # include "PGate.h" @@ -65,9 +66,12 @@ struct vlltype; /* This is information about port name information for named port connections. */ -struct portname_t { - string name; - PExpr*parm; + +typedef struct named portname_t; + +struct parmvalue_t { + svector*by_order; + svector*by_name; }; /* The lgate is gate instantiation information. */ @@ -144,7 +148,7 @@ extern void pform_makegates(PGBuiltin::Type type, svector*gates); extern void pform_make_modgates(const string&type, - svector*overrides, + struct parmvalue_t*overrides, svector*gates); /* Make a continuous assignment node, with optional bit- or part- select. */ @@ -176,6 +180,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.33 2000/01/09 05:50:49 steve + * Support named parameter override lists. + * * Revision 1.32 1999/12/30 19:06:14 steve * Support reg initial assignment syntax. * diff --git a/pform_dump.cc b/pform_dump.cc index a358b3a47..d73829a33 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform_dump.cc,v 1.45 1999/10/10 01:59:55 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.46 2000/01/09 05:50:49 steve Exp $" #endif /* @@ -283,7 +283,10 @@ void PGBuiltin::dump(ostream&out) const void PGModule::dump(ostream&out) const { out << " " << type_ << " "; + + // If parameters are overridden by order, dump them. if (overrides_) { + assert(parms_ == 0); out << "#("; out << *((*overrides_)[0]); for (unsigned idx = 1 ; idx < overrides_->count() ; idx += 1) { @@ -291,6 +294,19 @@ void PGModule::dump(ostream&out) const } out << ") "; } + + // If parameters are overridden by name, dump them. + if (parms_) { + assert(overrides_ == 0); + out << "#("; + out << "." << parms_[0].name << "(" << *parms_[0].parm << ")"; + for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) { + out << ", ." << parms_[idx].name << "(" << + *parms_[idx].parm << ")"; + } + out << ") "; + } + out << get_name() << "("; if (pins_) { out << "." << pins_[0].name << "("; @@ -675,6 +691,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.46 2000/01/09 05:50:49 steve + * Support named parameter override lists. + * * Revision 1.45 1999/10/10 01:59:55 steve * Structural case equals device. *