From e0a988bf7e119f516a6e3b1d57e550d8c9359ea8 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 31 Jul 1999 19:14:47 +0000 Subject: [PATCH] Add functions up to elaboration (Ed Carter) --- Makefile.in | 4 ++-- Module.cc | 10 +++++++++- Module.h | 8 +++++++- PExpr.h | 19 ++++++++++++++++++- PTask.h | 18 +++++++++++++++++- netlist.cc | 8 +++++++- parse.y | 38 +++++++++++++++++++++++++++++++++----- pform.cc | 28 +++++++++++++++++++++++++--- pform.h | 6 +++++- pform_dump.cc | 36 +++++++++++++++++++++++++++++++++++- 10 files changed, 158 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index df56cce76..c08df2718 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.9 1999/07/18 05:52:46 steve Exp $" +#ident "$Id: Makefile.in,v 1.10 1999/07/31 19:14:47 steve Exp $" # # SHELL = /bin/sh @@ -58,7 +58,7 @@ FF = nobufz.o propinit.o sigfold.o xnfio.o xnfsyn.o O = main.o cprop.o design_dump.o elaborate.o emit.o eval.o functor.o \ lexor.o mangle.o netlist.o parse.o parse_misc.o pform.o pform_dump.o \ verinum.o verireal.o target.o targets.o Module.o PExpr.o PGate.o \ -PTask.o PWire.o Statement.o \ +PTask.o PFunction.o PWire.o Statement.o \ $(FF) $(TT) Makefile: Makefile.in config.status diff --git a/Module.cc b/Module.cc index ac8638ce6..714790f69 100644 --- a/Module.cc +++ b/Module.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Module.cc,v 1.3 1999/07/03 02:12:51 steve Exp $" +#ident "$Id: Module.cc,v 1.4 1999/07/31 19:14:47 steve Exp $" #endif # include "Module.h" @@ -33,6 +33,11 @@ void Module::add_task(const string&name, PTask*task) tasks_[name] = task; } +void Module::add_function(const string &name, PFunction *func) +{ + funcs_[name] = func; +} + void Module::add_wire(PWire*wire) { wires_.push_back(wire); @@ -59,6 +64,9 @@ PWire* Module::get_wire(const string&name) /* * $Log: Module.cc,v $ + * Revision 1.4 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.3 1999/07/03 02:12:51 steve * Elaborate user defined tasks. * diff --git a/Module.h b/Module.h index 8ebd22114..60a549397 100644 --- a/Module.h +++ b/Module.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Module.h,v 1.5 1999/07/03 02:12:51 steve Exp $" +#ident "$Id: Module.h,v 1.6 1999/07/31 19:14:47 steve Exp $" #endif # include @@ -29,6 +29,7 @@ class PExpr; class PGate; class PTask; +class PFunction; class PWire; class PProcess; class Design; @@ -57,6 +58,7 @@ class Module { void add_wire(PWire*wire); void add_behavior(PProcess*behave); void add_task(const string&name, PTask*def); + void add_function(const string&name, PFunction*def); // Find a wire by name. This is used for connecting gates to // existing wires, etc. @@ -76,6 +78,7 @@ class Module { list gates_; list behaviors_; map tasks_; + map funcs_; private: // Not implemented Module(const Module&); @@ -85,6 +88,9 @@ class Module { /* * $Log: Module.h,v $ + * Revision 1.6 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.5 1999/07/03 02:12:51 steve * Elaborate user defined tasks. * diff --git a/PExpr.h b/PExpr.h index 63ecaaaec..b1f65365e 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PExpr.h,v 1.15 1999/07/22 02:05:20 steve Exp $" +#ident "$Id: PExpr.h,v 1.16 1999/07/31 19:14:47 steve Exp $" #endif # include @@ -225,8 +225,25 @@ class PETernary : public PExpr { PExpr*fal_; }; + +class PECallFunction : public PExpr { + public: + explicit PECallFunction(const string &n, const svector &parms) + : name_(n), parms_(parms) {} + ~PECallFunction() {} + + virtual void dump(ostream &) const; + + private: + string name_; + svector parms_; +}; + /* * $Log: PExpr.h,v $ + * Revision 1.16 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.15 1999/07/22 02:05:20 steve * is_constant method for PEConcat. * diff --git a/PTask.h b/PTask.h index 22a8c2b8c..8c3c29fcd 100644 --- a/PTask.h +++ b/PTask.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PTask.h,v 1.2 1999/07/24 02:11:19 steve Exp $" +#ident "$Id: PTask.h,v 1.3 1999/07/31 19:14:47 steve Exp $" #endif # include "LineInfo.h" @@ -50,8 +50,24 @@ class PTask : public LineInfo { PTask& operator=(const PTask&); }; +class PFunction : public LineInfo { + public: + explicit PFunction(svector *p, Statement *s); + ~PFunction(); + + //virtual void elaborate(Design *des, const string &path) const {} + void dump(ostream&, unsigned) const; + + private: + svector *ports_; + Statement *statement_; +}; + /* * $Log: PTask.h,v $ + * Revision 1.3 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.2 1999/07/24 02:11:19 steve * Elaborate task input ports. * diff --git a/netlist.cc b/netlist.cc index 1d4f35476..8cbfeff31 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.cc,v 1.49 1999/07/31 03:16:54 steve Exp $" +#ident "$Id: netlist.cc,v 1.50 1999/07/31 19:14:47 steve Exp $" #endif # include @@ -30,6 +30,9 @@ ostream& operator<< (ostream&o, NetNet::Type t) case NetNet::IMPLICIT: o << "wire /*implicit*/"; break; + case NetNet::IMPLICIT_REG: + o << "reg /*implicit*/"; + break; case NetNet::INTEGER: o << "integer"; break; @@ -1527,6 +1530,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.50 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.49 1999/07/31 03:16:54 steve * move binary operators to derived classes. * diff --git a/parse.y b/parse.y index 6787d7e75..5a9848a28 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.53 1999/07/28 03:47:24 steve Exp $" +#ident "$Id: parse.y,v 1.54 1999/07/31 19:14:47 steve Exp $" #endif # include "parse_misc.h" @@ -53,6 +53,7 @@ extern void lex_end_table(); NetNet::PortType porttype; PTask*task; + PFunction*function; PWire*wire; svector*wires; @@ -108,6 +109,7 @@ extern void lex_end_table(); %type port %type list_of_ports list_of_ports_opt %type task_item task_item_list task_item_list_opt +%type function_item function_item_list %type port_name %type port_name_list @@ -129,6 +131,7 @@ extern void lex_end_table(); %type port_type %type task_body +%type func_body %type event_expression %type event_control %type statement statement_opt @@ -609,8 +612,10 @@ expr_primary $$ = tmp; } | identifier '(' expression_list ')' - { yyerror(@2, "Sorry, function calls not supported."); - $$ = 0; + { PECallFunction*tmp = new PECallFunction($1, *$3); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } | SYSTEM_IDENTIFIER '(' expression_list ')' { yyerror(@2, "Sorry, function calls not supported."); @@ -650,19 +655,34 @@ expr_primary func_body : function_item_list statement + { $$ = new PFunction($1, $2); } | function_item_list { yyerror(@1, "function body has no statement."); } ; function_item : K_input range_opt list_of_variables ';' + { svector*tmp + = pform_make_task_ports(NetNet::PINPUT, $2, $3); + delete $2; + delete $3; + $$ = tmp; + } | K_reg range_opt list_of_variables ';' + { $$ = 0; } | K_integer list_of_variables ';' + { $$ = 0; } ; function_item_list : function_item + { $$ = $1; } | function_item_list function_item + { svector*tmp = new svector(*$1, *$2); + delete $1; + delete $2; + $$ = tmp; + } ; /* A gate_instance is a module instantiation or a built in part @@ -996,8 +1016,16 @@ module_item pform_set_task($2, $5); delete $2; } - | K_function range_or_type_opt IDENTIFIER ';' func_body K_endfunction - { yyerror(@1, "Sorry, function declarations not supported."); + | K_function range_or_type_opt IDENTIFIER ';' + { pform_push_scope($3); } + func_body + { pform_pop_scope(); } + K_endfunction + { PFunction *tmp = $6; + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + pform_set_function($3, $6); + delete $3; } | K_specify specify_item_list K_endspecify { diff --git a/pform.cc b/pform.cc index f1733980f..27da84916 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.33 1999/07/24 02:11:20 steve Exp $" +#ident "$Id: pform.cc,v 1.34 1999/07/31 19:14:47 steve Exp $" #endif # include "compiler.h" @@ -435,7 +435,7 @@ void pform_set_port_type(const string&name, NetNet::PortType pt) * but we know that if the name matches it is a part of the current * task, so in that case I just assign direction to it. * - * The following example demonstrates some if the issues: + * The following example demonstrates some of the issues: * * task foo; * input a; @@ -449,7 +449,21 @@ void pform_set_port_type(const string&name, NetNet::PortType pt) * the wire is declared as a register, so I create the foo.a * wire. For ``b'', I will find that there is already a foo.b and I * just set the port direction. In either case, the ``reg a, b'' - * statement is caught by the block_item non-terminal and processed there. + * statement is caught by the block_item non-terminal and processed + * there. + * + * Ports are implicitly type reg, because it must be possible for the + * port to act as an l-value in a procedural assignment. It is obvious + * for output and inout ports that the type is reg, because the task + * only contains behavior (no structure) to a procedural assignment is + * the *only* way to affect the put. It is less obvious for input + * ports, but in practice an input port receives its value as if by a + * procedural assignment from the calling behavior. + * + * This function also handles the input ports of function + * definitions. Input ports to function definitions have the same + * constraints as those of tasks, so this works fine. Functions have + * no output or inout ports. */ svector*pform_make_task_ports(NetNet::PortType pt, const svector*range, @@ -488,6 +502,11 @@ void pform_set_task(const string&name, PTask*task) pform_cur_module->add_task(name, task); } +void pform_set_function(const string&name, PFunction *func) +{ + pform_cur_module->add_function(name, func); +} + void pform_set_attrib(const string&name, const string&key, const string&value) { PWire*cur = pform_cur_module->get_wire(name); @@ -638,6 +657,9 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * 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. * diff --git a/pform.h b/pform.h index 02b2d97d8..2ef5bcf8a 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.h,v 1.24 1999/07/24 02:11:20 steve Exp $" +#ident "$Id: pform.h,v 1.25 1999/07/31 19:14:47 steve Exp $" #endif # include "netlist.h" @@ -121,6 +121,7 @@ extern void pform_set_net_range(list*names, const svector*); extern void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r); extern void pform_set_reg_integer(list*names); extern void pform_set_task(const string&, PTask*); +extern void pform_set_function(const string&, PFunction*); extern void pform_set_attrib(const string&name, const string&key, const string&value); extern void pform_set_type_attrib(const string&name, const string&key, @@ -165,6 +166,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.25 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.24 1999/07/24 02:11:20 steve * Elaborate task input ports. * diff --git a/pform_dump.cc b/pform_dump.cc index fb82c98b2..f06b2fc4c 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.30 1999/07/30 00:43:17 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.31 1999/07/31 19:14:47 steve Exp $" #endif /* @@ -61,6 +61,17 @@ void PEConcat::dump(ostream&out) const if (repeat_) out << "}"; } +void PECallFunction::dump(ostream &out) const +{ + out << name_ << "("; + parms_[0]->dump(out); + for (unsigned idx = 0; idx < parms_.count(); ++idx) { + out << ", "; + parms_[idx]->dump(out); + } + out << ")"; +} + void PEEvent::dump(ostream&out) const { switch (type_) { @@ -401,6 +412,17 @@ void PForStatement::dump(ostream&out, unsigned ind) const statement_->dump(out, ind+3); } +void PFunction::dump(ostream&out, unsigned ind) const +{ + for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) { + out << setw(ind) << ""; + out << "input "; + out << (*ports_)[idx]->name() << ";" << endl; + } + + statement_->dump(out, ind); +} + void PRepeat::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl; @@ -480,6 +502,15 @@ void Module::dump(ostream&out) const out << " endtask;" << endl; } + // Dump the function definitions. + typedef map::const_iterator func_iter_t; + for (func_iter_t cur = funcs_.begin() + ; cur != funcs_.end() ; cur ++) { + out << " function " << (*cur).first << ";" << endl; + (*cur).second->dump(out, 6); + out << " endfunction;" << endl; + } + // Iterate through and display all the gates for (list::const_iterator gate = gates_.begin() @@ -547,6 +578,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.31 1999/07/31 19:14:47 steve + * Add functions up to elaboration (Ed Carter) + * * Revision 1.30 1999/07/30 00:43:17 steve * Handle dumping tasks with no ports. *