Elaborate task input ports.
This commit is contained in:
parent
9021f68996
commit
93a77a2efd
9
PTask.cc
9
PTask.cc
|
|
@ -17,13 +17,13 @@
|
||||||
* 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.cc,v 1.1 1999/07/03 02:12:51 steve Exp $"
|
#ident "$Id: PTask.cc,v 1.2 1999/07/24 02:11:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "PTask.h"
|
# include "PTask.h"
|
||||||
|
|
||||||
PTask::PTask(Statement*s)
|
PTask::PTask(svector<PWire*>*p, Statement*s)
|
||||||
: statement_(s)
|
: ports_(p), statement_(s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,6 +33,9 @@ PTask::~PTask()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PTask.cc,v $
|
* $Log: PTask.cc,v $
|
||||||
|
* Revision 1.2 1999/07/24 02:11:19 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.1 1999/07/03 02:12:51 steve
|
* Revision 1.1 1999/07/03 02:12:51 steve
|
||||||
* Elaborate user defined tasks.
|
* Elaborate user defined tasks.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
10
PTask.h
10
PTask.h
|
|
@ -19,12 +19,14 @@
|
||||||
* 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.1 1999/07/03 02:12:51 steve Exp $"
|
#ident "$Id: PTask.h,v 1.2 1999/07/24 02:11:19 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
# include "svector.h"
|
||||||
# include <string>
|
# include <string>
|
||||||
class Design;
|
class Design;
|
||||||
|
class PWire;
|
||||||
class Statement;
|
class Statement;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -33,13 +35,14 @@ class Statement;
|
||||||
class PTask : public LineInfo {
|
class PTask : public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PTask(Statement*s);
|
explicit PTask(svector<PWire*>*p, Statement*s);
|
||||||
~PTask();
|
~PTask();
|
||||||
|
|
||||||
virtual void elaborate(Design*des, const string&path) const;
|
virtual void elaborate(Design*des, const string&path) const;
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
svector<PWire*>*ports_;
|
||||||
Statement*statement_;
|
Statement*statement_;
|
||||||
|
|
||||||
private: // Not implemented
|
private: // Not implemented
|
||||||
|
|
@ -49,6 +52,9 @@ class PTask : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PTask.h,v $
|
* $Log: PTask.h,v $
|
||||||
|
* Revision 1.2 1999/07/24 02:11:19 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.1 1999/07/03 02:12:51 steve
|
* Revision 1.1 1999/07/03 02:12:51 steve
|
||||||
* Elaborate user defined tasks.
|
* Elaborate user defined tasks.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.32 1999/07/17 19:50:59 steve Exp $"
|
#ident "$Id: design_dump.cc,v 1.33 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -196,7 +196,28 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||||
void NetTaskDef::dump(ostream&o, unsigned ind) const
|
void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "task " << name_ << ";" << endl;
|
o << setw(ind) << "" << "task " << name_ << ";" << endl;
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||||
|
o << setw(ind+4) << "";
|
||||||
|
switch (ports_[idx]->port_type()) {
|
||||||
|
case NetNet::PINPUT:
|
||||||
|
o << "input ";
|
||||||
|
break;
|
||||||
|
case NetNet::POUTPUT:
|
||||||
|
o << "output ";
|
||||||
|
break;
|
||||||
|
case NetNet::PINOUT:
|
||||||
|
o << "input ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
o << "NOT_A_PORT ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
o << ports_[idx]->name() << ";" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
proc_->dump(o, ind+4);
|
proc_->dump(o, ind+4);
|
||||||
|
|
||||||
o << setw(ind) << "" << "endtask" << endl;
|
o << setw(ind) << "" << "endtask" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -480,22 +501,7 @@ void NetSTask::dump(ostream&o, unsigned ind) const
|
||||||
|
|
||||||
void NetUTask::dump(ostream&o, unsigned ind) const
|
void NetUTask::dump(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << task_->name();
|
o << setw(ind) << "" << task_->name() << ";" << endl;
|
||||||
|
|
||||||
if (parms_.count() > 0) {
|
|
||||||
o << "(";
|
|
||||||
if (parms_[0])
|
|
||||||
parms_[0]->dump(o);
|
|
||||||
|
|
||||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
|
||||||
o << ", ";
|
|
||||||
if (parms_[idx])
|
|
||||||
parms_[idx]->dump(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
o << ")";
|
|
||||||
}
|
|
||||||
o << ";" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWhile::dump(ostream&o, unsigned ind) const
|
void NetWhile::dump(ostream&o, unsigned ind) const
|
||||||
|
|
@ -684,6 +690,9 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $Log: design_dump.cc,v $
|
||||||
|
* Revision 1.33 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.32 1999/07/17 19:50:59 steve
|
* Revision 1.32 1999/07/17 19:50:59 steve
|
||||||
* netlist support for ternary operator.
|
* netlist support for ternary operator.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
115
elaborate.cc
115
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.58 1999/07/18 21:17:50 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.59 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -103,6 +103,8 @@ void PWire::elaborate(Design*des, const string&path) const
|
||||||
NetNet::Type wtype = type_;
|
NetNet::Type wtype = type_;
|
||||||
if (wtype == NetNet::IMPLICIT)
|
if (wtype == NetNet::IMPLICIT)
|
||||||
wtype = NetNet::WIRE;
|
wtype = NetNet::WIRE;
|
||||||
|
if (wtype == NetNet::IMPLICIT_REG)
|
||||||
|
wtype = NetNet::REG;
|
||||||
|
|
||||||
unsigned wid = 1;
|
unsigned wid = 1;
|
||||||
|
|
||||||
|
|
@ -1533,15 +1535,36 @@ NetProc* PCallTask::elaborate_sys(Design*des, const string&path) const
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A call to a user defined task is different from a call to a system
|
||||||
|
* task because a user task in a netlist has no parameters: the
|
||||||
|
* assignments are done by the calling thread. For example:
|
||||||
|
*
|
||||||
|
* task foo;
|
||||||
|
* input a;
|
||||||
|
* output b;
|
||||||
|
* [...]
|
||||||
|
* endtask;
|
||||||
|
*
|
||||||
|
* [...] foo(x, y);
|
||||||
|
*
|
||||||
|
* is really:
|
||||||
|
*
|
||||||
|
* task foo;
|
||||||
|
* reg a;
|
||||||
|
* reg b;
|
||||||
|
* [...]
|
||||||
|
* endtask;
|
||||||
|
*
|
||||||
|
* [...]
|
||||||
|
* begin
|
||||||
|
* a = x;
|
||||||
|
* foo;
|
||||||
|
* y = b;
|
||||||
|
* end
|
||||||
|
*/
|
||||||
NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
||||||
{
|
{
|
||||||
svector<NetExpr*>eparms (nparms());
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
|
||||||
PExpr*ex = parm(idx);
|
|
||||||
eparms[idx] = ex? ex->elaborate_expr(des, path) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetTaskDef*def = des->find_task(path + "." + name_);
|
NetTaskDef*def = des->find_task(path + "." + name_);
|
||||||
if (def == 0) {
|
if (def == 0) {
|
||||||
cerr << get_line() << ": Enable of unknown task ``" <<
|
cerr << get_line() << ": Enable of unknown task ``" <<
|
||||||
|
|
@ -1550,8 +1573,60 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetUTask*cur = new NetUTask(def, eparms);
|
if (nparms() != def->port_count()) {
|
||||||
return cur;
|
cerr << get_line() << ": Port count mismatch in call to ``"
|
||||||
|
<< name_ << "''." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetUTask*cur;
|
||||||
|
|
||||||
|
/* Handle tasks with no parameters specially. There is no need
|
||||||
|
to make a sequential block to hold the generated code. */
|
||||||
|
if (nparms() == 0) {
|
||||||
|
cur = new NetUTask(def);
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetBlock*block = new NetBlock(NetBlock::SEQU);
|
||||||
|
|
||||||
|
/* Generate assignment statement statements for the input and
|
||||||
|
INOUT ports of the task. */
|
||||||
|
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||||
|
|
||||||
|
NetNet*port = def->port(idx);
|
||||||
|
assert(port->port_type() != NetNet::NOT_A_PORT);
|
||||||
|
if (port->port_type() == NetNet::POUTPUT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
NetExpr*rv = parms_[idx]->elaborate_expr(des, path);
|
||||||
|
NetAssign*pr = new NetAssign("@", des, port->pin_count(), rv);
|
||||||
|
for (unsigned pi = 0 ; pi < port->pin_count() ; pi += 1)
|
||||||
|
connect(port->pin(pi), pr->pin(pi));
|
||||||
|
des->add_node(pr);
|
||||||
|
block->append(pr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate the task call proper... */
|
||||||
|
cur = new NetUTask(def);
|
||||||
|
block->append(cur);
|
||||||
|
|
||||||
|
/* Generate assignment statement statements for the output and
|
||||||
|
INOUT ports of the task. */
|
||||||
|
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||||
|
|
||||||
|
NetNet*port = def->port(idx);
|
||||||
|
assert(port->port_type() != NetNet::NOT_A_PORT);
|
||||||
|
if (port->port_type() == NetNet::PINPUT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cerr << get_line() << ": Sorry, output ports not yet "
|
||||||
|
"implemented." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
|
NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
|
||||||
|
|
@ -1725,7 +1800,9 @@ NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A task definition is elaborated by elaborating the statement that
|
* A task definition is elaborated by elaborating the statement that
|
||||||
* it contains, and ... XXXX
|
* it contains, and connecting its ports to NetNet objects. The
|
||||||
|
* netlist doesn't really need the array of parameters once elaboration
|
||||||
|
* is complete, but this is the best place to store them.
|
||||||
*/
|
*/
|
||||||
void PTask::elaborate(Design*des, const string&path) const
|
void PTask::elaborate(Design*des, const string&path) const
|
||||||
{
|
{
|
||||||
|
|
@ -1737,8 +1814,19 @@ void PTask::elaborate(Design*des, const string&path) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetTaskDef*def = new NetTaskDef(path, st);
|
/* 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_->count());
|
||||||
|
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||||
|
NetNet*tmp = des->find_signal(path, (*ports_)[idx]->name());
|
||||||
|
|
||||||
|
ports[idx] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetTaskDef*def = new NetTaskDef(path, st, ports);
|
||||||
des->add_task(path, def);
|
des->add_task(path, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1862,6 +1950,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.59 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.58 1999/07/18 21:17:50 steve
|
* Revision 1.58 1999/07/18 21:17:50 steve
|
||||||
* Add support for CE input to XNF DFF, and do
|
* Add support for CE input to XNF DFF, and do
|
||||||
* complete cleanup of replaced design nodes.
|
* complete cleanup of replaced design nodes.
|
||||||
|
|
|
||||||
21
netlist.cc
21
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.47 1999/07/18 21:17:50 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.48 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -535,15 +535,13 @@ const NetExpr* NetSTask::parm(unsigned idx) const
|
||||||
return parms_[idx];
|
return parms_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
NetUTask::NetUTask(NetTaskDef*def, const svector<NetExpr*>&p)
|
NetUTask::NetUTask(NetTaskDef*def)
|
||||||
: task_(def), parms_(p)
|
: task_(def)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NetUTask::~NetUTask()
|
NetUTask::~NetUTask()
|
||||||
{
|
{
|
||||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
|
|
||||||
delete parms_[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr::~NetExpr()
|
NetExpr::~NetExpr()
|
||||||
|
|
@ -968,8 +966,8 @@ const NetExpr* NetRepeat::expr() const
|
||||||
return expr_;
|
return expr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetTaskDef::NetTaskDef(const string&n, NetProc*p)
|
NetTaskDef::NetTaskDef(const string&n, NetProc*p, const svector<NetNet*>&po)
|
||||||
: name_(n), proc_(p)
|
: name_(n), proc_(p), ports_(po)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -978,6 +976,12 @@ NetTaskDef::~NetTaskDef()
|
||||||
delete proc_;
|
delete proc_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet* NetTaskDef::port(unsigned idx)
|
||||||
|
{
|
||||||
|
assert(idx < ports_.count());
|
||||||
|
return ports_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
NetUDP::NetUDP(const string&n, unsigned pins, bool sequ)
|
NetUDP::NetUDP(const string&n, unsigned pins, bool sequ)
|
||||||
: NetNode(n, pins), sequential_(sequ), init_('x')
|
: NetNode(n, pins), sequential_(sequ), init_('x')
|
||||||
{
|
{
|
||||||
|
|
@ -1479,6 +1483,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.48 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.47 1999/07/18 21:17:50 steve
|
* Revision 1.47 1999/07/18 21:17:50 steve
|
||||||
* Add support for CE input to XNF DFF, and do
|
* Add support for CE input to XNF DFF, and do
|
||||||
* complete cleanup of replaced design nodes.
|
* complete cleanup of replaced design nodes.
|
||||||
|
|
|
||||||
24
netlist.h
24
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.50 1999/07/18 21:17:50 steve Exp $"
|
#ident "$Id: netlist.h,v 1.51 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -217,8 +217,8 @@ class NetNode : public NetObj {
|
||||||
class NetNet : public NetObj, public LineInfo {
|
class NetNet : public NetObj, public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Type { IMPLICIT, WIRE, TRI, TRI1, SUPPLY0, WAND, TRIAND,
|
enum Type { IMPLICIT, IMPLICIT_REG, WIRE, TRI, TRI1, SUPPLY0,
|
||||||
TRI0, SUPPLY1, WOR, TRIOR, REG, INTEGER };
|
WAND, TRIAND, TRI0, SUPPLY1, WOR, TRIOR, REG, INTEGER };
|
||||||
|
|
||||||
enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT };
|
enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT };
|
||||||
|
|
||||||
|
|
@ -885,17 +885,21 @@ class NetSTask : public NetProc {
|
||||||
class NetTaskDef {
|
class NetTaskDef {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetTaskDef(const string&n, NetProc*p);
|
NetTaskDef(const string&n, NetProc*p, const svector<NetNet*>&po);
|
||||||
~NetTaskDef();
|
~NetTaskDef();
|
||||||
|
|
||||||
const string& name() const { return name_; }
|
const string& name() const { return name_; }
|
||||||
const NetProc*proc() const { return proc_; }
|
const NetProc*proc() const { return proc_; }
|
||||||
|
|
||||||
|
unsigned port_count() const { return ports_.count(); }
|
||||||
|
NetNet*port(unsigned idx);
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string name_;
|
string name_;
|
||||||
NetProc*proc_;
|
NetProc*proc_;
|
||||||
|
svector<NetNet*>ports_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
NetTaskDef(const NetTaskDef&);
|
NetTaskDef(const NetTaskDef&);
|
||||||
|
|
@ -903,26 +907,21 @@ class NetTaskDef {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A call to a user defined task is elaborated into this object. I
|
* A call to a user defined task is elaborated into this object.
|
||||||
* save the parameters and the pointer to the task definition.
|
|
||||||
*/
|
*/
|
||||||
class NetUTask : public NetProc {
|
class NetUTask : public NetProc {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetUTask(NetTaskDef*, const svector<NetExpr*>&);
|
NetUTask(NetTaskDef*);
|
||||||
~NetUTask();
|
~NetUTask();
|
||||||
|
|
||||||
const string& name() const { return task_->name(); }
|
const string& name() const { return task_->name(); }
|
||||||
unsigned nparms() const { return parms_.count(); }
|
|
||||||
|
|
||||||
const NetExpr* parm(unsigned idx) const;
|
|
||||||
|
|
||||||
virtual void emit_proc(ostream&, struct target_t*) const;
|
virtual void emit_proc(ostream&, struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetTaskDef*task_;
|
NetTaskDef*task_;
|
||||||
svector<NetExpr*>parms_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1376,6 +1375,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.51 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.50 1999/07/18 21:17:50 steve
|
* Revision 1.50 1999/07/18 21:17:50 steve
|
||||||
* Add support for CE input to XNF DFF, and do
|
* Add support for CE input to XNF DFF, and do
|
||||||
* complete cleanup of replaced design nodes.
|
* complete cleanup of replaced design nodes.
|
||||||
|
|
|
||||||
37
netlist.txt
37
netlist.txt
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ident "$Id: netlist.txt,v 1.2 1999/07/21 01:15:29 steve Exp $"
|
#ident "$Id: netlist.txt,v 1.3 1999/07/24 02:11:20 steve Exp $"
|
||||||
|
|
||||||
|
|
||||||
Note that the netlist.h header contains detailed descriptions of how
|
Note that the netlist.h header contains detailed descriptions of how
|
||||||
|
|
@ -155,10 +155,43 @@ connect to and receive signals from the structural aspects of the
|
||||||
design.
|
design.
|
||||||
|
|
||||||
The pins of a NetESignal object are passive. The values at the pin are
|
The pins of a NetESignal object are passive. The values at the pin are
|
||||||
only sampled with the process evaluates the expression that includes
|
only sampled when the process evaluates the expression that includes
|
||||||
the NetESignal object.
|
the NetESignal object.
|
||||||
|
|
||||||
|
HIERARCHY IN NETLISTS
|
||||||
|
|
||||||
|
The obvious hierarchical structure of verilog is the module. The
|
||||||
|
Verilog program may contain any number of instantiations of modules in
|
||||||
|
order to form an hierarchical design. However, the elaboration of the
|
||||||
|
design into a netlist erases module boundaries. Modules are expanded
|
||||||
|
each place they are used, with the hierarchical instance name used to
|
||||||
|
name the components of the module instance. However, the fact that a
|
||||||
|
wire or register is a module port is lost.
|
||||||
|
|
||||||
|
The advantage of this behavior is first the simplification of the
|
||||||
|
netlist structure itself. Backends that process netlists only need to
|
||||||
|
cope with a list of nets, a list of nodes and a list of
|
||||||
|
processes. This eases the task of the backend code generators.
|
||||||
|
|
||||||
|
Another advantage of this flattening of the netlist is that optimizers
|
||||||
|
can operate globally, with optimizations freely crossing module
|
||||||
|
boundaries. This makes coding of netlist transform functions such as
|
||||||
|
constant propagation more effective and easier to write.
|
||||||
|
|
||||||
|
TASKS IN NETLISTS
|
||||||
|
|
||||||
|
The flattening of the design does not include tasks and named
|
||||||
|
begin-end blocks. Tasks are behavioral hierarchy (whereas modules are
|
||||||
|
structural) so do not easily succumb to the flattening process. In
|
||||||
|
particular, it is logically impossible to flatten tasks that
|
||||||
|
recurse. (The elaboration process does reserve the right to flatten
|
||||||
|
some task calls. C++ programmers recognize this as inlining a task.)
|
||||||
|
|
||||||
|
|
||||||
$Log: netlist.txt,v $
|
$Log: netlist.txt,v $
|
||||||
|
Revision 1.3 1999/07/24 02:11:20 steve
|
||||||
|
Elaborate task input ports.
|
||||||
|
|
||||||
Revision 1.2 1999/07/21 01:15:29 steve
|
Revision 1.2 1999/07/21 01:15:29 steve
|
||||||
Document netlist semantics.
|
Document netlist semantics.
|
||||||
|
|
||||||
|
|
|
||||||
32
parse.y
32
parse.y
|
|
@ -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: parse.y,v 1.51 1999/07/12 00:59:36 steve Exp $"
|
#ident "$Id: parse.y,v 1.52 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "parse_misc.h"
|
# include "parse_misc.h"
|
||||||
|
|
@ -107,6 +107,7 @@ extern void lex_end_table();
|
||||||
|
|
||||||
%type <wire> port
|
%type <wire> port
|
||||||
%type <wires> list_of_ports list_of_ports_opt
|
%type <wires> list_of_ports list_of_ports_opt
|
||||||
|
%type <wires> task_item task_item_list task_item_list_opt
|
||||||
|
|
||||||
%type <portname> port_name
|
%type <portname> port_name
|
||||||
%type <portnames> port_name_list
|
%type <portnames> port_name_list
|
||||||
|
|
@ -1542,32 +1543,53 @@ statement_opt
|
||||||
|
|
||||||
task_body
|
task_body
|
||||||
: task_item_list_opt statement_opt
|
: task_item_list_opt statement_opt
|
||||||
{ PTask*tmp = new PTask($2);
|
{ PTask*tmp = new PTask($1, $2);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
task_item
|
task_item
|
||||||
: block_item_decl
|
: block_item_decl
|
||||||
|
{ $$ = 0; }
|
||||||
| K_input range_opt list_of_variables ';'
|
| K_input range_opt list_of_variables ';'
|
||||||
{ yyerror(@1, "Sorry, task input ports not implemented.");
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINPUT, $2, $3);
|
||||||
|
delete $2;
|
||||||
|
delete $3;
|
||||||
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_output range_opt list_of_variables ';'
|
| K_output range_opt list_of_variables ';'
|
||||||
{ yyerror(@1, "Sorry, task output ports not implemented.");
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::POUTPUT, $2, $3);
|
||||||
|
delete $2;
|
||||||
|
delete $3;
|
||||||
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout range_opt list_of_variables ';'
|
| K_inout range_opt list_of_variables ';'
|
||||||
{ yyerror(@1, "Sorry, task inout ports not implemented.");
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINOUT, $2, $3);
|
||||||
|
delete $2;
|
||||||
|
delete $3;
|
||||||
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
task_item_list
|
task_item_list
|
||||||
: task_item_list task_item
|
: task_item_list task_item
|
||||||
|
{ svector<PWire*>*tmp = new svector<PWire*>(*$1, *$2);
|
||||||
|
delete $1;
|
||||||
|
delete $2;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| task_item
|
| task_item
|
||||||
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
task_item_list_opt
|
task_item_list_opt
|
||||||
: task_item_list
|
: task_item_list
|
||||||
|
{ $$ = $1; }
|
||||||
|
|
|
|
||||||
|
{ $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
udp_body
|
udp_body
|
||||||
|
|
|
||||||
74
pform.cc
74
pform.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: pform.cc,v 1.32 1999/07/10 01:03:18 steve Exp $"
|
#ident "$Id: pform.cc,v 1.33 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
|
|
@ -426,6 +426,63 @@ void pform_set_port_type(const string&name, NetNet::PortType pt)
|
||||||
VLerror("error setting port direction.");
|
VLerror("error setting port direction.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called by the parser to create task ports. The
|
||||||
|
* resulting wire (which should be a register) is put into a list to
|
||||||
|
* be packed into the task parameter list.
|
||||||
|
*
|
||||||
|
* It is possible that the wire (er, register) was already created,
|
||||||
|
* but we know that if the name matches it is a part of the current
|
||||||
|
* task, so in that case I just assign direction to it.
|
||||||
|
*
|
||||||
|
* The following example demonstrates some if the issues:
|
||||||
|
*
|
||||||
|
* task foo;
|
||||||
|
* input a;
|
||||||
|
* reg a, b;
|
||||||
|
* input b;
|
||||||
|
* [...]
|
||||||
|
* endtask
|
||||||
|
*
|
||||||
|
* This function is called when the parser matches the "input a" and
|
||||||
|
* the "input b" statements. For ``a'', this function is called before
|
||||||
|
* the wire is declared as a register, so I create the foo.a
|
||||||
|
* wire. For ``b'', I will find that there is already a foo.b and I
|
||||||
|
* just set the port direction. In either case, the ``reg a, b''
|
||||||
|
* statement is caught by the block_item non-terminal and processed there.
|
||||||
|
*/
|
||||||
|
svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
|
const svector<PExpr*>*range,
|
||||||
|
const list<string>*names)
|
||||||
|
{
|
||||||
|
svector<PWire*>*res = new svector<PWire*>(0);
|
||||||
|
for (list<string>::const_iterator cur = names->begin()
|
||||||
|
; cur != names->end() ; cur ++ ) {
|
||||||
|
|
||||||
|
string name = scoped_name(*cur);
|
||||||
|
|
||||||
|
/* Look for a preexisting wire. If it exists, set the
|
||||||
|
port direction. If not, create it. */
|
||||||
|
PWire*curw = pform_cur_module->get_wire(name);
|
||||||
|
if (curw) {
|
||||||
|
curw->set_port_type(pt);
|
||||||
|
} else {
|
||||||
|
curw = new PWire(name, NetNet::IMPLICIT_REG, pt);
|
||||||
|
pform_cur_module->add_wire(curw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is a range involved, it needs to be set. */
|
||||||
|
if (range)
|
||||||
|
curw->set_range((*range)[0], (*range)[1]);
|
||||||
|
|
||||||
|
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
|
||||||
|
delete res;
|
||||||
|
res = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void pform_set_task(const string&name, PTask*task)
|
void pform_set_task(const string&name, PTask*task)
|
||||||
{
|
{
|
||||||
pform_cur_module->add_task(name, task);
|
pform_cur_module->add_task(name, task);
|
||||||
|
|
@ -554,18 +611,6 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st)
|
||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
Statement* pform_make_calltask(string*name, svector<PExpr*>*parms)
|
|
||||||
{
|
|
||||||
if (parms == 0)
|
|
||||||
parms = new svector<PExpr*>(0);
|
|
||||||
|
|
||||||
PCallTask*ct = new PCallTask(*name, *parms);
|
|
||||||
delete name;
|
|
||||||
delete parms;
|
|
||||||
return ct;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FILE*vl_input = 0;
|
FILE*vl_input = 0;
|
||||||
int pform_parse(const char*path, map<string,Module*>&modules,
|
int pform_parse(const char*path, map<string,Module*>&modules,
|
||||||
|
|
@ -593,6 +638,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.cc,v $
|
* $Log: pform.cc,v $
|
||||||
|
* Revision 1.33 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.32 1999/07/10 01:03:18 steve
|
* Revision 1.32 1999/07/10 01:03:18 steve
|
||||||
* remove string from lexical phase.
|
* remove string from lexical phase.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
13
pform.h
13
pform.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: pform.h,v 1.23 1999/07/10 01:03:18 steve Exp $"
|
#ident "$Id: pform.h,v 1.24 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -145,6 +145,14 @@ extern void pform_make_modgates(const string&type, svector<lgate>*gates);
|
||||||
/* Make a continuous assignment node, with optional bit- or part- select. */
|
/* Make a continuous assignment node, with optional bit- or part- select. */
|
||||||
extern PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval);
|
extern PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval);
|
||||||
|
|
||||||
|
|
||||||
|
/* Given a port type and a list of names, make a list of wires that
|
||||||
|
can be used as task port information. */
|
||||||
|
extern svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
|
const svector<PExpr*>*range,
|
||||||
|
const list<string>*names);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are functions that the outside-the-parser code uses the do
|
* These are functions that the outside-the-parser code uses the do
|
||||||
* interesting things to the verilog. The parse function reads and
|
* interesting things to the verilog. The parse function reads and
|
||||||
|
|
@ -157,6 +165,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.h,v $
|
* $Log: pform.h,v $
|
||||||
|
* Revision 1.24 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.23 1999/07/10 01:03:18 steve
|
* Revision 1.23 1999/07/10 01:03:18 steve
|
||||||
* remove string from lexical phase.
|
* remove string from lexical phase.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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: pform_dump.cc,v 1.28 1999/07/17 19:51:00 steve Exp $"
|
#ident "$Id: pform_dump.cc,v 1.29 1999/07/24 02:11:20 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -409,6 +409,22 @@ void PRepeat::dump(ostream&out, unsigned ind) const
|
||||||
|
|
||||||
void PTask::dump(ostream&out, unsigned ind) const
|
void PTask::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
|
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||||
|
out << setw(ind) << "";
|
||||||
|
switch ((*ports_)[idx]->get_port_type()) {
|
||||||
|
case NetNet::PINPUT:
|
||||||
|
out << "input ";
|
||||||
|
break;
|
||||||
|
case NetNet::POUTPUT:
|
||||||
|
out << "output ";
|
||||||
|
break;
|
||||||
|
case NetNet::PINOUT:
|
||||||
|
out << "inout ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out << (*ports_)[idx]->name() << ";" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
statement_->dump(out, ind);
|
statement_->dump(out, ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -530,6 +546,9 @@ void PUdp::dump(ostream&out) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform_dump.cc,v $
|
* $Log: pform_dump.cc,v $
|
||||||
|
* Revision 1.29 1999/07/24 02:11:20 steve
|
||||||
|
* Elaborate task input ports.
|
||||||
|
*
|
||||||
* Revision 1.28 1999/07/17 19:51:00 steve
|
* Revision 1.28 1999/07/17 19:51:00 steve
|
||||||
* netlist support for ternary operator.
|
* netlist support for ternary operator.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue