Elaborate and emit to vvm procedural functions.

This commit is contained in:
steve 1999-08-31 22:38:29 +00:00
parent 1c11c864d5
commit e69345b9fe
10 changed files with 284 additions and 26 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.17 1999/08/01 21:18:55 steve Exp $"
#ident "$Id: PExpr.h,v 1.18 1999/08/31 22:38:29 steve Exp $"
#endif
# include <string>
@ -254,6 +254,7 @@ class PECallFunction : public PExpr {
~PECallFunction() {}
virtual void dump(ostream &) const;
virtual NetEUFunc*elaborate_expr(Design*des, const string&path) const;
private:
string name_;
@ -262,6 +263,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.18 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.17 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: design_dump.cc,v 1.35 1999/08/25 22:22:41 steve Exp $"
#ident "$Id: design_dump.cc,v 1.36 1999/08/31 22:38:29 steve Exp $"
#endif
/*
@ -123,24 +123,25 @@ void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
void NetAssign::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Procedural assign: " << *rval_ << endl;
o << setw(ind) << "" << "Procedural assign (NetAssign): " <<
*rval_ << endl;
dump_node_pins(o, ind+4);
}
void NetAssignNB::dump_node(ostream&o, unsigned ind) const
{
if (bmux_)
o << setw(ind) << "" << "Procedural NB assign: " << name()
<< "[" << *bmux_ << "] <= " << *rval_ << endl;
o << setw(ind) << "" << "Procedural NB assign (NetAssignNB): "
<< name() << "[" << *bmux_ << "] <= " << *rval_ << endl;
else
o << setw(ind) << "" << "Procedural NB assign: " << name()
<< " <= " << *rval_ << endl;
o << setw(ind) << "" << "Procedural NB assign (NetAssignNB): "
<< name() << " <= " << *rval_ << endl;
dump_node_pins(o, ind+4);
}
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "BUFZ: " << name() << endl;
o << setw(ind) << "" << "NetBUFZ: " << name() << endl;
dump_node_pins(o, ind+4);
}
@ -616,7 +617,8 @@ void NetEMemory::dump(ostream&o) const
void NetESignal::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Expression Node: " << name() << endl;
o << setw(ind) << "" << "Expression Node (NetESignal): " <<
name() << endl;
dump_node_pins(o, ind+4);
}
@ -627,6 +629,18 @@ void NetETernary::dump(ostream&o) const
false_val_ << ")";
}
void NetEUFunc::dump(ostream&o) const
{
o << name() << "(";
assert(parms_.count() > 0);
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
o << ", ";
parms_[idx]->dump(o);
}
o << ")";
}
void NetEUnary::dump(ostream&o) const
{
o << op_ << "(";
@ -666,6 +680,15 @@ void Design::dump(ostream&o) const
}
}
o << "ELABORATED FUNCTION DEFINITIONS:" << endl;
{
map<string,NetFuncDef*>::const_iterator pp;
for (pp = funcs_.begin()
; pp != funcs_.end() ; pp ++) {
(*pp).second->dump(o, 0);
}
}
o << "ELABORATED TASK DEFINITIONS:" << endl;
{
map<string,NetTaskDef*>::const_iterator pp;
@ -696,6 +719,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.36 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.35 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.73 1999/08/25 22:22:41 steve Exp $"
#ident "$Id: elaborate.cc,v 1.74 1999/08/31 22:38:29 steve Exp $"
#endif
/*
@ -733,6 +733,27 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
return osig;
}
NetEUFunc* PECallFunction::elaborate_expr(Design*des, const string&path) const
{
string myname = path+"."+name_;
NetFuncDef*def = des->find_function(myname);
assert(def);
svector<NetExpr*> parms (parms_.count());
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
NetExpr*tmp = parms_[idx]->elaborate_expr(des, myname);
parms[idx] = tmp;
}
NetNet*res = des->find_signal(myname, name_);
assert(res);
NetESignal*eres = new NetESignal(res);
assert(eres);
des->add_node(eres);
NetEUFunc*func = new NetEUFunc(def, eres, parms);
return func;
}
/*
* The concatenation operator, as a net, is a wide signal that is
* connected to all the pins of the elaborated expression nets.
@ -1869,12 +1890,29 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
void PFunction::elaborate(Design*des, const string&path) const
{
NetProc*st = statement_->elaborate(des, path);
NetFuncDef*def = new NetFuncDef(path, st);
des->add_function(path, def);
if (st == 0) {
cerr << statement_->get_line() << ": Unable to elaborate "
"statement in function " << path << " at " << get_line()
<< "." << endl;
return;
}
cerr << get_line() << ": Sorry, unable to elaborate "
"function definitions." << endl;
des->errors += 1;
/* Translate the wires that are ports to NetNet pointers by
presuming that the name is already elaborated, and look it
up in the design. Then save that pointer for later use by
calls to the task. (Remember, the task itself does not need
these ports.) */
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
ports[0] = des->find_signal(path, path);
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
NetNet*tmp = des->find_signal(path, (*ports_)[idx]->name());
ports[idx+1] = tmp;
}
NetFuncDef*def = new NetFuncDef(path, st, ports);
des->add_function(path, def);
}
NetProc* PRepeat::elaborate(Design*des, const string&path) const
@ -2089,6 +2127,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.74 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.73 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*

18
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: emit.cc,v 1.18 1999/07/17 19:50:59 steve Exp $"
#ident "$Id: emit.cc,v 1.19 1999/08/31 22:38:29 steve Exp $"
#endif
/*
@ -229,6 +229,14 @@ void Design::emit(ostream&o, struct target_t*tgt) const
}
// emit function definitions
{
map<string,NetFuncDef*>::const_iterator ta;
for (ta = funcs_.begin() ; ta != funcs_.end() ; ta ++) {
tgt->func_def(o, (*ta).second);
}
}
// emit task definitions
{
map<string,NetTaskDef*>::const_iterator ta;
@ -269,6 +277,11 @@ void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_memory(this);
}
void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ufunc(this);
}
void NetESignal::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_signal(this);
@ -308,6 +321,9 @@ void emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.19 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.18 1999/07/17 19:50:59 steve
* netlist support for ternary operator.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.cc,v 1.53 1999/08/25 22:22:41 steve Exp $"
#ident "$Id: netlist.cc,v 1.54 1999/08/31 22:38:29 steve Exp $"
#endif
# include <cassert>
@ -482,8 +482,8 @@ NetProc* NetCondit::else_clause()
return else_;
}
NetFuncDef::NetFuncDef(const string&n, NetProc*st)
: name_(n), statement_(st)
NetFuncDef::NetFuncDef(const string&n, NetProc*st, const svector<NetNet*>&po)
: name_(n), statement_(st), ports_(po)
{
}
@ -491,6 +491,16 @@ NetFuncDef::~NetFuncDef()
{
}
const string& NetFuncDef::name() const
{
return name_;
}
const NetProc* NetFuncDef::proc() const
{
return statement_;
}
NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe)
: NetNode(ev, wid), sref<NetPEvent,NetNEvent>(pe), edge_(e)
{
@ -547,6 +557,44 @@ const NetExpr* NetSTask::parm(unsigned idx) const
return parms_[idx];
}
NetEUFunc::NetEUFunc(NetFuncDef*def, NetESignal*res, svector<NetExpr*>&p)
: func_(def), result_(res), parms_(p)
{
}
NetEUFunc::~NetEUFunc()
{
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
delete parms_[idx];
}
const string& NetEUFunc::name() const
{
return func_->name();
}
const NetESignal*NetEUFunc::result() const
{
return result_;
}
/*
* 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
* parameter of the function definition and take that into account.
*/
bool NetEUFunc::set_width(unsigned wid)
{
expr_width(wid);
return true;
}
NetEUFunc* NetEUFunc::dup_expr() const
{
assert(0);
return 0;
}
NetUTask::NetUTask(NetTaskDef*def)
: task_(def)
{
@ -1453,6 +1501,15 @@ void Design::add_function(const string&key, NetFuncDef*def)
funcs_[key] = def;
}
NetFuncDef* Design::find_function(const string&key)
{
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
if (cur == funcs_.end())
return 0;
return (*cur).second;
}
void Design::add_task(const string&key, NetTaskDef*def)
{
tasks_[key] = def;
@ -1585,6 +1642,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.54 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.53 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.h,v 1.57 1999/08/25 22:22:41 steve Exp $"
#ident "$Id: netlist.h,v 1.58 1999/08/31 22:38:29 steve Exp $"
#endif
/*
@ -40,6 +40,7 @@ class NetNode;
class NetProc;
class NetProcTop;
class NetExpr;
class NetESignal;
class ostream;
@ -758,17 +759,27 @@ class NetForever : public NetProc {
NetProc*statement_;
};
/*
* A funciton definition is elaborated just like a task, though by now
* it is certain that the first parameter (a phantom parameter) is the
* output and all the remaining parameters are the inputs. This makes
* for easy code generation in targets that support behavioral descriptions.
*/
class NetFuncDef {
public:
explicit NetFuncDef(const string&, NetProc*st);
NetFuncDef(const string&, NetProc*st, const svector<NetNet*>&po);
~NetFuncDef();
const string& name() const;
const NetProc*proc() const;
virtual void dump(ostream&, unsigned ind) const;
private:
string name_;
NetProc*statement_;
svector<NetNet*>ports_;
};
class NetPDelay : public NetProc {
@ -923,7 +934,44 @@ class NetTaskDef {
};
/*
* A call to a user defined task is elaborated into this object.
* This node represents a function call in an expression. The object
* contains a pointer to the function definition, which is used to
* locate the value register and input expressions.
*
* The NetNet parameter to the constructor is the *register* NetNet
* that receives the result of the function, and the NetExpr list is
* the paraneters passed to the function.
*/
class NetEUFunc : public NetExpr {
public:
NetEUFunc(NetFuncDef*, NetESignal*, svector<NetExpr*>&);
~NetEUFunc();
const string& name() const;
const NetESignal*result() const;
virtual bool set_width(unsigned);
virtual void dump(ostream&) const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEUFunc*dup_expr() const;
private:
NetFuncDef*func_;
NetESignal*result_;
svector<NetExpr*> parms_;
private: // not implemented
NetEUFunc(const NetEUFunc&);
NetEUFunc& operator= (const NetEUFunc&);
};
/*
* A call to a user defined task is elaborated into this object. This
* contains a pointer to the elaborated task definition, but is a
* NetProc object so that it can be linked into statements.
*/
class NetUTask : public NetProc {
@ -1354,6 +1402,7 @@ class Design {
// Functions
void add_function(const string&n, NetFuncDef*);
NetFuncDef* find_function(const string&key);
// Tasks
void add_task(const string&n, NetTaskDef*);
@ -1459,6 +1508,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.58 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.57 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform.cc,v 1.40 1999/08/27 15:08:37 steve Exp $"
#ident "$Id: pform.cc,v 1.41 1999/08/31 22:38:29 steve Exp $"
#endif
# include "compiler.h"
@ -518,6 +518,11 @@ void pform_set_task(const 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 string&name, svector<PExpr*>*ra, PFunction *func)
{
PWire*out = new PWire(name+"."+name, NetNet::REG, NetNet::POUTPUT);
@ -682,6 +687,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* Revision 1.41 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.40 1999/08/27 15:08:37 steve
* continuous assignment lists.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.35 1999/08/15 01:23:56 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.36 1999/08/31 22:38:29 steve Exp $"
#endif
# include <iostream>
@ -43,6 +43,7 @@ class target_vvm : public target_t {
virtual void signal(ostream&os, const NetNet*);
virtual void memory(ostream&os, const NetMemory*);
virtual void task_def(ostream&os, const NetTaskDef*);
virtual void func_def(ostream&os, const NetFuncDef*);
virtual void logic(ostream&os, const NetLogic*);
virtual void bufz(ostream&os, const NetBUFZ*);
virtual void udp(ostream&os, const NetUDP*);
@ -119,6 +120,7 @@ class vvm_proc_rval : public expr_scan_t {
virtual void expr_subsignal(const NetESubSignal*sig);
virtual void expr_unary(const NetEUnary*);
virtual void expr_binary(const NetEBinary*);
virtual void expr_ufunc(const NetEUFunc*);
};
void vvm_proc_rval::expr_concat(const NetEConcat*expr)
@ -204,6 +206,13 @@ void vvm_proc_rval::expr_subsignal(const NetESubSignal*sig)
result = val;
}
void vvm_proc_rval::expr_ufunc(const NetEUFunc*expr)
{
string name = mangle(expr->name());
os_ << " " << name << "(sim_);" << endl;
result = mangle(expr->result()->name()) + "_bits";
}
void vvm_proc_rval::expr_unary(const NetEUnary*expr)
{
expr->expr()->expr_scan(this);
@ -515,6 +524,25 @@ void target_vvm::task_def(ostream&os, const NetTaskDef*def)
os << "};" << endl;
}
/*
* A function definition is emitted as a C++ function that takes no
* parameters and returns no result. The actual parameter passing
* happens in the function call, where the signals that are the inputs
* are assigned by the caller, the caller calls the function (which
* writes the result) then the caller copies the result out of the
* magic result register.
*/
void target_vvm::func_def(ostream&os, const NetFuncDef*def)
{
thread_step_ = 0;
const string name = mangle(def->name());
os << "// Function " << def->name() << endl;
os << "static void " << name << "(vvm_simulation*sim_)" << endl;
os << "{" << endl;
def->proc()->emit_proc(os, this);
os << "}" << endl;
}
/*
* This method handles writing output functions for gates that have a
* single output (at pin 0). This writes the output_fun method into
@ -1357,6 +1385,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.36 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.35 1999/08/15 01:23:56 steve
* Convert vvm to implement system tasks with vpi.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: target.cc,v 1.16 1999/08/18 04:00:02 steve Exp $"
#ident "$Id: target.cc,v 1.17 1999/08/31 22:38:29 steve Exp $"
#endif
# include "target.h"
@ -41,6 +41,12 @@ void target_t::memory(ostream&os, const NetMemory*)
"Unhandled memory." << endl;
}
void target_t::func_def(ostream&os, const NetFuncDef*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled function definition." << endl;
}
void target_t::task_def(ostream&os, const NetTaskDef*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -230,6 +236,12 @@ void expr_scan_t::expr_ternary(const NetETernary*)
"unhandled expr_ternary." << endl;
}
void expr_scan_t::expr_ufunc(const NetEUFunc*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
"unhandled function call." << endl;
}
void expr_scan_t::expr_unary(const NetEUnary*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
@ -244,6 +256,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.17 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.16 1999/08/18 04:00:02 steve
* Fixup spelling and some error messages. <LRDoolittle@lbl.gov>
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: target.h,v 1.15 1999/07/17 19:51:00 steve Exp $"
#ident "$Id: target.h,v 1.16 1999/08/31 22:38:29 steve Exp $"
#endif
# include "netlist.h"
@ -63,6 +63,7 @@ struct target_t {
/* Output a defined task. */
virtual void task_def(ostream&, const NetTaskDef*);
virtual void func_def(ostream&, const NetFuncDef*);
/* Output a gate (called for each gate) */
virtual void logic(ostream&os, const NetLogic*);
@ -109,6 +110,7 @@ struct expr_scan_t {
virtual void expr_signal(const NetESignal*);
virtual void expr_subsignal(const NetESubSignal*);
virtual void expr_ternary(const NetETernary*);
virtual void expr_ufunc(const NetEUFunc*);
virtual void expr_unary(const NetEUnary*);
virtual void expr_binary(const NetEBinary*);
};
@ -130,6 +132,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.16 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.15 1999/07/17 19:51:00 steve
* netlist support for ternary operator.
*