Rewire/generalize parsing an elaboration of

function return values to allow for better
 speed and more type support.
This commit is contained in:
steve 2004-05-31 23:34:36 +00:00
parent e7fa56981a
commit 5472b27e1f
20 changed files with 445 additions and 143 deletions

View File

@ -17,16 +17,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $" #ident "$Id: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
#include "PTask.h" #include "PTask.h"
PFunction::PFunction() PFunction::PFunction(perm_string name)
: out_(0), ports_(0), statement_(0) : name_(name), ports_(0), statement_(0)
{ {
return_type_.type = PTF_NONE;
} }
PFunction::~PFunction() PFunction::~PFunction()
@ -46,14 +47,18 @@ void PFunction::set_statement(Statement*s)
statement_ = s; statement_ = s;
} }
void PFunction::set_output(PWire*o) void PFunction::set_return(PTaskFuncArg t)
{ {
assert(out_ == 0); return_type_ = t;
out_ = o;
} }
/* /*
* $Log: PFunction.cc,v $ * $Log: PFunction.cc,v $
* Revision 1.7 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.6 2002/08/12 01:34:58 steve * Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig. * conditional ident string using autoconfig.
* *

32
PTask.h
View File

@ -19,16 +19,32 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $" #ident "$Id: PTask.h,v 1.13 2004/05/31 23:34:36 steve Exp $"
#endif #endif
# include "LineInfo.h" # include "LineInfo.h"
# include "svector.h" # include "svector.h"
# include "StringHeap.h"
# include <string> # include <string>
class Design; class Design;
class NetScope; class NetScope;
class PWire; class PWire;
class Statement; class Statement;
class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
PTF_TIME
};
struct PTaskFuncArg {
PTaskFuncEnum type;
svector<PExpr*>*range;
};
/* /*
* The PTask holds the parsed definitions of a task. * The PTask holds the parsed definitions of a task.
@ -69,16 +85,18 @@ class PTask : public LineInfo {
* The function is similar to a task (in this context) but there is a * The function is similar to a task (in this context) but there is a
* single output port and a set of input ports. The output port is the * single output port and a set of input ports. The output port is the
* function return value. * function return value.
*
* The output value is not elaborated until elaborate_sig.
*/ */
class PFunction : public LineInfo { class PFunction : public LineInfo {
public: public:
explicit PFunction(); explicit PFunction(perm_string name);
~PFunction(); ~PFunction();
void set_ports(svector<PWire *>*p); void set_ports(svector<PWire *>*p);
void set_statement(Statement *s); void set_statement(Statement *s);
void set_output(PWire*); void set_return(PTaskFuncArg t);
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
@ -91,13 +109,19 @@ class PFunction : public LineInfo {
void dump(ostream&, unsigned) const; void dump(ostream&, unsigned) const;
private: private:
PWire*out_; perm_string name_;
PTaskFuncArg return_type_;
svector<PWire *> *ports_; svector<PWire *> *ports_;
Statement *statement_; Statement *statement_;
}; };
/* /*
* $Log: PTask.h,v $ * $Log: PTask.h,v $
* Revision 1.13 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.12 2002/08/12 01:34:58 steve * Revision 1.12 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig. * conditional ident string using autoconfig.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.147 2004/02/20 06:22:56 steve Exp $" #ident "$Id: design_dump.cc,v 1.148 2004/05/31 23:34:36 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -645,6 +645,13 @@ void NetForever::dump(ostream&o, unsigned ind) const
void NetFuncDef::dump(ostream&o, unsigned ind) const void NetFuncDef::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "function " << scope_->name() << endl; o << setw(ind) << "" << "function " << scope_->name() << endl;
if (result_sig_)
o << setw(ind+2) << "" << "Return signal: "
<< result_sig_->name() << endl;
if (result_var_)
o << setw(ind+2) << "" << "Return variable: "
<< result_var_->basename() << endl;
if (statement_) if (statement_)
statement_->dump(o, ind+2); statement_->dump(o, ind+2);
else else
@ -781,7 +788,10 @@ void NetScope::dump(ostream&o) const
switch (type_) { switch (type_) {
case FUNC: case FUNC:
func_def()->dump(o, 4); if (func_def())
func_def()->dump(o, 4);
else
o << " MISSING FUNCTION DEFINITION" << endl;
break; break;
case TASK: case TASK:
task_def()->dump(o, 4); task_def()->dump(o, 4);
@ -1079,6 +1089,11 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.148 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.147 2004/02/20 06:22:56 steve * Revision 1.147 2004/02/20 06:22:56 steve
* parameter keys are per_strings. * parameter keys are per_strings.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: dup_expr.cc,v 1.16 2003/10/31 02:47:11 steve Exp $" #ident "$Id: dup_expr.cc,v 1.17 2004/05/31 23:34:36 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -109,8 +109,13 @@ NetEUFunc* NetEUFunc::dup_expr() const
tmp_parms[idx] = parms_[idx]->dup_expr(); tmp_parms[idx] = parms_[idx]->dup_expr();
} }
tmp = new NetEUFunc(func_, result_->dup_expr(), tmp_parms); tmp = 0;
if (result_sig_)
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
if (result_var_)
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
assert(tmp);
return tmp; return tmp;
} }
@ -136,6 +141,11 @@ NetEVariable* NetEVariable::dup_expr() const
/* /*
* $Log: dup_expr.cc,v $ * $Log: dup_expr.cc,v $
* Revision 1.17 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.16 2003/10/31 02:47:11 steve * Revision 1.16 2003/10/31 02:47:11 steve
* NetEUReduce has its own dup_expr method. * NetEUReduce has its own dup_expr method.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: elab_expr.cc,v 1.85 2004/03/09 04:29:42 steve Exp $" #ident "$Id: elab_expr.cc,v 1.86 2004/05/31 23:34:36 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -344,20 +344,24 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
dscope, in this case, is the scope of the function, so the dscope, in this case, is the scope of the function, so the
return value is the name within that scope. */ return value is the name within that scope. */
NetNet*res = dscope->find_signal(dscope->basename()); if (NetNet*res = dscope->find_signal(dscope->basename())) {
if (res == 0) { NetESignal*eres = new NetESignal(res);
cerr << get_line() << ": internal error: Unable to locate " NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
"function return value for " << path_ << " in " << return func;
def->name() << "." << endl;
des->errors += 1;
return 0;
} }
assert(res); if (NetVariable*res = dscope->find_variable(dscope->basename())) {
NetESignal*eres = new NetESignal(res); NetEVariable*eres = new NetEVariable(res);
assert(eres); eres->set_line(*res);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms); NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func; return func;
}
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << path_
<< " in " << def->name() << "." << endl;
des->errors += 1;
return 0;
} }
@ -951,6 +955,11 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
/* /*
* $Log: elab_expr.cc,v $ * $Log: elab_expr.cc,v $
* Revision 1.86 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.85 2004/03/09 04:29:42 steve * Revision 1.85 2004/03/09 04:29:42 steve
* Separate out the lookup_sys_func table, for eventual * Separate out the lookup_sys_func table, for eventual
* support for function type tables. * support for function type tables.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: elab_net.cc,v 1.125 2004/02/20 18:53:34 steve Exp $" #ident "$Id: elab_net.cc,v 1.126 2004/05/31 23:34:36 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1062,7 +1062,10 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
/* /*
* This method elaborates a call to a function in the context of a * This method elaborates a call to a function in the context of a
* continuous assignment. * continuous assignment. The definition of the function contains a
* list of the ports, and an output port. The NetEUFunc that I create
* here has a port for all the input ports and the output port. The
* ports are connected by pins.
*/ */
NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope, NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
unsigned width, unsigned width,
@ -1107,6 +1110,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
NetScope*dscope = def->scope(); NetScope*dscope = def->scope();
assert(dscope); assert(dscope);
/* This must be a ufuction that returns a signal. */
assert(def->return_sig());
/* check the validity of the parameters. */ /* check the validity of the parameters. */
if (! check_call_matches_definition_(des, dscope)) if (! check_call_matches_definition_(des, dscope))
return 0; return 0;
@ -1115,9 +1121,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
and collect the resulting NetNet objects. All the and collect the resulting NetNet objects. All the
parameters take on the size of the target port. */ parameters take on the size of the target port. */
svector<NetNet*> eparms (def->port_count()-1); svector<NetNet*> eparms (def->port_count());
for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) { for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
const NetNet* port_reg = def->port(idx+1); const NetNet* port_reg = def->port(idx);
NetNet*tmp = parms_[idx]->elaborate_net(des, scope, NetNet*tmp = parms_[idx]->elaborate_net(des, scope,
port_reg->pin_count(), port_reg->pin_count(),
0, 0, 0, 0, 0, 0,
@ -1148,7 +1154,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
of the function net. */ of the function net. */
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::WIRE,
def->port(0)->pin_count()); def->return_sig()->pin_count());
osig->local_flag(true); osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
@ -1156,7 +1162,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
/* Connect the parameter pins to the parameter expressions. */ /* Connect the parameter pins to the parameter expressions. */
for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) { for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
const NetNet* port = def->port(idx+1); const NetNet* port = def->port(idx);
NetNet*cur = eparms[idx]; NetNet*cur = eparms[idx];
NetNet*tmp = pad_to_width(des, cur, port->pin_count()); NetNet*tmp = pad_to_width(des, cur, port->pin_count());
@ -2426,6 +2432,11 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $Log: elab_net.cc,v $
* Revision 1.126 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.125 2004/02/20 18:53:34 steve * Revision 1.125 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings. * Addtrbute keys are perm_strings.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: elab_sig.cc,v 1.33 2004/02/18 17:11:55 steve Exp $" #ident "$Id: elab_sig.cc,v 1.34 2004/05/31 23:34:37 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -231,7 +231,10 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
} }
/* /*
* A function definition exists within an elaborated module. * A function definition exists within an elaborated module. This
* matters when elaborating signals, as the ports of the function are
* created as signals/variables for each instance of the
* function. That is why PFunction has an elaborate_sig method.
*/ */
void PFunction::elaborate_sig(Design*des, NetScope*scope) const void PFunction::elaborate_sig(Design*des, NetScope*scope) const
{ {
@ -249,21 +252,73 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
des->errors += 1; des->errors += 1;
} }
svector<NetNet*>ports (ports_? ports_->count()+1 : 1); NetNet*ret_sig = 0;
NetVariable*ret_real = 0;
/* Get the reg for the return value. I know the name of the /* Create the signals/variables of the return value and write
reg variable, and I know that it is in this scope, so look them into the function scope. */
it up directly. */ switch (return_type_.type) {
ports[0] = scope->find_signal(scope->basename());
if (ports[0] == 0) { case PTF_REG:
cerr << get_line() << ": internal error: function scope " if (return_type_.range) {
<< scope->name() << " is missing return reg " NetExpr*me = elab_and_eval(des, scope,
<< fname << "." << endl; (*return_type_.range)[0]);
scope->dump(cerr); assert(me);
des->errors += 1; NetExpr*le = elab_and_eval(des, scope,
return; (*return_type_.range)[1]);
assert(le);
long mnum = 0, lnum = 0;
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
mnum = tmp->value().as_long();
} else {
cerr << me->get_line() << ": error: "
"Unable to evaluate constant expression "
<< *me << "." << endl;
des->errors += 1;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
lnum = tmp->value().as_long();
} else {
cerr << le->get_line() << ": error: "
"Unable to evaluate constant expression "
<< *le << "." << endl;
des->errors += 1;
}
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
} else {
ret_sig = new NetNet(scope, fname, NetNet::REG);
}
ret_sig->set_line(*this);
ret_sig->port_type(NetNet::POUTPUT);
break;
case PTF_INTEGER:
ret_sig = new NetNet(scope, fname, NetNet::REG, INTEGER_WIDTH);
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(true);
ret_sig->port_type(NetNet::POUTPUT);
break;
case PTF_REAL:
case PTF_REALTIME:
ret_real = new NetVariable(fname);
ret_real->set_line(*this);
scope->add_variable(ret_real);
break;
default:
cerr << get_line() << ": internal error: I don't know how "
<< "to deal with return type of function "
<< scope->basename() << "." << endl;
} }
svector<NetNet*>ports (ports_? ports_->count() : 0);
if (ports_) if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) { for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
@ -289,14 +344,19 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
<< scope->name() << " is missing port " << scope->name() << " is missing port "
<< pname << "." << endl; << pname << "." << endl;
scope->dump(cerr); scope->dump(cerr);
cerr << get_line() << ": Continuing..." << endl;
des->errors += 1; des->errors += 1;
} }
ports[idx+1] = tmp; ports[idx] = tmp;
} }
NetFuncDef*def = new NetFuncDef(scope, ports); NetFuncDef*def = 0;
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
if (ret_real) def = new NetFuncDef(scope, ret_real, ports);
assert(def);
scope->set_func_def(def); scope->set_func_def(def);
} }
@ -367,6 +427,7 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
*/ */
void PWire::elaborate_sig(Design*des, NetScope*scope) const void PWire::elaborate_sig(Design*des, NetScope*scope) const
{ {
/* The parser may produce hierarchical names for wires. I here /* The parser may produce hierarchical names for wires. I here
follow the scopes down to the base where I actually want to follow the scopes down to the base where I actually want to
elaborate the NetNet object. */ elaborate the NetNet object. */
@ -374,7 +435,13 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
free(tmp_path.remove_tail_name()); free(tmp_path.remove_tail_name());
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) { for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
scope = scope->child(tmp_path.peek_name(idx)); scope = scope->child(tmp_path.peek_name(idx));
assert(scope);
if (scope == 0) {
cerr << get_line() << ": internal error: "
<< "Bad scope component for name "
<< hname_ << endl;
assert(scope);
}
} }
} }
@ -540,6 +607,11 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/* /*
* $Log: elab_sig.cc,v $ * $Log: elab_sig.cc,v $
* Revision 1.34 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.33 2004/02/18 17:11:55 steve * Revision 1.33 2004/02/18 17:11:55 steve
* Use perm_strings for named langiage items. * Use perm_strings for named langiage items.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.301 2004/05/25 03:42:58 steve Exp $" #ident "$Id: elaborate.cc,v 1.302 2004/05/31 23:34:37 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1101,6 +1101,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
assert(rval()); assert(rval());
NetExpr*rv = elab_and_eval(des, scope, rval()); NetExpr*rv = elab_and_eval(des, scope, rval());
if (rv == 0) return 0;
assert(rv); assert(rv);
@ -2313,6 +2314,13 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
void PFunction::elaborate(Design*des, NetScope*scope) const void PFunction::elaborate(Design*des, NetScope*scope) const
{ {
NetFuncDef*def = scope->func_def(); NetFuncDef*def = scope->func_def();
if (def == 0) {
cerr << get_line() << ": internal error: "
<< "No function definition for function "
<< scope->name() << endl;
return;
}
assert(def); assert(def);
NetProc*st = statement_->elaborate(des, scope); NetProc*st = statement_->elaborate(des, scope);
@ -2700,6 +2708,11 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.302 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.301 2004/05/25 03:42:58 steve * Revision 1.301 2004/05/25 03:42:58 steve
* Handle wait with constant-false expression. * Handle wait with constant-false expression.
* *

17
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: emit.cc,v 1.75 2003/09/13 01:30:07 steve Exp $" #ident "$Id: emit.cc,v 1.76 2004/05/31 23:34:37 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -335,17 +335,18 @@ void NetScope::emit_scope(struct target_t*tgt) const
} }
} }
void NetScope::emit_defs(struct target_t*tgt) const bool NetScope::emit_defs(struct target_t*tgt) const
{ {
bool flag = true;
switch (type_) { switch (type_) {
case MODULE: case MODULE:
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_) for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_defs(tgt); flag &= cur->emit_defs(tgt);
break; break;
case FUNC: case FUNC:
tgt->func_def(this); flag &= tgt->func_def(this);
break; break;
case TASK: case TASK:
tgt->task_def(this); tgt->task_def(this);
@ -354,6 +355,7 @@ void NetScope::emit_defs(struct target_t*tgt) const
break; break;
} }
return flag;
} }
void NetWhile::emit_proc_recurse(struct target_t*tgt) const void NetWhile::emit_proc_recurse(struct target_t*tgt) const
@ -388,7 +390,7 @@ bool Design::emit(struct target_t*tgt) const
// emit task and function definitions // emit task and function definitions
for (list<NetScope*>::const_iterator scope = root_scopes_.begin(); for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++) scope != root_scopes_.end(); scope++)
(*scope)->emit_defs(tgt); rc &= (*scope)->emit_defs(tgt);
// emit the processes // emit the processes
@ -509,6 +511,11 @@ bool emit(const Design*des, const char*type)
/* /*
* $Log: emit.cc,v $ * $Log: emit.cc,v $
* Revision 1.76 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.75 2003/09/13 01:30:07 steve * Revision 1.75 2003/09/13 01:30:07 steve
* Missing case warnings. * Missing case warnings.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: net_func.cc,v 1.5 2004/02/18 17:11:56 steve Exp $" #ident "$Id: net_func.cc,v 1.6 2004/05/31 23:34:37 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -28,7 +28,9 @@
static unsigned count_def_pins(const NetFuncDef*def) static unsigned count_def_pins(const NetFuncDef*def)
{ {
unsigned sum = 0; assert(def->return_sig());
unsigned sum = def->return_sig()->pin_count();
for (unsigned idx = 0 ; idx < def->port_count() ; idx += 1) for (unsigned idx = 0 ; idx < def->port_count() ; idx += 1)
sum += def->port(idx)->pin_count(); sum += def->port(idx)->pin_count();
@ -50,7 +52,7 @@ NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d)
unsigned pin_base = port_wid; unsigned pin_base = port_wid;
for (unsigned idx = 1 ; idx < port_count() ; idx += 1) { for (unsigned idx = 1 ; idx < port_count() ; idx += 1) {
const NetNet*port_sig = def->port(idx); const NetNet*port_sig = def->port(idx-1);
unsigned bits = port_width(idx); unsigned bits = port_width(idx);
for (unsigned bit = 0; bit < bits; bit += 1) { for (unsigned bit = 0; bit < bits; bit += 1) {
pin(pin_base+bit).set_dir(Link::INPUT); pin(pin_base+bit).set_dir(Link::INPUT);
@ -69,13 +71,21 @@ NetUserFunc::~NetUserFunc()
unsigned NetUserFunc::port_count() const unsigned NetUserFunc::port_count() const
{ {
return def_->func_def()->port_count(); return def_->func_def()->port_count() + 1;
} }
unsigned NetUserFunc::port_width(unsigned port) const unsigned NetUserFunc::port_width(unsigned port) const
{ {
NetFuncDef*def = def_->func_def(); NetFuncDef*def = def_->func_def();
/* Port 0 is the return port. */
if (port == 0) {
const NetNet*sig = def->return_sig();
assert(sig);
return sig->pin_count();
}
port -= 1;
assert(port < def->port_count()); assert(port < def->port_count());
const NetNet*port_sig = def->port(port); const NetNet*port_sig = def->port(port);
@ -88,6 +98,13 @@ Link& NetUserFunc::port_pin(unsigned port, unsigned idx)
unsigned pin_base = 0; unsigned pin_base = 0;
const NetNet*port_sig; const NetNet*port_sig;
if (port == 0)
return pin(idx);
port_sig = def->return_sig();
pin_base += port_sig->pin_count();
port -= 1;
assert(port < def->port_count()); assert(port < def->port_count());
for (unsigned port_idx = 0 ; port_idx < port ; port_idx += 1) { for (unsigned port_idx = 0 ; port_idx < port ; port_idx += 1) {
@ -133,10 +150,10 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
return false; return false;
} }
if ((parms_count+1) != dscope->func_def()->port_count()) { if (parms_count != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name() cerr << get_line() << ": error: Function " << dscope->name()
<< " expects " << (dscope->func_def()->port_count()-1) << " expects " << (dscope->func_def()->port_count()-1)
<< " parameters, you passed " << parms_count << "." << " arguments, you passed " << parms_count << "."
<< endl; << endl;
des->errors += 1; des->errors += 1;
return false; return false;
@ -147,6 +164,11 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
/* /*
* $Log: net_func.cc,v $ * $Log: net_func.cc,v $
* Revision 1.6 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.5 2004/02/18 17:11:56 steve * Revision 1.5 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items. * Use perm_strings for named langiage items.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.cc,v 1.222 2004/02/20 06:22:56 steve Exp $" #ident "$Id: netlist.cc,v 1.223 2004/05/31 23:34:37 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -237,6 +237,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
switch (t) { switch (t) {
case REG: case REG:
case INTEGER:
case IMPLICIT_REG: case IMPLICIT_REG:
init_value = verinum::Vx; init_value = verinum::Vx;
dir = Link::OUTPUT; dir = Link::OUTPUT;
@ -1658,8 +1659,13 @@ verinum::V NetConst::value(unsigned idx) const
return value_[idx]; return value_[idx];
} }
NetFuncDef::NetFuncDef(NetScope*s, const svector<NetNet*>&po) NetFuncDef::NetFuncDef(NetScope*s, NetNet*result, const svector<NetNet*>&po)
: scope_(s), statement_(0), ports_(po) : scope_(s), statement_(0), result_sig_(result), result_var_(0), ports_(po)
{
}
NetFuncDef::NetFuncDef(NetScope*s, NetVariable*result, const svector<NetNet*>&po)
: scope_(s), statement_(0), result_sig_(0), result_var_(result), ports_(po)
{ {
} }
@ -1700,6 +1706,16 @@ const NetNet* NetFuncDef::port(unsigned idx) const
return ports_[idx]; return ports_[idx];
} }
const NetNet* NetFuncDef::return_sig() const
{
return result_sig_;
}
const NetVariable* NetFuncDef::return_var() const
{
return result_var_;
}
NetSTask::NetSTask(const char*na, const svector<NetExpr*>&pa) NetSTask::NetSTask(const char*na, const svector<NetExpr*>&pa)
: name_(0), parms_(pa) : name_(0), parms_(pa)
{ {
@ -1731,9 +1747,14 @@ const NetExpr* NetSTask::parm(unsigned idx) const
} }
NetEUFunc::NetEUFunc(NetScope*def, NetESignal*res, svector<NetExpr*>&p) NetEUFunc::NetEUFunc(NetScope*def, NetESignal*res, svector<NetExpr*>&p)
: func_(def), result_(res), parms_(p) : func_(def), result_sig_(res), result_var_(0), parms_(p)
{
expr_width(result_sig_->expr_width());
}
NetEUFunc::NetEUFunc(NetScope*def, NetEVariable*res, svector<NetExpr*>&p)
: func_(def), result_sig_(0), result_var_(res), parms_(p)
{ {
expr_width(result_->expr_width());
} }
NetEUFunc::~NetEUFunc() NetEUFunc::~NetEUFunc()
@ -1747,9 +1768,14 @@ const string NetEUFunc::name() const
return func_->name(); return func_->name();
} }
const NetESignal*NetEUFunc::result() const const NetESignal*NetEUFunc::result_sig() const
{ {
return result_; return result_sig_;
}
const NetEVariable*NetEUFunc::result_var() const
{
return result_var_;
} }
unsigned NetEUFunc::parm_count() const unsigned NetEUFunc::parm_count() const
@ -1768,6 +1794,16 @@ const NetScope* NetEUFunc::func() const
return func_; return func_;
} }
NetExpr::TYPE NetEUFunc::expr_type() const
{
if (result_sig_)
return result_sig_->expr_type();
if (result_var_)
return result_var_->expr_type();
return ET_VOID;
}
NetUTask::NetUTask(NetScope*def) NetUTask::NetUTask(NetScope*def)
: task_(def) : task_(def)
{ {
@ -2218,6 +2254,11 @@ const NetProc*NetTaskDef::proc() const
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.223 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.222 2004/02/20 06:22:56 steve * Revision 1.222 2004/02/20 06:22:56 steve
* parameter keys are per_strings. * parameter keys are per_strings.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.311 2004/02/20 06:22:57 steve Exp $" #ident "$Id: netlist.h,v 1.312 2004/05/31 23:34:38 steve Exp $"
#endif #endif
/* /*
@ -57,6 +57,7 @@ class NetVariable;
class NetEvProbe; class NetEvProbe;
class NetExpr; class NetExpr;
class NetESignal; class NetESignal;
class NetEVariable;
class NetFuncDef; class NetFuncDef;
@ -1996,7 +1997,8 @@ class NetForever : public NetProc {
class NetFuncDef { class NetFuncDef {
public: public:
NetFuncDef(NetScope*, const svector<NetNet*>&po); NetFuncDef(NetScope*, NetNet*result, const svector<NetNet*>&po);
NetFuncDef(NetScope*, NetVariable*result, const svector<NetNet*>&po);
~NetFuncDef(); ~NetFuncDef();
void set_proc(NetProc*st); void set_proc(NetProc*st);
@ -2008,11 +2010,16 @@ class NetFuncDef {
unsigned port_count() const; unsigned port_count() const;
const NetNet*port(unsigned idx) const; const NetNet*port(unsigned idx) const;
const NetNet*return_sig() const;
const NetVariable*return_var() const;
void dump(ostream&, unsigned ind) const; void dump(ostream&, unsigned ind) const;
private: private:
NetScope*scope_; NetScope*scope_;
NetProc*statement_; NetProc*statement_;
NetNet*result_sig_;
NetVariable*result_var_;
svector<NetNet*>ports_; svector<NetNet*>ports_;
}; };
@ -2205,18 +2212,22 @@ class NetVariable : public LineInfo {
class NetEUFunc : public NetExpr { class NetEUFunc : public NetExpr {
public: public:
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&); NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
NetEUFunc(NetScope*, NetEVariable*, svector<NetExpr*>&);
~NetEUFunc(); ~NetEUFunc();
const string name() const; const string name() const;
const NetESignal*result() const; const NetESignal*result_sig() const;
const NetEVariable*result_var() const;
unsigned parm_count() const; unsigned parm_count() const;
const NetExpr* parm(unsigned idx) const; const NetExpr* parm(unsigned idx) const;
const NetScope* func() const; const NetScope* func() const;
virtual bool set_width(unsigned); virtual bool set_width(unsigned);
virtual TYPE expr_type() const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
@ -2225,7 +2236,8 @@ class NetEUFunc : public NetExpr {
private: private:
NetScope*func_; NetScope*func_;
NetESignal*result_; NetESignal*result_sig_;
NetEVariable*result_var_;
svector<NetExpr*> parms_; svector<NetExpr*> parms_;
private: // not implemented private: // not implemented
@ -3103,7 +3115,7 @@ class NetScope : public Attrib {
void dump(ostream&) const; void dump(ostream&) const;
void emit_scope(struct target_t*tgt) const; void emit_scope(struct target_t*tgt) const;
void emit_defs(struct target_t*tgt) const; bool emit_defs(struct target_t*tgt) const;
/* This method runs the functor on me. Recurse through the /* This method runs the functor on me. Recurse through the
children of this node as well. */ children of this node as well. */
@ -3315,6 +3327,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.312 2004/05/31 23:34:38 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.311 2004/02/20 06:22:57 steve * Revision 1.311 2004/02/20 06:22:57 steve
* parameter keys are per_strings. * parameter keys are per_strings.
* *

30
parse.y
View File

@ -1,7 +1,7 @@
%{ %{
/* /*
* Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2004 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: parse.y,v 1.195 2004/05/25 19:21:06 steve Exp $" #ident "$Id: parse.y,v 1.196 2004/05/31 23:34:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -114,7 +114,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
Statement*statement; Statement*statement;
svector<Statement*>*statement_list; svector<Statement*>*statement_list;
struct { svector<PExpr*>*range; NetNet::Type ntype; } range_type; PTaskFuncArg function_type;
struct { svector<PExpr*>*range; svector<PExpr*>*delay; } range_delay; struct { svector<PExpr*>*range; svector<PExpr*>*delay; } range_delay;
net_decl_assign_t*net_decl_assign; net_decl_assign_t*net_decl_assign;
@ -204,7 +204,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
%type <porttype> port_type %type <porttype> port_type
%type <parmvalue> parameter_value_opt %type <parmvalue> parameter_value_opt
%type <range_type> range_or_type_opt %type <function_type> function_range_or_type_opt
%type <event_expr> event_expression_list %type <event_expr> event_expression_list
%type <event_expr> event_expression %type <event_expr> event_expression
%type <event_statement> event_control %type <event_statement> event_control
@ -1667,16 +1667,18 @@ module_item
definitions in the func_body to take on the scope of the function definitions in the func_body to take on the scope of the function
instead of the module. */ instead of the module. */
| K_function range_or_type_opt IDENTIFIER ';' | K_function function_range_or_type_opt IDENTIFIER ';'
{ pform_push_scope($3); } { pform_push_scope($3); }
function_item_list statement function_item_list statement
K_endfunction K_endfunction
{ PFunction *tmp = new PFunction; { perm_string name = lex_strings.make($3);
PFunction *tmp = new PFunction(name);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
tmp->set_ports($6); tmp->set_ports($6);
tmp->set_statement($7); tmp->set_statement($7);
pform_set_function($3, $2.ntype, $2.range, tmp); tmp->set_return($2);
pform_set_function(name, tmp);
pform_pop_scope(); pform_pop_scope();
delete $3; delete $3;
} }
@ -2155,13 +2157,13 @@ range_opt
; ;
/* This is used to express the return type of a function. */ /* This is used to express the return type of a function. */
range_or_type_opt function_range_or_type_opt
: range { $$.range = $1; $$.ntype = NetNet::REG; } : range { $$.range = $1; $$.type = PTF_REG; }
| K_integer { $$.range = 0; $$.ntype = NetNet::INTEGER; } | K_integer { $$.range = 0; $$.type = PTF_INTEGER; }
| K_real { $$.range = 0; $$.ntype = NetNet::IMPLICIT; } | K_real { $$.range = 0; $$.type = PTF_REAL; }
| K_realtime { $$.range = 0; $$.ntype = NetNet::IMPLICIT; } | K_realtime { $$.range = 0; $$.type = PTF_REALTIME; }
| K_time { $$.range = 0; $$.ntype = NetNet::IMPLICIT; } | K_time { $$.range = 0; $$.type = PTF_TIME; }
| { $$.range = 0; $$.ntype = NetNet::IMPLICIT; } | { $$.range = 0; $$.type = PTF_REG; }
; ;
/* The register_variable rule is matched only when I am parsing /* The register_variable rule is matched only when I am parsing

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: pform.cc,v 1.125 2004/05/25 19:21:07 steve Exp $" #ident "$Id: pform.cc,v 1.126 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1302,42 +1302,10 @@ void pform_set_task(perm_string name, PTask*task)
pform_cur_module->add_task(name, task); pform_cur_module->add_task(name, task);
} }
/*
* This function is called to fill out the definition of the function void pform_set_function(perm_string name, PFunction*func)
* with the trappings that are discovered after the basic function
* name is parsed.
*/
void pform_set_function(const char*name, NetNet::Type ntype,
svector<PExpr*>*ra, PFunction *func)
{ {
if (ntype == NetNet::IMPLICIT) pform_cur_module->add_function(name, func);
ntype = NetNet::REG;
/* Form into path_return a hierarchical name for the synthetic
return value for the function. The return value is the same
name as the function, so if the function name is "foo", the
wire is "foo.foo". */
hname_t path_return (name);
path_return.append(name);
PWire*out = new PWire(path_return, ntype, NetNet::POUTPUT);
if (ra) {
assert(ra->count() == 2);
out->set_range((*ra)[0], (*ra)[1]);
delete ra;
}
/* If the return type of the function is INTEGER, then
generate a range for it. */
if (ntype == NetNet::INTEGER) {
out->set_signed(true);
out->set_range(new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)),
new PENumber(new verinum(0UL, INTEGER_WIDTH)));
}
pform_cur_module->add_wire(out);
func->set_output(out);
pform_cur_module->add_function(lex_strings.make(name), func);
} }
void pform_set_attrib(perm_string name, perm_string key, char*value) void pform_set_attrib(perm_string name, perm_string key, char*value)
@ -1598,6 +1566,11 @@ int pform_parse(const char*path, FILE*file)
/* /*
* $Log: pform.cc,v $ * $Log: pform.cc,v $
* Revision 1.126 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.125 2004/05/25 19:21:07 steve * Revision 1.125 2004/05/25 19:21:07 steve
* More identifier lists use perm_strings. * More identifier lists use perm_strings.
* *

10
pform.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: pform.h,v 1.78 2004/05/25 19:21:07 steve Exp $" #ident "$Id: pform.h,v 1.79 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -203,8 +203,7 @@ extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r);
extern void pform_set_reg_integer(list<perm_string>*names); extern void pform_set_reg_integer(list<perm_string>*names);
extern void pform_set_reg_time(list<perm_string>*names); extern void pform_set_reg_time(list<perm_string>*names);
extern void pform_set_task(perm_string name, PTask*); extern void pform_set_task(perm_string name, PTask*);
extern void pform_set_function(const char*, NetNet::Type, extern void pform_set_function(perm_string name, PFunction*);
svector<PExpr*>*, PFunction*);
/* pform_set_attrib and pform_set_type_attrib exist to support the /* pform_set_attrib and pform_set_type_attrib exist to support the
$attribute syntax, which can only set string values to $attribute syntax, which can only set string values to
@ -291,6 +290,11 @@ extern void pform_dump(ostream&out, Module*mod);
/* /*
* $Log: pform.h,v $ * $Log: pform.h,v $
* Revision 1.79 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.78 2004/05/25 19:21:07 steve * Revision 1.78 2004/05/25 19:21:07 steve
* More identifier lists use perm_strings. * More identifier lists use perm_strings.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: pform_dump.cc,v 1.86 2004/05/25 19:21:07 steve Exp $" #ident "$Id: pform_dump.cc,v 1.87 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -600,7 +600,35 @@ void PForStatement::dump(ostream&out, unsigned ind) const
void PFunction::dump(ostream&out, unsigned ind) const void PFunction::dump(ostream&out, unsigned ind) const
{ {
out << setw(ind) << "" << "output " << out_->path() << ";" << endl; out << setw(ind) << "" << "function ";
switch (return_type_.type) {
case PTF_NONE:
out << "?none? ";
break;
case PTF_REG:
out << "reg ";
break;
case PTF_INTEGER:
out << "integer ";
break;
case PTF_REAL:
out << "real ";
break;
case PTF_REALTIME:
out << "realtime ";
break;
case PTF_TIME:
out << "time ";
break;
}
if (return_type_.range) {
out << "[";
out << "] ";
}
out << name_ << ";" << endl;
if (ports_) if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) { for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
out << setw(ind) << ""; out << setw(ind) << "";
@ -881,6 +909,11 @@ void PUdp::dump(ostream&out) const
/* /*
* $Log: pform_dump.cc,v $ * $Log: pform_dump.cc,v $
* Revision 1.87 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.86 2004/05/25 19:21:07 steve * Revision 1.86 2004/05/25 19:21:07 steve
* More identifier lists use perm_strings. * More identifier lists use perm_strings.
* *

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-proc.cc,v 1.63 2004/05/19 03:18:40 steve Exp $" #ident "$Id: t-dll-proc.cc,v 1.64 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -99,7 +99,7 @@ void dll_target::task_def(const NetScope*net)
} }
void dll_target::func_def(const NetScope*net) bool dll_target::func_def(const NetScope*net)
{ {
ivl_scope_t scope = lookup_scope_(net); ivl_scope_t scope = lookup_scope_(net);
const NetFuncDef*def = net->func_def(); const NetFuncDef*def = net->func_def();
@ -113,12 +113,35 @@ void dll_target::func_def(const NetScope*net)
scope->def = stmt_cur_; scope->def = stmt_cur_;
stmt_cur_ = 0; stmt_cur_ = 0;
scope->ports = def->port_count(); scope->ports = def->port_count() + 1;
if (scope->ports > 0) { if (scope->ports > 0) {
scope->port = new ivl_signal_t[scope->ports]; scope->port = new ivl_signal_t[scope->ports];
for (unsigned idx = 0 ; idx < scope->ports ; idx += 1) for (unsigned idx = 1 ; idx < scope->ports ; idx += 1)
scope->port[idx] = find_signal(des_, def->port(idx)); scope->port[idx] = find_signal(des_, def->port(idx-1));
} }
/* FIXME: the ivl_target API expects port-0 to be the output
port. This assumes that the return value is a signal, which
is *not* correct. Someday, I'm going to have to change
this, but that will break code generators that use this
result. */
if (const NetNet*ret_sig = def->return_sig()) {
scope->port[0] = find_signal(des_, ret_sig);
return true;
}
if (const NetVariable*ret_var = def->return_var()) {
cerr << ret_var->get_line() << ": internal error: "
<< "Function " << net->name() << " has an unsupported "
<< "return type." << endl;
return false;
}
cerr << "?:0" << ": internal error: "
<< "Function " << net->name() << " has a return type"
<< " that I do not understand." << endl;
return false;
} }
/* /*
@ -849,6 +872,11 @@ void dll_target::proc_while(const NetWhile*net)
/* /*
* $Log: t-dll-proc.cc,v $ * $Log: t-dll-proc.cc,v $
* Revision 1.64 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.63 2004/05/19 03:18:40 steve * Revision 1.63 2004/05/19 03:18:40 steve
* Add ivl_target support for non-blocking assign of real. * Add ivl_target support for non-blocking assign of real.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.h,v 1.112 2004/02/20 06:22:58 steve Exp $" #ident "$Id: t-dll.h,v 1.113 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "target.h" # include "target.h"
@ -123,7 +123,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool proc_wait(const NetEvWait*); bool proc_wait(const NetEvWait*);
void proc_while(const NetWhile*); void proc_while(const NetWhile*);
void func_def(const NetScope*); bool func_def(const NetScope*);
void task_def(const NetScope*); void task_def(const NetScope*);
struct ivl_expr_s*expr_; struct ivl_expr_s*expr_;
@ -683,6 +683,11 @@ struct ivl_variable_s {
/* /*
* $Log: t-dll.h,v $ * $Log: t-dll.h,v $
* Revision 1.113 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.112 2004/02/20 06:22:58 steve * Revision 1.112 2004/02/20 06:22:58 steve
* parameter keys are per_strings. * parameter keys are per_strings.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: target.cc,v 1.68 2003/05/30 02:55:32 steve Exp $" #ident "$Id: target.cc,v 1.69 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -53,10 +53,11 @@ void target_t::variable(const NetVariable*that)
<< "): Unhandled variable <" << that->basename() << ">." << endl; << "): Unhandled variable <" << that->basename() << ">." << endl;
} }
void target_t::func_def(const NetScope*) bool target_t::func_def(const NetScope*)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
"Unhandled function definition." << endl; "Unhandled function definition." << endl;
return false;
} }
void target_t::task_def(const NetScope*) void target_t::task_def(const NetScope*)
@ -419,6 +420,11 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/* /*
* $Log: target.cc,v $ * $Log: target.cc,v $
* Revision 1.69 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.68 2003/05/30 02:55:32 steve * Revision 1.68 2003/05/30 02:55:32 steve
* Support parameters in real expressions and * Support parameters in real expressions and
* as real expressions, and fix multiply and * as real expressions, and fix multiply and

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: target.h,v 1.64 2003/05/30 02:55:32 steve Exp $" #ident "$Id: target.h,v 1.65 2004/05/31 23:34:39 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -73,7 +73,7 @@ struct target_t {
/* Output a defined task. */ /* Output a defined task. */
virtual void task_def(const NetScope*); virtual void task_def(const NetScope*);
virtual void func_def(const NetScope*); virtual bool func_def(const NetScope*);
/* LPM style components are handled here. */ /* LPM style components are handled here. */
virtual void lpm_add_sub(const NetAddSub*); virtual void lpm_add_sub(const NetAddSub*);
@ -170,6 +170,11 @@ extern const struct target *target_table[];
/* /*
* $Log: target.h,v $ * $Log: target.h,v $
* Revision 1.65 2004/05/31 23:34:39 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.64 2003/05/30 02:55:32 steve * Revision 1.64 2003/05/30 02:55:32 steve
* Support parameters in real expressions and * Support parameters in real expressions and
* as real expressions, and fix multiply and * as real expressions, and fix multiply and