Handle mutual reference of tasks by elaborating

task definitions in two passes, like functions.
This commit is contained in:
steve 1999-09-30 21:28:34 +00:00
parent f068196272
commit efa5222c66
5 changed files with 119 additions and 31 deletions

14
PTask.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PTask.h,v 1.5 1999/09/01 20:46:19 steve Exp $"
#ident "$Id: PTask.h,v 1.6 1999/09/30 21:28:34 steve Exp $"
#endif
# include "LineInfo.h"
@ -38,7 +38,9 @@ class PTask : public LineInfo {
explicit PTask(svector<PWire*>*p, Statement*s);
~PTask();
virtual void elaborate(Design*des, const string&path) const;
void elaborate_1(Design*des, const string&path) const;
void elaborate_2(Design*des, const string&path) const;
void dump(ostream&, unsigned) const;
private:
@ -64,8 +66,8 @@ class PFunction : public LineInfo {
void set_output(PWire*);
/* 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 elaborate_1(Design *des, const string &path) const;
void elaborate_2(Design *des, const string &path) const;
void dump(ostream&, unsigned) const;
@ -77,6 +79,10 @@ class PFunction : public LineInfo {
/*
* $Log: PTask.h,v $
* Revision 1.6 1999/09/30 21:28:34 steve
* Handle mutual reference of tasks by elaborating
* task definitions in two passes, like functions.
*
* Revision 1.5 1999/09/01 20:46:19 steve
* Handle recursive functions and arbitrary function
* references to other functions, properly pass

View File

@ -252,12 +252,31 @@ current state of support for Verilog.
- force/release/assign/deassign procedural assignments not
supported.
- block disable not supported, i.e.:
begin : foo
[...]
disable foo; // sorry
[...]
end
- fork/join is not supported in vvm runtime
- structural arithmetic operators are in general not supported.
assign foo = a + b; // sorry
always @(a or b) foo = a + b; // OK
- Functions in structural contexts are not supported.
assign foo = user_function(a,b); // sorry
always @(a or b) foo = user_function(a,b); // OK
- multiplicative operators (*, /, %) are not supported.
assign foo = a * b; // sorry
always @(a or b) foo = a * b; // sorry
- event data type is not supported.
- real data type not supported.
@ -265,6 +284,14 @@ current state of support for Verilog.
- system functions are not supported. (User defined functions are
supported, and system tasks are supported.)
assign foo = $some_function(a,b); // sorry
always @(a or b) foo = $some_function(a,b); // sorry
- non-constant delay expressions, i.e.:
reg [7:0] del;
always #(reg) $display($time,,"del = %d", del); // sorry
Specify blocks are parsed but ignored in general.

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.106 1999/09/30 17:22:33 steve Exp $"
#ident "$Id: elaborate.cc,v 1.107 1999/09/30 21:28:34 steve Exp $"
#endif
/*
@ -1921,16 +1921,16 @@ NetProc* PCallTask::elaborate_sys(Design*des, const string&path) const
*/
NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
{
NetTaskDef*def = des->find_task(path + "." + name_);
NetTaskDef*def = des->find_task(path, name_);
if (def == 0) {
cerr << get_line() << ": Enable of unknown task ``" <<
name_ << "''." << endl;
cerr << get_line() << ": error: Enable of unknown task ``" <<
path << "." << name_ << "''." << endl;
des->errors += 1;
return 0;
}
if (nparms() != def->port_count()) {
cerr << get_line() << ": Port count mismatch in call to ``"
cerr << get_line() << ": error: Port count mismatch in call to ``"
<< name_ << "''." << endl;
des->errors += 1;
return 0;
@ -2226,7 +2226,7 @@ void PFunction::elaborate_2(Design*des, const string&path) const
NetProc*st = statement_->elaborate(des, path);
if (st == 0) {
cerr << statement_->get_line() << ": Unable to elaborate "
cerr << statement_->get_line() << ": error: Unable to elaborate "
"statement in function " << path << "." << endl;
des->errors += 1;
return;
@ -2280,8 +2280,29 @@ NetProc* PRepeat::elaborate(Design*des, const string&path) const
* 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_1(Design*des, const string&path) const
{
/* 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() : 0);
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, ports);
des->add_task(path, def);
}
void PTask::elaborate_2(Design*des, const string&path) const
{
NetTaskDef*def = des->find_task(path);
assert(def);
NetProc*st;
if (statement_ == 0) {
cerr << get_line() << ": warning: task has no statement." << endl;
@ -2298,20 +2319,7 @@ void PTask::elaborate(Design*des, const string&path) const
}
}
/* 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() : 0);
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);
def->set_proc(st);
}
/*
@ -2432,10 +2440,17 @@ bool Module::elaborate(Design*des, const string&path, svector<PExpr*>*overrides_
// behaviors so that task calls may reference these, and after
// the signals so that the tasks can reference them.
typedef map<string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
string pname = path + "." + (*cur).first;
(*cur).second->elaborate(des, pname);
(*cur).second->elaborate_1(des, pname);
}
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
string pname = path + "." + (*cur).first;
(*cur).second->elaborate_2(des, pname);
}
// Get all the gates of the module and elaborate them by
@ -2513,6 +2528,10 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.107 1999/09/30 21:28:34 steve
* Handle mutual reference of tasks by elaborating
* task definitions in two passes, like functions.
*
* Revision 1.106 1999/09/30 17:22:33 steve
* catch non-constant delays as unsupported.
*

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.71 1999/09/29 18:36:03 steve Exp $"
#ident "$Id: netlist.cc,v 1.72 1999/09/30 21:28:34 steve Exp $"
#endif
# include <cassert>
@ -1090,8 +1090,8 @@ const NetExpr* NetRepeat::expr() const
return expr_;
}
NetTaskDef::NetTaskDef(const string&n, NetProc*p, const svector<NetNet*>&po)
: name_(n), proc_(p), ports_(po)
NetTaskDef::NetTaskDef(const string&n, const svector<NetNet*>&po)
: name_(n), proc_(0), ports_(po)
{
}
@ -1100,6 +1100,12 @@ NetTaskDef::~NetTaskDef()
delete proc_;
}
void NetTaskDef::set_proc(NetProc*p)
{
assert(proc_ == 0);
proc_ = p;
}
NetNet* NetTaskDef::port(unsigned idx)
{
assert(idx < ports_.count());
@ -1530,6 +1536,25 @@ void Design::add_task(const string&key, NetTaskDef*def)
tasks_[key] = def;
}
NetTaskDef* Design::find_task(const string&path, const string&name)
{
string root = path;
for (;;) {
string key = root + "." + name;
map<string,NetTaskDef*>::const_iterator cur = tasks_.find(key);
if (cur != tasks_.end())
return (*cur).second;
unsigned pos = root.rfind('.');
if (pos > root.length())
break;
root = root.substr(0, pos);
}
return 0;
}
NetTaskDef* Design::find_task(const string&key)
{
map<string,NetTaskDef*>::const_iterator cur = tasks_.find(key);
@ -1657,6 +1682,10 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.72 1999/09/30 21:28:34 steve
* Handle mutual reference of tasks by elaborating
* task definitions in two passes, like functions.
*
* Revision 1.71 1999/09/29 18:36:03 steve
* Full case support
*

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.75 1999/09/30 02:43:02 steve Exp $"
#ident "$Id: netlist.h,v 1.76 1999/09/30 21:28:34 steve Exp $"
#endif
/*
@ -991,9 +991,11 @@ class NetSTask : public NetProc {
class NetTaskDef {
public:
NetTaskDef(const string&n, NetProc*p, const svector<NetNet*>&po);
NetTaskDef(const string&n, const svector<NetNet*>&po);
~NetTaskDef();
void set_proc(NetProc*p);
const string& name() const { return name_; }
const NetProc*proc() const { return proc_; }
@ -1602,6 +1604,7 @@ class Design {
// Tasks
void add_task(const string&n, NetTaskDef*);
NetTaskDef* find_task(const string&path, const string&name);
NetTaskDef* find_task(const string&key);
// NODES
@ -1704,6 +1707,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.76 1999/09/30 21:28:34 steve
* Handle mutual reference of tasks by elaborating
* task definitions in two passes, like functions.
*
* Revision 1.75 1999/09/30 02:43:02 steve
* Elaborate ~^ and ~| operators.
*