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
*/
#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
# include "config.h"
#include "PTask.h"
PFunction::PFunction()
: out_(0), ports_(0), statement_(0)
PFunction::PFunction(perm_string name)
: name_(name), ports_(0), statement_(0)
{
return_type_.type = PTF_NONE;
}
PFunction::~PFunction()
@ -46,14 +47,18 @@ void PFunction::set_statement(Statement*s)
statement_ = s;
}
void PFunction::set_output(PWire*o)
void PFunction::set_return(PTaskFuncArg t)
{
assert(out_ == 0);
out_ = o;
return_type_ = t;
}
/*
* $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
* 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
*/
#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
# include "LineInfo.h"
# include "svector.h"
# include "StringHeap.h"
# include <string>
class Design;
class NetScope;
class PWire;
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.
@ -69,16 +85,18 @@ class PTask : public LineInfo {
* 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
* function return value.
*
* The output value is not elaborated until elaborate_sig.
*/
class PFunction : public LineInfo {
public:
explicit PFunction();
explicit PFunction(perm_string name);
~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
void set_output(PWire*);
void set_return(PTaskFuncArg t);
void elaborate_scope(Design*des, NetScope*scope) const;
@ -91,13 +109,19 @@ class PFunction : public LineInfo {
void dump(ostream&, unsigned) const;
private:
PWire*out_;
perm_string name_;
PTaskFuncArg return_type_;
svector<PWire *> *ports_;
Statement *statement_;
};
/*
* $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
* conditional ident string using autoconfig.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -645,6 +645,13 @@ void NetForever::dump(ostream&o, unsigned ind) const
void NetFuncDef::dump(ostream&o, unsigned ind) const
{
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_)
statement_->dump(o, ind+2);
else
@ -781,7 +788,10 @@ void NetScope::dump(ostream&o) const
switch (type_) {
case FUNC:
func_def()->dump(o, 4);
if (func_def())
func_def()->dump(o, 4);
else
o << " MISSING FUNCTION DEFINITION" << endl;
break;
case TASK:
task_def()->dump(o, 4);
@ -1079,6 +1089,11 @@ void Design::dump(ostream&o) const
/*
* $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
* parameter keys are per_strings.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -109,8 +109,13 @@ NetEUFunc* NetEUFunc::dup_expr() const
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;
}
@ -136,6 +141,11 @@ NetEVariable* NetEVariable::dup_expr() const
/*
* $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
* 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
*/
#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
# 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
return value is the name within that scope. */
NetNet*res = dscope->find_signal(dscope->basename());
if (res == 0) {
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << path_ << " in " <<
def->name() << "." << endl;
des->errors += 1;
return 0;
if (NetNet*res = dscope->find_signal(dscope->basename())) {
NetESignal*eres = new NetESignal(res);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func;
}
assert(res);
NetESignal*eres = new NetESignal(res);
assert(eres);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func;
if (NetVariable*res = dscope->find_variable(dscope->basename())) {
NetEVariable*eres = new NetEVariable(res);
eres->set_line(*res);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
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 $
* 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
* Separate out the lookup_sys_func table, for eventual
* support for function type tables.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# 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
* 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,
unsigned width,
@ -1107,6 +1110,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
NetScope*dscope = def->scope();
assert(dscope);
/* This must be a ufuction that returns a signal. */
assert(def->return_sig());
/* check the validity of the parameters. */
if (! check_call_matches_definition_(des, dscope))
return 0;
@ -1115,9 +1121,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
and collect the resulting NetNet objects. All the
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) {
const NetNet* port_reg = def->port(idx+1);
const NetNet* port_reg = def->port(idx);
NetNet*tmp = parms_[idx]->elaborate_net(des, scope,
port_reg->pin_count(),
0, 0, 0,
@ -1148,7 +1154,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
of the function net. */
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE,
def->port(0)->pin_count());
def->return_sig()->pin_count());
osig->local_flag(true);
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. */
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*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 $
* 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
* 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
* 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
*/
#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
# 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
{
@ -249,21 +252,73 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
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
reg variable, and I know that it is in this scope, so look
it up directly. */
ports[0] = scope->find_signal(scope->basename());
if (ports[0] == 0) {
cerr << get_line() << ": internal error: function scope "
<< scope->name() << " is missing return reg "
<< fname << "." << endl;
scope->dump(cerr);
des->errors += 1;
return;
/* Create the signals/variables of the return value and write
them into the function scope. */
switch (return_type_.type) {
case PTF_REG:
if (return_type_.range) {
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0]);
assert(me);
NetExpr*le = elab_and_eval(des, scope,
(*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_)
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 "
<< pname << "." << endl;
scope->dump(cerr);
cerr << get_line() << ": Continuing..." << endl;
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);
}
@ -367,6 +427,7 @@ bool PGate::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
follow the scopes down to the base where I actually want to
elaborate the NetNet object. */
@ -374,7 +435,13 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
free(tmp_path.remove_tail_name());
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
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 $
* 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
* 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
*/
#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
# include "config.h"
@ -1101,6 +1101,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
assert(rval());
NetExpr*rv = elab_and_eval(des, scope, rval());
if (rv == 0) return 0;
assert(rv);
@ -2313,6 +2314,13 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
void PFunction::elaborate(Design*des, NetScope*scope) const
{
NetFuncDef*def = scope->func_def();
if (def == 0) {
cerr << get_line() << ": internal error: "
<< "No function definition for function "
<< scope->name() << endl;
return;
}
assert(def);
NetProc*st = statement_->elaborate(des, scope);
@ -2700,6 +2708,11 @@ Design* elaborate(list<perm_string>roots)
/*
* $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
* 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
*/
#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
# 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_) {
case MODULE:
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_defs(tgt);
flag &= cur->emit_defs(tgt);
break;
case FUNC:
tgt->func_def(this);
flag &= tgt->func_def(this);
break;
case TASK:
tgt->task_def(this);
@ -354,6 +355,7 @@ void NetScope::emit_defs(struct target_t*tgt) const
break;
}
return flag;
}
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
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_defs(tgt);
rc &= (*scope)->emit_defs(tgt);
// emit the processes
@ -509,6 +511,11 @@ bool emit(const Design*des, const char*type)
/*
* $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
* 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
* 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
*/
#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
# include "config.h"
@ -28,7 +28,9 @@
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)
sum += def->port(idx)->pin_count();
@ -50,7 +52,7 @@ NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d)
unsigned pin_base = port_wid;
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);
for (unsigned bit = 0; bit < bits; bit += 1) {
pin(pin_base+bit).set_dir(Link::INPUT);
@ -69,13 +71,21 @@ NetUserFunc::~NetUserFunc()
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
{
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());
const NetNet*port_sig = def->port(port);
@ -88,6 +98,13 @@ Link& NetUserFunc::port_pin(unsigned port, unsigned idx)
unsigned pin_base = 0;
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());
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;
}
if ((parms_count+1) != dscope->func_def()->port_count()) {
if (parms_count != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name()
<< " expects " << (dscope->func_def()->port_count()-1)
<< " parameters, you passed " << parms_count << "."
<< " arguments, you passed " << parms_count << "."
<< endl;
des->errors += 1;
return false;
@ -147,6 +164,11 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
/*
* $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
* 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
*/
#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
# include "config.h"
@ -237,6 +237,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
switch (t) {
case REG:
case INTEGER:
case IMPLICIT_REG:
init_value = verinum::Vx;
dir = Link::OUTPUT;
@ -1658,8 +1659,13 @@ verinum::V NetConst::value(unsigned idx) const
return value_[idx];
}
NetFuncDef::NetFuncDef(NetScope*s, const svector<NetNet*>&po)
: scope_(s), statement_(0), ports_(po)
NetFuncDef::NetFuncDef(NetScope*s, NetNet*result, const svector<NetNet*>&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];
}
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)
: name_(0), parms_(pa)
{
@ -1731,9 +1747,14 @@ const NetExpr* NetSTask::parm(unsigned idx) const
}
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()
@ -1747,9 +1768,14 @@ const string NetEUFunc::name() const
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
@ -1768,6 +1794,16 @@ const NetScope* NetEUFunc::func() const
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)
: task_(def)
{
@ -2218,6 +2254,11 @@ const NetProc*NetTaskDef::proc() const
/*
* $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
* parameter keys are per_strings.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
/*
@ -57,6 +57,7 @@ class NetVariable;
class NetEvProbe;
class NetExpr;
class NetESignal;
class NetEVariable;
class NetFuncDef;
@ -1996,7 +1997,8 @@ class NetForever : public NetProc {
class NetFuncDef {
public:
NetFuncDef(NetScope*, const svector<NetNet*>&po);
NetFuncDef(NetScope*, NetNet*result, const svector<NetNet*>&po);
NetFuncDef(NetScope*, NetVariable*result, const svector<NetNet*>&po);
~NetFuncDef();
void set_proc(NetProc*st);
@ -2008,11 +2010,16 @@ class NetFuncDef {
unsigned port_count() const;
const NetNet*port(unsigned idx) const;
const NetNet*return_sig() const;
const NetVariable*return_var() const;
void dump(ostream&, unsigned ind) const;
private:
NetScope*scope_;
NetProc*statement_;
NetNet*result_sig_;
NetVariable*result_var_;
svector<NetNet*>ports_;
};
@ -2205,18 +2212,22 @@ class NetVariable : public LineInfo {
class NetEUFunc : public NetExpr {
public:
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
NetEUFunc(NetScope*, NetEVariable*, svector<NetExpr*>&);
~NetEUFunc();
const string name() const;
const NetESignal*result() const;
const NetESignal*result_sig() const;
const NetEVariable*result_var() const;
unsigned parm_count() const;
const NetExpr* parm(unsigned idx) const;
const NetScope* func() const;
virtual bool set_width(unsigned);
virtual TYPE expr_type() const;
virtual void dump(ostream&) const;
virtual void expr_scan(struct expr_scan_t*) const;
@ -2225,7 +2236,8 @@ class NetEUFunc : public NetExpr {
private:
NetScope*func_;
NetESignal*result_;
NetESignal*result_sig_;
NetEVariable*result_var_;
svector<NetExpr*> parms_;
private: // not implemented
@ -3103,7 +3115,7 @@ class NetScope : public Attrib {
void dump(ostream&) 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
children of this node as well. */
@ -3315,6 +3327,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $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
* 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
* 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
*/
#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
# include "config.h"
@ -114,7 +114,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
Statement*statement;
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;
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 <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
%type <event_statement> event_control
@ -1667,16 +1667,18 @@ module_item
definitions in the func_body to take on the scope of the function
instead of the module. */
| K_function range_or_type_opt IDENTIFIER ';'
| K_function function_range_or_type_opt IDENTIFIER ';'
{ pform_push_scope($3); }
function_item_list statement
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_lineno(@1.first_line);
tmp->set_ports($6);
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();
delete $3;
}
@ -2155,13 +2157,13 @@ range_opt
;
/* This is used to express the return type of a function. */
range_or_type_opt
: range { $$.range = $1; $$.ntype = NetNet::REG; }
| K_integer { $$.range = 0; $$.ntype = NetNet::INTEGER; }
| K_real { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
| K_realtime { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
| K_time { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
| { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
function_range_or_type_opt
: range { $$.range = $1; $$.type = PTF_REG; }
| K_integer { $$.range = 0; $$.type = PTF_INTEGER; }
| K_real { $$.range = 0; $$.type = PTF_REAL; }
| K_realtime { $$.range = 0; $$.type = PTF_REALTIME; }
| K_time { $$.range = 0; $$.type = PTF_TIME; }
| { $$.range = 0; $$.type = PTF_REG; }
;
/* 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
*/
#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
# include "config.h"
@ -1302,42 +1302,10 @@ void pform_set_task(perm_string name, PTask*task)
pform_cur_module->add_task(name, task);
}
/*
* This function is called to fill out the definition of the function
* 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)
void pform_set_function(perm_string name, PFunction*func)
{
if (ntype == NetNet::IMPLICIT)
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);
pform_cur_module->add_function(name, func);
}
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 $
* 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
* 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
*/
#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
# 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_time(list<perm_string>*names);
extern void pform_set_task(perm_string name, PTask*);
extern void pform_set_function(const char*, NetNet::Type,
svector<PExpr*>*, PFunction*);
extern void pform_set_function(perm_string name, PFunction*);
/* pform_set_attrib and pform_set_type_attrib exist to support the
$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 $
* 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
* More identifier lists use perm_strings.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -600,7 +600,35 @@ void PForStatement::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_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
out << setw(ind) << "";
@ -881,6 +909,11 @@ void PUdp::dump(ostream&out) const
/*
* $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
* More identifier lists use perm_strings.
*

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# 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);
const NetFuncDef*def = net->func_def();
@ -113,12 +113,35 @@ void dll_target::func_def(const NetScope*net)
scope->def = stmt_cur_;
stmt_cur_ = 0;
scope->ports = def->port_count();
scope->ports = def->port_count() + 1;
if (scope->ports > 0) {
scope->port = new ivl_signal_t[scope->ports];
for (unsigned idx = 0 ; idx < scope->ports ; idx += 1)
scope->port[idx] = find_signal(des_, def->port(idx));
for (unsigned idx = 1 ; idx < scope->ports ; idx += 1)
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 $
* 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
* 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
*/
#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
# include "target.h"
@ -123,7 +123,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool proc_wait(const NetEvWait*);
void proc_while(const NetWhile*);
void func_def(const NetScope*);
bool func_def(const NetScope*);
void task_def(const NetScope*);
struct ivl_expr_s*expr_;
@ -683,6 +683,11 @@ struct ivl_variable_s {
/*
* $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
* parameter keys are per_strings.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -53,10 +53,11 @@ void target_t::variable(const NetVariable*that)
<< "): Unhandled variable <" << that->basename() << ">." << endl;
}
void target_t::func_def(const NetScope*)
bool target_t::func_def(const NetScope*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled function definition." << endl;
return false;
}
void target_t::task_def(const NetScope*)
@ -419,6 +420,11 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $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
* Support parameters in real expressions 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
*/
#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
# include "netlist.h"
@ -73,7 +73,7 @@ struct target_t {
/* Output a defined task. */
virtual void task_def(const NetScope*);
virtual void func_def(const NetScope*);
virtual bool func_def(const NetScope*);
/* LPM style components are handled here. */
virtual void lpm_add_sub(const NetAddSub*);
@ -170,6 +170,11 @@ extern const struct target *target_table[];
/*
* $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
* Support parameters in real expressions and
* as real expressions, and fix multiply and