diff --git a/PTask.h b/PTask.h index 8b07ea897..f136cdb34 100644 --- a/PTask.h +++ b/PTask.h @@ -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*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 diff --git a/README.txt b/README.txt index b3f5c3522..154656032 100644 --- a/README.txt +++ b/README.txt @@ -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. diff --git a/elaborate.cc b/elaborate.cc index f8b5d207f..94d81d95e 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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.) */ + svectorports (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.) */ - svectorports (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*overrides_ // behaviors so that task calls may reference these, and after // the signals so that the tasks can reference them. typedef map::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&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. * diff --git a/netlist.cc b/netlist.cc index 474e88b46..c8a11dc41 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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 @@ -1090,8 +1090,8 @@ const NetExpr* NetRepeat::expr() const return expr_; } -NetTaskDef::NetTaskDef(const string&n, NetProc*p, const svector&po) -: name_(n), proc_(p), ports_(po) +NetTaskDef::NetTaskDef(const string&n, const svector&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::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::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 * diff --git a/netlist.h b/netlist.h index d3e2bc11b..b3c30ce27 100644 --- a/netlist.h +++ b/netlist.h @@ -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&po); + NetTaskDef(const string&n, const svector&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. *