Handle recursive functions and arbitrary function
references to other functions, properly pass function parameters and save function results.
This commit is contained in:
parent
5ee83fce70
commit
9f7eb4a935
12
PTask.h
12
PTask.h
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: PTask.h,v 1.4 1999/08/25 22:22:41 steve Exp $"
|
#ident "$Id: PTask.h,v 1.5 1999/09/01 20:46:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
|
@ -63,7 +63,10 @@ class PFunction : public LineInfo {
|
||||||
|
|
||||||
void set_output(PWire*);
|
void set_output(PWire*);
|
||||||
|
|
||||||
virtual void elaborate(Design *des, const string &path) const;
|
/* Functions are elaborated in 2 passes. */
|
||||||
|
virtual void elaborate_1(Design *des, const string &path) const;
|
||||||
|
virtual void elaborate_2(Design *des, const string &path) const;
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -74,6 +77,11 @@ class PFunction : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PTask.h,v $
|
* $Log: PTask.h,v $
|
||||||
|
* Revision 1.5 1999/09/01 20:46:19 steve
|
||||||
|
* Handle recursive functions and arbitrary function
|
||||||
|
* references to other functions, properly pass
|
||||||
|
* function parameters and save function results.
|
||||||
|
*
|
||||||
* Revision 1.4 1999/08/25 22:22:41 steve
|
* Revision 1.4 1999/08/25 22:22:41 steve
|
||||||
* elaborate some aspects of functions.
|
* elaborate some aspects of functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: design_dump.cc,v 1.36 1999/08/31 22:38:29 steve Exp $"
|
#ident "$Id: design_dump.cc,v 1.37 1999/09/01 20:46:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -427,7 +427,10 @@ 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 " << name_ << endl;
|
o << setw(ind) << "" << "function " << name_ << endl;
|
||||||
statement_->dump(o, ind+2);
|
if (statement_)
|
||||||
|
statement_->dump(o, ind+2);
|
||||||
|
else
|
||||||
|
o << setw(ind+2) << "" << "// NO STATEMENT" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetPDelay::dump(ostream&o, unsigned ind) const
|
void NetPDelay::dump(ostream&o, unsigned ind) const
|
||||||
|
|
@ -719,6 +722,11 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $Log: design_dump.cc,v $
|
||||||
|
* Revision 1.37 1999/09/01 20:46:19 steve
|
||||||
|
* Handle recursive functions and arbitrary function
|
||||||
|
* references to other functions, properly pass
|
||||||
|
* function parameters and save function results.
|
||||||
|
*
|
||||||
* Revision 1.36 1999/08/31 22:38:29 steve
|
* Revision 1.36 1999/08/31 22:38:29 steve
|
||||||
* Elaborate and emit to vvm procedural functions.
|
* Elaborate and emit to vvm procedural functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
73
elaborate.cc
73
elaborate.cc
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: elaborate.cc,v 1.74 1999/08/31 22:38:29 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.75 1999/09/01 20:46:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -736,7 +736,13 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
|
||||||
NetEUFunc* PECallFunction::elaborate_expr(Design*des, const string&path) const
|
NetEUFunc* PECallFunction::elaborate_expr(Design*des, const string&path) const
|
||||||
{
|
{
|
||||||
string myname = path+"."+name_;
|
string myname = path+"."+name_;
|
||||||
NetFuncDef*def = des->find_function(myname);
|
NetFuncDef*def = des->find_function(path, name_);
|
||||||
|
if (def == 0) {
|
||||||
|
cerr << get_line() << ": No function " << name_ <<
|
||||||
|
" in this context (" << path << ")." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
assert(def);
|
assert(def);
|
||||||
svector<NetExpr*> parms (parms_.count());
|
svector<NetExpr*> parms (parms_.count());
|
||||||
|
|
||||||
|
|
@ -745,7 +751,17 @@ NetEUFunc* PECallFunction::elaborate_expr(Design*des, const string&path) const
|
||||||
parms[idx] = tmp;
|
parms[idx] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet*res = des->find_signal(myname, name_);
|
/* Look for the return value signal for the called function in
|
||||||
|
the context of the function definition, not my context. */
|
||||||
|
NetNet*res = des->find_signal(def->name(), name_);
|
||||||
|
if (res == 0) {
|
||||||
|
cerr << get_line() << ": INTERNAL ERROR: Unable to locate "
|
||||||
|
"function return value for " << name_ << " in " <<
|
||||||
|
def->name() << "." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
assert(res);
|
assert(res);
|
||||||
NetESignal*eres = new NetESignal(res);
|
NetESignal*eres = new NetESignal(res);
|
||||||
assert(eres);
|
assert(eres);
|
||||||
|
|
@ -1887,16 +1903,16 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PFunction::elaborate(Design*des, const string&path) const
|
/*
|
||||||
|
* Elaborating function definitions takes 2 passes. The first creates
|
||||||
|
* the NetFuncDef object and attaches the ports to it. The second pass
|
||||||
|
* (elaborate_2) elaborates the statement that is contained
|
||||||
|
* within. These passes are needed because the statement may invoke
|
||||||
|
* the function itself (or other functions) so can't be elaborated
|
||||||
|
* until all the functions are partially elaborated.
|
||||||
|
*/
|
||||||
|
void PFunction::elaborate_1(Design*des, const string&path) const
|
||||||
{
|
{
|
||||||
NetProc*st = statement_->elaborate(des, path);
|
|
||||||
if (st == 0) {
|
|
||||||
cerr << statement_->get_line() << ": Unable to elaborate "
|
|
||||||
"statement in function " << path << " at " << get_line()
|
|
||||||
<< "." << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Translate the wires that are ports to NetNet pointers by
|
/* Translate the wires that are ports to NetNet pointers by
|
||||||
presuming that the name is already elaborated, and look it
|
presuming that the name is already elaborated, and look it
|
||||||
up in the design. Then save that pointer for later use by
|
up in the design. Then save that pointer for later use by
|
||||||
|
|
@ -1910,11 +1926,26 @@ void PFunction::elaborate(Design*des, const string&path) const
|
||||||
ports[idx+1] = tmp;
|
ports[idx+1] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetFuncDef*def = new NetFuncDef(path, ports);
|
||||||
NetFuncDef*def = new NetFuncDef(path, st, ports);
|
|
||||||
des->add_function(path, def);
|
des->add_function(path, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PFunction::elaborate_2(Design*des, const string&path) const
|
||||||
|
{
|
||||||
|
NetFuncDef*def = des->find_function(path);
|
||||||
|
assert(def);
|
||||||
|
|
||||||
|
NetProc*st = statement_->elaborate(des, path);
|
||||||
|
if (st == 0) {
|
||||||
|
cerr << statement_->get_line() << ": Unable to elaborate "
|
||||||
|
"statement in function " << path << "." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
def->set_proc(st);
|
||||||
|
}
|
||||||
|
|
||||||
NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
||||||
{
|
{
|
||||||
NetExpr*expr = expr_->elaborate_expr(des, path);
|
NetExpr*expr = expr_->elaborate_expr(des, path);
|
||||||
|
|
@ -2036,10 +2067,17 @@ bool Module::elaborate(Design*des, const string&path, svector<PExpr*>*overrides_
|
||||||
|
|
||||||
// Elaborate functions.
|
// Elaborate functions.
|
||||||
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
|
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
|
||||||
|
|
||||||
for (mfunc_it_t cur = funcs_.begin()
|
for (mfunc_it_t cur = funcs_.begin()
|
||||||
; cur != funcs_.end() ; cur ++) {
|
; cur != funcs_.end() ; cur ++) {
|
||||||
string pname = path + "." + (*cur).first;
|
string pname = path + "." + (*cur).first;
|
||||||
(*cur).second->elaborate(des, pname);
|
(*cur).second->elaborate_1(des, pname);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mfunc_it_t cur = funcs_.begin()
|
||||||
|
; cur != funcs_.end() ; cur ++) {
|
||||||
|
string pname = path + "." + (*cur).first;
|
||||||
|
(*cur).second->elaborate_2(des, pname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elaborate the task definitions. This is done before the
|
// Elaborate the task definitions. This is done before the
|
||||||
|
|
@ -2127,6 +2165,11 @@ Design* elaborate(const map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.75 1999/09/01 20:46:19 steve
|
||||||
|
* Handle recursive functions and arbitrary function
|
||||||
|
* references to other functions, properly pass
|
||||||
|
* function parameters and save function results.
|
||||||
|
*
|
||||||
* Revision 1.74 1999/08/31 22:38:29 steve
|
* Revision 1.74 1999/08/31 22:38:29 steve
|
||||||
* Elaborate and emit to vvm procedural functions.
|
* Elaborate and emit to vvm procedural functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
72
netlist.cc
72
netlist.cc
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.cc,v 1.54 1999/08/31 22:38:29 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.55 1999/09/01 20:46:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -482,8 +482,8 @@ NetProc* NetCondit::else_clause()
|
||||||
return else_;
|
return else_;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetFuncDef::NetFuncDef(const string&n, NetProc*st, const svector<NetNet*>&po)
|
NetFuncDef::NetFuncDef(const string&n, const svector<NetNet*>&po)
|
||||||
: name_(n), statement_(st), ports_(po)
|
: name_(n), statement_(0), ports_(po)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -496,11 +496,29 @@ const string& NetFuncDef::name() const
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetFuncDef::set_proc(NetProc*st)
|
||||||
|
{
|
||||||
|
assert(statement_ == 0);
|
||||||
|
assert(st != 0);
|
||||||
|
statement_ = st;
|
||||||
|
}
|
||||||
|
|
||||||
const NetProc* NetFuncDef::proc() const
|
const NetProc* NetFuncDef::proc() const
|
||||||
{
|
{
|
||||||
return statement_;
|
return statement_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned NetFuncDef::port_count() const
|
||||||
|
{
|
||||||
|
return ports_.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetNet* NetFuncDef::port(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < ports_.count());
|
||||||
|
return ports_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe)
|
NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe)
|
||||||
: NetNode(ev, wid), sref<NetPEvent,NetNEvent>(pe), edge_(e)
|
: NetNode(ev, wid), sref<NetPEvent,NetNEvent>(pe), edge_(e)
|
||||||
{
|
{
|
||||||
|
|
@ -560,6 +578,7 @@ const NetExpr* NetSTask::parm(unsigned idx) const
|
||||||
NetEUFunc::NetEUFunc(NetFuncDef*def, NetESignal*res, svector<NetExpr*>&p)
|
NetEUFunc::NetEUFunc(NetFuncDef*def, NetESignal*res, svector<NetExpr*>&p)
|
||||||
: func_(def), result_(res), parms_(p)
|
: func_(def), result_(res), parms_(p)
|
||||||
{
|
{
|
||||||
|
expr_width(result_->expr_width());
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEUFunc::~NetEUFunc()
|
NetEUFunc::~NetEUFunc()
|
||||||
|
|
@ -578,6 +597,22 @@ const NetESignal*NetEUFunc::result() const
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned NetEUFunc::parm_count() const
|
||||||
|
{
|
||||||
|
return parms_.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetExpr* NetEUFunc::parm(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < parms_.count());
|
||||||
|
return parms_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetFuncDef* NetEUFunc::definition() const
|
||||||
|
{
|
||||||
|
return func_;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXXX FIX ME: For now, just take whatever the caller says as my
|
* XXXX FIX ME: For now, just take whatever the caller says as my
|
||||||
* width. What I really need to do is note the width of the output
|
* width. What I really need to do is note the width of the output
|
||||||
|
|
@ -1501,13 +1536,31 @@ void Design::add_function(const string&key, NetFuncDef*def)
|
||||||
funcs_[key] = def;
|
funcs_[key] = def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetFuncDef* Design::find_function(const string&path, const string&name)
|
||||||
|
{
|
||||||
|
string root = path;
|
||||||
|
for (;;) {
|
||||||
|
string key = root + "." + name;
|
||||||
|
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
||||||
|
if (cur != funcs_.end())
|
||||||
|
return (*cur).second;
|
||||||
|
|
||||||
|
unsigned pos = root.rfind('.');
|
||||||
|
if (pos > root.length())
|
||||||
|
break;
|
||||||
|
|
||||||
|
root = root.substr(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
NetFuncDef* Design::find_function(const string&key)
|
NetFuncDef* Design::find_function(const string&key)
|
||||||
{
|
{
|
||||||
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
||||||
if (cur == funcs_.end())
|
if (cur != funcs_.end())
|
||||||
return 0;
|
return (*cur).second;
|
||||||
|
return 0;
|
||||||
return (*cur).second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::add_task(const string&key, NetTaskDef*def)
|
void Design::add_task(const string&key, NetTaskDef*def)
|
||||||
|
|
@ -1642,6 +1695,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.55 1999/09/01 20:46:19 steve
|
||||||
|
* Handle recursive functions and arbitrary function
|
||||||
|
* references to other functions, properly pass
|
||||||
|
* function parameters and save function results.
|
||||||
|
*
|
||||||
* Revision 1.54 1999/08/31 22:38:29 steve
|
* Revision 1.54 1999/08/31 22:38:29 steve
|
||||||
* Elaborate and emit to vvm procedural functions.
|
* Elaborate and emit to vvm procedural functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
21
netlist.h
21
netlist.h
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.h,v 1.58 1999/08/31 22:38:29 steve Exp $"
|
#ident "$Id: netlist.h,v 1.59 1999/09/01 20:46:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -768,12 +768,17 @@ class NetForever : public NetProc {
|
||||||
class NetFuncDef {
|
class NetFuncDef {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetFuncDef(const string&, NetProc*st, const svector<NetNet*>&po);
|
NetFuncDef(const string&, const svector<NetNet*>&po);
|
||||||
~NetFuncDef();
|
~NetFuncDef();
|
||||||
|
|
||||||
|
void set_proc(NetProc*st);
|
||||||
|
|
||||||
const string& name() const;
|
const string& name() const;
|
||||||
const NetProc*proc() const;
|
const NetProc*proc() const;
|
||||||
|
|
||||||
|
unsigned port_count() const;
|
||||||
|
const NetNet*port(unsigned idx) const;
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -951,6 +956,10 @@ class NetEUFunc : public NetExpr {
|
||||||
const string& name() const;
|
const string& name() const;
|
||||||
|
|
||||||
const NetESignal*result() const;
|
const NetESignal*result() const;
|
||||||
|
unsigned parm_count() const;
|
||||||
|
const NetExpr* parm(unsigned idx) const;
|
||||||
|
|
||||||
|
const NetFuncDef* definition() const;
|
||||||
|
|
||||||
virtual bool set_width(unsigned);
|
virtual bool set_width(unsigned);
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
@ -1402,7 +1411,8 @@ class Design {
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
void add_function(const string&n, NetFuncDef*);
|
void add_function(const string&n, NetFuncDef*);
|
||||||
NetFuncDef* find_function(const string&key);
|
NetFuncDef* find_function(const string&path, const string&key);
|
||||||
|
NetFuncDef* find_function(const string&path);
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
void add_task(const string&n, NetTaskDef*);
|
void add_task(const string&n, NetTaskDef*);
|
||||||
|
|
@ -1508,6 +1518,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.59 1999/09/01 20:46:19 steve
|
||||||
|
* Handle recursive functions and arbitrary function
|
||||||
|
* references to other functions, properly pass
|
||||||
|
* function parameters and save function results.
|
||||||
|
*
|
||||||
* Revision 1.58 1999/08/31 22:38:29 steve
|
* Revision 1.58 1999/08/31 22:38:29 steve
|
||||||
* Elaborate and emit to vvm procedural functions.
|
* Elaborate and emit to vvm procedural functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
65
t-vvm.cc
65
t-vvm.cc
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: t-vvm.cc,v 1.36 1999/08/31 22:38:29 steve Exp $"
|
#ident "$Id: t-vvm.cc,v 1.37 1999/09/01 20:46:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
@ -206,11 +206,38 @@ void vvm_proc_rval::expr_subsignal(const NetESubSignal*sig)
|
||||||
result = val;
|
result = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A function call is handled by assigning the parameters from the
|
||||||
|
* input expressions, then calling the function. After the function
|
||||||
|
* returns, copy the result into a temporary variable.
|
||||||
|
*
|
||||||
|
* Function calls are different from tasks in this regard--tasks had
|
||||||
|
* all this assigning arranged during elaboration. For functions, we
|
||||||
|
* must do it ourselves.
|
||||||
|
*/
|
||||||
void vvm_proc_rval::expr_ufunc(const NetEUFunc*expr)
|
void vvm_proc_rval::expr_ufunc(const NetEUFunc*expr)
|
||||||
{
|
{
|
||||||
string name = mangle(expr->name());
|
const NetFuncDef*def = expr->definition();
|
||||||
os_ << " " << name << "(sim_);" << endl;
|
const unsigned pcnt = expr->parm_count();
|
||||||
result = mangle(expr->result()->name()) + "_bits";
|
assert(pcnt == (def->port_count()-1));
|
||||||
|
|
||||||
|
/* Scan the parameter expressions, and assign the values to
|
||||||
|
the parameter port register. */
|
||||||
|
for (unsigned idx = 0 ; idx < pcnt ; idx += 1) {
|
||||||
|
expr->parm(idx)->expr_scan(this);
|
||||||
|
os_ << " " << mangle(def->port(idx+1)->name()) <<
|
||||||
|
"_bits = " << result << ";" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make the function call. */
|
||||||
|
os_ << " " << mangle(expr->name()) << "(sim_);" << endl;
|
||||||
|
|
||||||
|
/* Save the return value in a temporary. */
|
||||||
|
result = make_temp();
|
||||||
|
string rbits = mangle(expr->result()->name()) + "_bits";
|
||||||
|
|
||||||
|
os_ << " vvm_bitset_t<" << expr->expr_width() << "> " <<
|
||||||
|
result << " = " << rbits << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vvm_proc_rval::expr_unary(const NetEUnary*expr)
|
void vvm_proc_rval::expr_unary(const NetEUnary*expr)
|
||||||
|
|
@ -537,10 +564,13 @@ void target_vvm::func_def(ostream&os, const NetFuncDef*def)
|
||||||
thread_step_ = 0;
|
thread_step_ = 0;
|
||||||
const string name = mangle(def->name());
|
const string name = mangle(def->name());
|
||||||
os << "// Function " << def->name() << endl;
|
os << "// Function " << def->name() << endl;
|
||||||
os << "static void " << name << "(vvm_simulation*sim_)" << endl;
|
os << "static void " << name << "(vvm_simulation*);" << endl;
|
||||||
os << "{" << endl;
|
|
||||||
def->proc()->emit_proc(os, this);
|
delayed << "// Function " << def->name() << endl;
|
||||||
os << "}" << endl;
|
delayed << "static void " << name << "(vvm_simulation*sim_)" << endl;
|
||||||
|
delayed << "{" << endl;
|
||||||
|
def->proc()->emit_proc(delayed, this);
|
||||||
|
delayed << "}" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1191,19 +1221,6 @@ void target_vvm::proc_stask(ostream&os, const NetSTask*net)
|
||||||
{
|
{
|
||||||
string ptmp = make_temp();
|
string ptmp = make_temp();
|
||||||
|
|
||||||
#if 0
|
|
||||||
os << " struct __vpiHandle " << ptmp << "[" <<
|
|
||||||
net->nparms() << "];" << endl;
|
|
||||||
for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1)
|
|
||||||
if (net->parm(idx)) {
|
|
||||||
string val = emit_parm_rval(os, net->parm(idx));
|
|
||||||
os << " vvm_make_vpi_parm(&" << ptmp << "["
|
|
||||||
<< idx << "], " << val << ");" << endl;
|
|
||||||
} else {
|
|
||||||
os << " vvm_make_vpi_parm(&" << ptmp << "["
|
|
||||||
<< idx << "]);" << endl;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
os << " vpiHandle " << ptmp << "[" << net->nparms() <<
|
os << " vpiHandle " << ptmp << "[" << net->nparms() <<
|
||||||
"];" << endl;
|
"];" << endl;
|
||||||
for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1) {
|
||||||
|
|
@ -1221,7 +1238,6 @@ void target_vvm::proc_stask(ostream&os, const NetSTask*net)
|
||||||
os << " " << ptmp << "[" << idx << "] = " << val << ";"
|
os << " " << ptmp << "[" << idx << "] = " << val << ";"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
os << " vvm_calltask(sim_, \"" << net->name() << "\", " <<
|
os << " vvm_calltask(sim_, \"" << net->name() << "\", " <<
|
||||||
net->nparms() << ", " << ptmp << ");" << endl;
|
net->nparms() << ", " << ptmp << ");" << endl;
|
||||||
|
|
@ -1385,6 +1401,11 @@ extern const struct target tgt_vvm = {
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* $Log: t-vvm.cc,v $
|
* $Log: t-vvm.cc,v $
|
||||||
|
* Revision 1.37 1999/09/01 20:46:19 steve
|
||||||
|
* Handle recursive functions and arbitrary function
|
||||||
|
* references to other functions, properly pass
|
||||||
|
* function parameters and save function results.
|
||||||
|
*
|
||||||
* Revision 1.36 1999/08/31 22:38:29 steve
|
* Revision 1.36 1999/08/31 22:38:29 steve
|
||||||
* Elaborate and emit to vvm procedural functions.
|
* Elaborate and emit to vvm procedural functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue