Rewire/generalize parsing an elaboration of
function return values to allow for better speed and more type support.
This commit is contained in:
parent
e7fa56981a
commit
5472b27e1f
17
PFunction.cc
17
PFunction.cc
|
|
@ -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
32
PTask.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
14
dup_expr.cc
14
dup_expr.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
35
elab_expr.cc
35
elab_expr.cc
|
|
@ -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.
|
||||
|
|
|
|||
23
elab_net.cc
23
elab_net.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
108
elab_sig.cc
108
elab_sig.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
15
elaborate.cc
15
elaborate.cc
|
|
@ -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
17
emit.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
36
net_func.cc
36
net_func.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
55
netlist.cc
55
netlist.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
29
netlist.h
29
netlist.h
|
|
@ -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
30
parse.y
|
|
@ -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
|
||||
|
|
|
|||
45
pform.cc
45
pform.cc
|
|
@ -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
10
pform.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
9
t-dll.h
9
t-dll.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
10
target.cc
10
target.cc
|
|
@ -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
|
||||
|
|
|
|||
9
target.h
9
target.h
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue