Named events really should be expressed with PEIdent

objects in the pform,

 Handle named events within the mix of net events
 and edges. As a unified lot they get caught together.
 wait statements are broken into more complex statements
 that include a conditional.

 Do not generate NetPEvent or NetNEvent objects in
 elaboration. NetEvent, NetEvWait and NetEvProbe
 take over those functions in the netlist.
This commit is contained in:
steve 2000-04-12 04:23:57 +00:00
parent b0d0cdbd7d
commit b1fd927acb
16 changed files with 492 additions and 325 deletions

View File

@ -17,13 +17,17 @@
* 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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.cc,v 1.15 2000/04/01 19:31:57 steve Exp $" #ident "$Id: PExpr.cc,v 1.16 2000/04/12 04:23:57 steve Exp $"
#endif #endif
# include "PExpr.h" # include "PExpr.h"
# include "Module.h" # include "Module.h"
# include <typeinfo> # include <typeinfo>
PExpr::PExpr()
{
}
PExpr::~PExpr() PExpr::~PExpr()
{ {
} }
@ -69,6 +73,11 @@ PECallFunction::~PECallFunction()
{ {
} }
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), repeat_(r)
{
}
bool PEConcat::is_constant(Module *mod) const bool PEConcat::is_constant(Module *mod) const
{ {
bool constant = repeat_? repeat_->is_constant(mod) : true; bool constant = repeat_? repeat_->is_constant(mod) : true;
@ -83,21 +92,16 @@ PEConcat::~PEConcat()
delete repeat_; delete repeat_;
} }
PEEvent::PEEvent(NetNEvent::Type t, PExpr*e) PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e)
: type_(t), expr_(e) : type_(t), expr_(e)
{ {
} }
PEEvent::PEEvent(const string&n)
: name_(n)
{
}
PEEvent::~PEEvent() PEEvent::~PEEvent()
{ {
} }
NetNEvent::Type PEEvent::type() const PEEvent::edge_t PEEvent::type() const
{ {
return type_; return type_;
} }
@ -107,9 +111,18 @@ PExpr* PEEvent::expr() const
return expr_; return expr_;
} }
string PEEvent::name() const PEIdent::PEIdent(const string&s)
: text_(s), msb_(0), lsb_(0), idx_(0)
{ {
return name_; }
PEIdent::~PEIdent()
{
}
string PEIdent::name() const
{
return text_;
} }
/* /*
@ -129,6 +142,22 @@ bool PEIdent::is_constant(Module*mod) const
return false; return false;
} }
PENumber::PENumber(verinum*vp)
: value_(vp)
{
assert(vp);
}
PENumber::~PENumber()
{
delete value_;
}
const verinum& PENumber::value() const
{
return *value_;
}
bool PENumber::is_the_same(const PExpr*that) const bool PENumber::is_the_same(const PExpr*that) const
{ {
const PENumber*obj = dynamic_cast<const PENumber*>(that); const PENumber*obj = dynamic_cast<const PENumber*>(that);
@ -143,6 +172,20 @@ bool PENumber::is_constant(Module*) const
return true; return true;
} }
PEString::PEString(const string&s)
: text_(s)
{
}
PEString::~PEString()
{
}
string PEString::value() const
{
return text_;
}
bool PEString::is_constant(Module*) const bool PEString::is_constant(Module*) const
{ {
return true; return true;
@ -164,6 +207,19 @@ bool PETernary::is_constant(Module*) const
/* /*
* $Log: PExpr.cc,v $ * $Log: PExpr.cc,v $
* Revision 1.16 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.15 2000/04/01 19:31:57 steve * Revision 1.15 2000/04/01 19:31:57 steve
* Named events as far as the pform. * Named events as far as the pform.
* *

59
PExpr.h
View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.h,v 1.34 2000/04/01 21:40:22 steve Exp $" #ident "$Id: PExpr.h,v 1.35 2000/04/12 04:23:57 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -44,7 +44,9 @@ class NetScope;
*/ */
class PExpr : public LineInfo { class PExpr : public LineInfo {
public: public:
PExpr();
virtual ~PExpr(); virtual ~PExpr();
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -86,6 +88,9 @@ class PExpr : public LineInfo {
// of expresions. // of expresions.
virtual bool is_constant(Module*) const; virtual bool is_constant(Module*) const;
private: // not implemented
PExpr(const PExpr&);
PExpr& operator= (const PExpr&);
}; };
ostream& operator << (ostream&, const PExpr&); ostream& operator << (ostream&, const PExpr&);
@ -93,8 +98,7 @@ ostream& operator << (ostream&, const PExpr&);
class PEConcat : public PExpr { class PEConcat : public PExpr {
public: public:
PEConcat(const svector<PExpr*>&p, PExpr*r =0) PEConcat(const svector<PExpr*>&p, PExpr*r =0);
: parms_(p), repeat_(r) { }
~PEConcat(); ~PEConcat();
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -122,30 +126,28 @@ class PEConcat : public PExpr {
class PEEvent : public PExpr { class PEEvent : public PExpr {
public: public:
enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE};
// Use this constructor to create events based on edges or levels. // Use this constructor to create events based on edges or levels.
PEEvent(NetNEvent::Type t, PExpr*e); PEEvent(edge_t t, PExpr*e);
// Use this to create named events.
PEEvent(const string&n);
~PEEvent(); ~PEEvent();
NetNEvent::Type type() const; edge_t type() const;
PExpr* expr() const; PExpr* expr() const;
string name() const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
private: private:
NetNEvent::Type type_; edge_t type_;
PExpr*expr_; PExpr *expr_;
string name_;
}; };
class PEIdent : public PExpr { class PEIdent : public PExpr {
public: public:
explicit PEIdent(const string&s) explicit PEIdent(const string&s);
: text_(s), msb_(0), lsb_(0), idx_(0) { } ~PEIdent();
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -165,8 +167,7 @@ class PEIdent : public PExpr {
virtual bool is_constant(Module*) const; virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const string&path) const; verinum* eval_const(const Design*des, const string&path) const;
// XXXX string name() const;
string name() const { return text_; }
private: private:
string text_; string text_;
@ -190,11 +191,10 @@ class PEIdent : public PExpr {
class PENumber : public PExpr { class PENumber : public PExpr {
public: public:
explicit PENumber(verinum*vp) explicit PENumber(verinum*vp);
: value_(vp) { assert(vp); } ~PENumber();
~PENumber() { delete value_; }
const verinum& value() const { return *value_; } const verinum& value() const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
@ -216,10 +216,10 @@ class PENumber : public PExpr {
class PEString : public PExpr { class PEString : public PExpr {
public: public:
explicit PEString(const string&s) explicit PEString(const string&s);
: text_(s) { } ~PEString();
string value() const { return text_; } string value() const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
@ -358,6 +358,19 @@ class PECallFunction : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $Log: PExpr.h,v $
* Revision 1.35 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.34 2000/04/01 21:40:22 steve * Revision 1.34 2000/04/01 21:40:22 steve
* Add support for integer division. * Add support for integer division.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.cc,v 1.18 2000/04/01 19:31:57 steve Exp $" #ident "$Id: Statement.cc,v 1.19 2000/04/12 04:23:57 steve Exp $"
#endif #endif
# include "Statement.h" # include "Statement.h"
@ -122,6 +122,11 @@ PCase::~PCase()
delete[]items_; delete[]items_;
} }
PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
: expr_(ex), if_(i), else_(e)
{
}
PCondit::~PCondit() PCondit::~PCondit()
{ {
delete expr_; delete expr_;
@ -129,6 +134,17 @@ PCondit::~PCondit()
delete else_; delete else_;
} }
PDelayStatement::PDelayStatement(PExpr*d, Statement*st)
: delay_(d), statement_(st)
{
}
PDelayStatement::~PDelayStatement()
{
}
PEventStatement::PEventStatement(const svector<PEEvent*>&ee) PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0) : expr_(ee), statement_(0)
{ {
@ -146,6 +162,11 @@ PEventStatement::~PEventStatement()
// delete the events and the statement? // delete the events and the statement?
} }
void PEventStatement::set_statement(Statement*st)
{
statement_ = st;
}
PForever::PForever(Statement*s) PForever::PForever(Statement*s)
: statement_(s) : statement_(s)
{ {
@ -189,6 +210,19 @@ PWhile::~PWhile()
/* /*
* $Log: Statement.cc,v $ * $Log: Statement.cc,v $
* Revision 1.19 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.18 2000/04/01 19:31:57 steve * Revision 1.18 2000/04/01 19:31:57 steve
* Named events as far as the pform. * Named events as far as the pform.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.h,v 1.23 2000/04/01 19:31:57 steve Exp $" #ident "$Id: Statement.h,v 1.24 2000/04/12 04:23:57 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -225,8 +225,7 @@ class PCase : public Statement {
class PCondit : public Statement { class PCondit : public Statement {
public: public:
PCondit(PExpr*ex, Statement*i, Statement*e) PCondit(PExpr*ex, Statement*i, Statement*e);
: expr_(ex), if_(i), else_(e) { }
~PCondit(); ~PCondit();
virtual NetProc* elaborate(Design*des, const string&path) const; virtual NetProc* elaborate(Design*des, const string&path) const;
@ -246,8 +245,8 @@ class PCondit : public Statement {
class PDelayStatement : public Statement { class PDelayStatement : public Statement {
public: public:
PDelayStatement(PExpr*d, Statement*st) PDelayStatement(PExpr*d, Statement*st);
: delay_(d), statement_(st) { } ~PDelayStatement();
virtual void dump(ostream&out, unsigned ind) const; virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const; virtual NetProc* elaborate(Design*des, const string&path) const;
@ -274,7 +273,7 @@ class PEventStatement : public Statement {
~PEventStatement(); ~PEventStatement();
void set_statement(Statement*st) { statement_ = st; } void set_statement(Statement*st);
virtual void dump(ostream&out, unsigned ind) const; virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const; virtual NetProc* elaborate(Design*des, const string&path) const;
@ -382,6 +381,19 @@ class PWhile : public Statement {
/* /*
* $Log: Statement.h,v $ * $Log: Statement.h,v $
* Revision 1.24 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.23 2000/04/01 19:31:57 steve * Revision 1.23 2000/04/01 19:31:57 steve
* Named events as far as the pform. * Named events as far as the pform.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.74 2000/04/10 05:26:05 steve Exp $" #ident "$Id: design_dump.cc,v 1.75 2000/04/12 04:23:57 steve Exp $"
#endif #endif
/* /*
@ -555,8 +555,14 @@ void NetEvTrig::dump(ostream&o, unsigned ind) const
void NetEvWait::dump(ostream&o, unsigned ind) const void NetEvWait::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "@" << event_->name() assert(nevents() > 0);
<< " // " << get_line() << endl; o << setw(ind) <<"" << "@(" << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << event(idx)->name();
o << ") // " << get_line() << endl;
if (statement_) if (statement_)
statement_->dump(o, ind+2); statement_->dump(o, ind+2);
else else
@ -948,6 +954,19 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.75 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.74 2000/04/10 05:26:05 steve * Revision 1.74 2000/04/10 05:26:05 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elaborate.cc,v 1.157 2000/04/10 05:26:06 steve Exp $" #ident "$Id: elaborate.cc,v 1.158 2000/04/12 04:23:58 steve Exp $"
#endif #endif
/* /*
@ -1541,12 +1541,66 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
* *
* NetEvWait ---/---> NetEvent <----\---- NetEvProbe * NetEvWait ---/---> NetEvent <----\---- NetEvProbe
* ... | | ... * ... | | ...
* NetEvWait ---+ +-----NetEvProbe * NetEvWait ---+ +---- NetEvProbe
* | ...
* +---- NetEvTrig
* *
* That is, many NetEvWait statements may wait on a single NetEvent * That is, many NetEvWait statements may wait on a single NetEvent
* object, and Many NetEvProbe objects may trigger the NetEvent * object, and Many NetEvProbe objects may trigger the NetEvent
* object. * object. The many NetEvWait objects pointing to the NetEvent object
* reflects the possibility of different places in the code blocking
* on the same named event, like so:
*
* event foo;
* [...]
* always begin @foo <statement1>; @foo <statement2> end
*
* This tends to not happen with signal edges. The multiple probes
* pointing to the same event reflect the possibility of many
* expressions in the same blocking statement, like so:
*
* wire reset, clk;
* [...]
* always @(reset or posedge clk) <stmt>;
*
* Conjunctions like this cause a NetEvent object be created to
* represent the overall conjuction, and NetEvProbe objects for each
* event expression.
*
* If the NetEvent object represents a named event from the source,
* then there are NetEvTrig objects that represent the trigger
* statements instead of the NetEvProbe objects representing signals.
* For example:
*
* event foo;
* always @foo <stmt>;
* initial begin
* [...]
* -> foo;
* [...]
* -> foo;
* [...]
* end
*
* Each trigger statement in the source generates a separate NetEvTrig
* object in the netlist. Those trigger objects are elaborated
* elsewhere.
*
* Additional complications arise when named events show up in
* conjunctions. An example of such a case is:
*
* event foo;
* wire bar;
* always @(foo or posedge bar) <stmt>;
*
* Since there is by definition a NetEvent object for the foo object,
* this is handled by allowing the NetEvWait object to point to
* multiple NetEvent objects. All the NetEvProbe based objects are
* collected and pointed as the synthetic NetEvent object, and all the
* named events are added into the list of NetEvent object that the
* NetEvWait object can refer to.
*/ */
NetProc* PEventStatement::elaborate_st(Design*des, const string&path, NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetProc*enet) const NetProc*enet) const
{ {
@ -1573,10 +1627,11 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
| |
+---> <statement> +---> <statement>
This is quite a mouthful */ This is quite a mouthful. Should I not move wait handling
to specialized objects? */
if ((expr_.count() == 1) && (expr_[0]->type() == NetNEvent::POSITIVE)) { if ((expr_.count() == 1) && (expr_[0]->type() == PEEvent::POSITIVE)) {
NetBlock*bl = new NetBlock(NetBlock::SEQU); NetBlock*bl = new NetBlock(NetBlock::SEQU);
@ -1592,7 +1647,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetEvent*ev = new NetEvent(scope->local_symbol()); NetEvent*ev = new NetEvent(scope->local_symbol());
scope->add_event(ev); scope->add_event(ev);
NetEvWait*we = new NetEvWait(ev, 0); NetEvWait*we = new NetEvWait(0);
we->add_event(ev);
NetEvProbe*po = new NetEvProbe(path+"."+scope->local_symbol(), NetEvProbe*po = new NetEvProbe(path+"."+scope->local_symbol(),
ev, NetEvProbe::POSEDGE, 1); ev, NetEvProbe::POSEDGE, 1);
@ -1604,34 +1660,26 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetCondit*co = new NetCondit(new NetEUnary('!', ce), we, 0); NetCondit*co = new NetCondit(new NetEUnary('!', ce), we, 0);
bl->append(co); bl->append(co);
bl->append(enet); bl->append(enet);
ev->set_line(*this);
bl->set_line(*this);
we->set_line(*this);
co->set_line(*this);
return bl; return bl;
} }
/* Handle as a special case the block on an event. In this
case I generate a NetEvWait object to represent me. */
if ((expr_.count() == 1) && (expr_[0]->expr() == 0)) {
string ename = expr_[0]->name();
NetEvent*ev = scope->find_event(ename);
if (ev == 0) {
cerr << get_line() << ": error: no such named event "
<< "``" << ename << "''." << endl;
des->errors += 1;
return 0;
}
NetEvWait*pr = new NetEvWait(ev, enet);
pr->set_line(*this);
return pr;
}
/* Handle the special case of an event name as an identifier /* Handle the special case of an event name as an identifier
in an expression. Make a named event reference. */ in an expression. Make a named event reference. */
if (expr_.count() == 1) { if (expr_.count() == 1) {
assert(expr_[0]->expr());
PEIdent*id = dynamic_cast<PEIdent*>(expr_[0]->expr()); PEIdent*id = dynamic_cast<PEIdent*>(expr_[0]->expr());
NetEvent*ev; NetEvent*ev;
if (id && (ev = scope->find_event(id->name()))) { if (id && (ev = scope->find_event(id->name()))) {
NetEvWait*pr = new NetEvWait(ev, enet); NetEvWait*pr = new NetEvWait(enet);
pr->add_event(ev);
pr->set_line(*this); pr->set_line(*this);
return pr; return pr;
} }
@ -1643,28 +1691,32 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
object. */ object. */
NetEvent*ev = new NetEvent(scope->local_symbol()); NetEvent*ev = new NetEvent(scope->local_symbol());
scope->add_event(ev); ev->set_line(*this);
unsigned expr_count = 0;
NetEvWait*wa = new NetEvWait(ev, enet); NetEvWait*wa = new NetEvWait(enet);
wa->set_line(*this);
for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
if (expr_[idx]->expr() == 0) {
cerr << get_line() << ": sorry: block on named events " assert(expr_[idx]->expr());
<< "not supported." << endl;
des->errors += 1; /* If the expression is an identifier that matches a
return 0; named event, then handle this case all at once at
} skip the rest of the expression handling. */
if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) { if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
NetEvent*ev = scope->find_event(id->name()); NetEvent*tmp = scope->find_event(id->name());
if (ev) { if (tmp) {
cerr << get_line() << ": sorry: block on named events " wa->add_event(tmp);
<< "not supported." << endl; continue;
des->errors += 1;
return 0;
} }
} }
/* So now we have a normal event expression. Elaborate
the sub-expression as a net and decide how to handle
the edge. */
NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path, NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path,
0, 0, 0, 0); 0, 0, 0, 0);
if (expr == 0) { if (expr == 0) {
@ -1675,22 +1727,22 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
} }
assert(expr); assert(expr);
unsigned pins = (expr_[idx]->type() == NetNEvent::ANYEDGE) unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE)
? expr->pin_count() : 1; ? expr->pin_count() : 1;
NetEvProbe*pr; NetEvProbe*pr;
switch (expr_[idx]->type()) { switch (expr_[idx]->type()) {
case NetNEvent::POSEDGE: case PEEvent::POSEDGE:
pr = new NetEvProbe(des->local_symbol(path), ev, pr = new NetEvProbe(des->local_symbol(path), ev,
NetEvProbe::POSEDGE, pins); NetEvProbe::POSEDGE, pins);
break; break;
case NetNEvent::NEGEDGE: case PEEvent::NEGEDGE:
pr = new NetEvProbe(des->local_symbol(path), ev, pr = new NetEvProbe(des->local_symbol(path), ev,
NetEvProbe::NEGEDGE, pins); NetEvProbe::NEGEDGE, pins);
break; break;
case NetNEvent::ANYEDGE: case PEEvent::ANYEDGE:
pr = new NetEvProbe(des->local_symbol(path), ev, pr = new NetEvProbe(des->local_symbol(path), ev,
NetEvProbe::ANYEDGE, pins); NetEvProbe::ANYEDGE, pins);
break; break;
@ -1703,6 +1755,17 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
connect(pr->pin(p), expr->pin(p)); connect(pr->pin(p), expr->pin(p));
des->add_node(pr); des->add_node(pr);
expr_count += 1;
}
/* If there was at least one conjunction that was an
expression (and not a named event) then add this
event. Otherwise, we didn't use it so delete it. */
if (expr_count > 0) {
scope->add_event(ev);
wa->add_event(ev);
} else {
delete ev;
} }
return wa; return wa;
@ -2161,6 +2224,19 @@ Design* elaborate(const map<string,Module*>&modules,
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.158 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.157 2000/04/10 05:26:06 steve * Revision 1.157 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

31
emit.cc
View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.38 2000/04/10 05:26:06 steve Exp $" #ident "$Id: emit.cc,v 1.39 2000/04/12 04:23:58 steve Exp $"
#endif #endif
/* /*
@ -110,11 +110,6 @@ void NetRamDq::emit_node(ostream&o, struct target_t*tgt) const
tgt->lpm_ram_dq(o, this); tgt->lpm_ram_dq(o, this);
} }
void NetNEvent::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_event(o, this);
}
void NetBUFZ::emit_node(ostream&o, struct target_t*tgt) const void NetBUFZ::emit_node(ostream&o, struct target_t*tgt) const
{ {
tgt->bufz(o, this); tgt->bufz(o, this);
@ -189,17 +184,6 @@ void NetPDelay::emit_proc_recurse(ostream&o, struct target_t*tgt) const
if (statement_) statement_->emit_proc(o, tgt); if (statement_) statement_->emit_proc(o, tgt);
} }
bool NetPEvent::emit_proc(ostream&o, struct target_t*tgt) const
{
tgt->proc_event(o, this);
return true;
}
void NetPEvent::emit_proc_recurse(ostream&o, struct target_t*tgt) const
{
if (statement_) statement_->emit_proc(o, tgt);
}
bool NetRepeat::emit_proc(ostream&o, struct target_t*tgt) const bool NetRepeat::emit_proc(ostream&o, struct target_t*tgt) const
{ {
tgt->proc_repeat(o, this); tgt->proc_repeat(o, this);
@ -432,6 +416,19 @@ bool emit(ostream&o, const Design*des, const char*type)
/* /*
* $Log: emit.cc,v $ * $Log: emit.cc,v $
* Revision 1.39 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.38 2000/04/10 05:26:06 steve * Revision 1.38 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_event.cc,v 1.2 2000/04/10 05:26:06 steve Exp $" #ident "$Id: net_event.cc,v 1.3 2000/04/12 04:23:58 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -82,23 +82,63 @@ const NetEvent* NetEvProbe::event() const
return event_; return event_;
} }
NetEvWait::NetEvWait(NetEvent*ev, NetProc*pr) NetEvWait::NetEvWait(NetProc*pr)
: event_(ev), statement_(pr) : statement_(pr), nevents_(0), events_(0)
{ {
} }
NetEvWait::~NetEvWait() NetEvWait::~NetEvWait()
{ {
if (events_) delete[]events_;
delete statement_; delete statement_;
} }
const NetEvent* NetEvWait::event() const void NetEvWait::add_event(NetEvent*tgt)
{ {
return event_; assert(tgt);
if (nevents_ == 0) {
events_ = new NetEvent*[1];
} else {
NetEvent**tmp = new NetEvent*[nevents_+1];
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
tmp[idx] = events_[idx];
assert(tmp[idx] != tgt);
}
delete[]events_;
events_ = tmp;
}
events_[nevents_] = tgt;
nevents_ += 1;
}
unsigned NetEvWait::nevents() const
{
return nevents_;
}
const NetEvent* NetEvWait::event(unsigned idx) const
{
assert(idx < nevents_);
return events_[idx];
} }
/* /*
* $Log: net_event.cc,v $ * $Log: net_event.cc,v $
* Revision 1.3 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.2 2000/04/10 05:26:06 steve * Revision 1.2 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.119 2000/04/10 05:26:06 steve Exp $" #ident "$Id: netlist.h,v 1.120 2000/04/12 04:23:58 steve Exp $"
#endif #endif
/* /*
@ -1312,18 +1312,23 @@ class NetEvTrig : public NetProc {
class NetEvWait : public NetProc { class NetEvWait : public NetProc {
public: public:
explicit NetEvWait(NetEvent*tgt, NetProc*st); explicit NetEvWait(NetProc*st);
~NetEvWait(); ~NetEvWait();
const NetEvent*event() const; void add_event(NetEvent*tgt);
unsigned nevents() const;
const NetEvent*event(unsigned) const;
virtual bool emit_proc(ostream&, struct target_t*) const; virtual bool emit_proc(ostream&, struct target_t*) const;
bool emit_recurse(ostream&, struct target_t*) const; bool emit_recurse(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const; virtual void dump(ostream&, unsigned ind) const;
private: private:
NetEvent*event_;
NetProc*statement_; NetProc*statement_;
unsigned nevents_;
NetEvent**events_;
}; };
class NetEvProbe : public NetNode { class NetEvProbe : public NetNode {
@ -1440,11 +1445,8 @@ class NetPEvent : public NetProc {
const NetNEvent* next() const; const NetNEvent* next() const;
virtual int match_proc(struct proc_match_t*); virtual int match_proc(struct proc_match_t*);
virtual bool emit_proc(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const; virtual void dump(ostream&, unsigned ind) const;
void emit_proc_recurse(ostream&, struct target_t*) const;
private: private:
string name_; string name_;
NetProc*statement_; NetProc*statement_;
@ -1477,8 +1479,6 @@ class NetNEvent : public NetNode {
Type type() const; Type type() const;
const NetPEvent*pevent() const; const NetPEvent*pevent() const;
virtual void emit_node(ostream&, struct target_t*) const;
void dump_proc(ostream&) const; void dump_proc(ostream&) const;
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
@ -2399,6 +2399,19 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.120 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.119 2000/04/10 05:26:06 steve * Revision 1.119 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

17
parse.y
View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.88 2000/04/02 04:25:39 steve Exp $" #ident "$Id: parse.y,v 1.89 2000/04/12 04:23:58 steve Exp $"
#endif #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -398,10 +398,11 @@ dr_strength1 : K_supply1 | K_strong1 | K_pull1 | K_weak1 ;
event_control event_control
: '@' IDENTIFIER : '@' IDENTIFIER
{ PEEvent*tmpe = new PEEvent($2); { PEIdent*tmpi = new PEIdent($2);
tmpe->set_file(@2.text); tmpi->set_file(@2.text);
tmpe->set_lineno(@2.first_line); tmpi->set_lineno(@2.first_line);
delete[]$2; delete[]$2;
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
PEventStatement*tmps = new PEventStatement(tmpe); PEventStatement*tmps = new PEventStatement(tmpe);
tmps->set_file(@1.text); tmps->set_file(@1.text);
tmps->set_lineno(@1.first_line); tmps->set_lineno(@1.first_line);
@ -433,7 +434,7 @@ event_expression_list
event_expression event_expression
: K_posedge expression : K_posedge expression
{ PEEvent*tmp = new PEEvent(NetNEvent::POSEDGE, $2); { PEEvent*tmp = new PEEvent(PEEvent::POSEDGE, $2);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
svector<PEEvent*>*tl = new svector<PEEvent*>(1); svector<PEEvent*>*tl = new svector<PEEvent*>(1);
@ -441,7 +442,7 @@ event_expression
$$ = tl; $$ = tl;
} }
| K_negedge expression | K_negedge expression
{ PEEvent*tmp = new PEEvent(NetNEvent::NEGEDGE, $2); { PEEvent*tmp = new PEEvent(PEEvent::NEGEDGE, $2);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
svector<PEEvent*>*tl = new svector<PEEvent*>(1); svector<PEEvent*>*tl = new svector<PEEvent*>(1);
@ -449,7 +450,7 @@ event_expression
$$ = tl; $$ = tl;
} }
| expression | expression
{ PEEvent*tmp = new PEEvent(NetNEvent::ANYEDGE, $1); { PEEvent*tmp = new PEEvent(PEEvent::ANYEDGE, $1);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
svector<PEEvent*>*tl = new svector<PEEvent*>(1); svector<PEEvent*>*tl = new svector<PEEvent*>(1);
@ -1860,7 +1861,7 @@ statement
} }
| K_wait '(' expression ')' statement_opt | K_wait '(' expression ')' statement_opt
{ PEventStatement*tmp; { PEventStatement*tmp;
PEEvent*etmp = new PEEvent(NetNEvent::POSITIVE, $3); PEEvent*etmp = new PEEvent(PEEvent::POSITIVE, $3);
tmp = new PEventStatement(etmp); tmp = new PEventStatement(etmp);
tmp->set_statement($5); tmp->set_statement($5);
$$ = tmp; $$ = tmp;

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform_dump.cc,v 1.52 2000/04/01 19:31:57 steve Exp $" #ident "$Id: pform_dump.cc,v 1.53 2000/04/12 04:23:58 steve Exp $"
#endif #endif
/* /*
@ -81,24 +81,21 @@ void PECallFunction::dump(ostream &out) const
void PEEvent::dump(ostream&out) const void PEEvent::dump(ostream&out) const
{ {
if (expr_) { switch (type_) {
switch (type_) { case NetNEvent::ANYEDGE:
case NetNEvent::ANYEDGE: break;
break; case NetNEvent::POSEDGE:
case NetNEvent::POSEDGE: out << "posedge ";
out << "posedge "; break;
break; case NetNEvent::NEGEDGE:
case NetNEvent::NEGEDGE: out << "negedge ";
out << "negedge "; break;
break; case NetNEvent::POSITIVE:
case NetNEvent::POSITIVE: out << "positive ";
out << "positive "; break;
break;
}
out << *expr_;
} else {
out << "<event " << name_ << ">";
} }
out << *expr_;
} }
void PENumber::dump(ostream&out) const void PENumber::dump(ostream&out) const
@ -736,6 +733,19 @@ void PUdp::dump(ostream&out) const
/* /*
* $Log: pform_dump.cc,v $ * $Log: pform_dump.cc,v $
* Revision 1.53 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.52 2000/04/01 19:31:57 steve * Revision 1.52 2000/04/01 19:31:57 steve
* Named events as far as the pform. * Named events as far as the pform.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-null.cc,v 1.10 2000/02/23 02:56:55 steve Exp $" #ident "$Id: t-null.cc,v 1.11 2000/04/12 04:23:58 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -37,11 +37,9 @@ static class target_null_t : public target_t {
void net_assign_nb(ostream&os, const NetAssignNB*) { } void net_assign_nb(ostream&os, const NetAssignNB*) { }
void net_const(ostream&, const NetConst*) { } void net_const(ostream&, const NetConst*) { }
void net_esignal(ostream&, const NetESignal*) { } void net_esignal(ostream&, const NetESignal*) { }
void net_event(ostream&, const NetNEvent*) { }
bool proc_block(ostream&, const NetBlock*) { return true; } bool proc_block(ostream&, const NetBlock*) { return true; }
void proc_condit(ostream&, const NetCondit*) { } void proc_condit(ostream&, const NetCondit*) { }
void proc_delay(ostream&, const NetPDelay*) { } void proc_delay(ostream&, const NetPDelay*) { }
void proc_event(ostream&, const NetPEvent*) { }
void proc_forever(ostream&, const NetForever*) { } void proc_forever(ostream&, const NetForever*) { }
void proc_repeat(ostream&, const NetRepeat*) { } void proc_repeat(ostream&, const NetRepeat*) { }
void proc_stask(ostream&, const NetSTask*) { } void proc_stask(ostream&, const NetSTask*) { }
@ -52,6 +50,19 @@ static class target_null_t : public target_t {
extern const struct target tgt_null = { "null", &target_null_obj }; extern const struct target tgt_null = { "null", &target_null_obj };
/* /*
* $Log: t-null.cc,v $ * $Log: t-null.cc,v $
* Revision 1.11 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.10 2000/02/23 02:56:55 steve * Revision 1.10 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident. * Macintosh compilers do not support ident.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-verilog.cc,v 1.9 2000/02/23 02:56:55 steve Exp $" #ident "$Id: t-verilog.cc,v 1.10 2000/04/12 04:23:58 steve Exp $"
#endif #endif
/* /*
@ -45,7 +45,6 @@ class target_verilog : public target_t {
virtual void start_process(ostream&os, const NetProcTop*); virtual void start_process(ostream&os, const NetProcTop*);
virtual bool proc_block(ostream&os, const NetBlock*); virtual bool proc_block(ostream&os, const NetBlock*);
virtual void proc_delay(ostream&os, const NetPDelay*); virtual void proc_delay(ostream&os, const NetPDelay*);
virtual void proc_event(ostream&os, const NetPEvent*);
virtual void proc_stask(ostream&os, const NetSTask*); virtual void proc_stask(ostream&os, const NetSTask*);
virtual void end_design(ostream&os, const Design*); virtual void end_design(ostream&os, const Design*);
private: private:
@ -192,35 +191,6 @@ void target_verilog::proc_delay(ostream&os, const NetPDelay*net)
indent_ -= 4; indent_ -= 4;
} }
void target_verilog::proc_event(ostream&os, const NetPEvent*net)
{
os << setw(indent_) << "" << "@";
#if 0
unsigned sidx;
const NetNet*sig = find_link_signal(net, 0, sidx);
switch (net->edge()) {
case NetNEvent::ANYEDGE:
os << mangle(sig->name()) << "[" << sidx << "]";
break;
case NetNEvent::POSEDGE:
os << "(posedge " << mangle(sig->name()) << "[" << sidx << "])";
break;
case NetNEvent::NEGEDGE:
os << "(negedge " << mangle(sig->name()) << "[" << sidx << "])";
break;
}
#else
os << endl;
os << "#error \"proc_event temporarily out of order\"";
#endif
os << endl;
indent_ += 4;
net->emit_proc_recurse(os, this);
indent_ -= 4;
}
static void vtask_parm(ostream&os, const NetExpr*ex) static void vtask_parm(ostream&os, const NetExpr*ex)
{ {
@ -272,6 +242,19 @@ const struct target tgt_verilog = {
/* /*
* $Log: t-verilog.cc,v $ * $Log: t-verilog.cc,v $
* Revision 1.10 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.9 2000/02/23 02:56:55 steve * Revision 1.9 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident. * Macintosh compilers do not support ident.
* *

153
t-vvm.cc
View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-vvm.cc,v 1.132 2000/04/10 05:26:06 steve Exp $" #ident "$Id: t-vvm.cc,v 1.133 2000/04/12 04:23:58 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
@ -80,7 +80,6 @@ class target_vvm : public target_t {
virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_assign_nb(ostream&os, const NetAssignNB*);
virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
virtual void net_const(ostream&os, const NetConst*); virtual void net_const(ostream&os, const NetConst*);
virtual void net_event(ostream&os, const NetNEvent*);
virtual void net_probe(ostream&os, const NetEvProbe*); virtual void net_probe(ostream&os, const NetEvProbe*);
virtual bool process(ostream&os, const NetProcTop*); virtual bool process(ostream&os, const NetProcTop*);
virtual void proc_assign(ostream&os, const NetAssign*); virtual void proc_assign(ostream&os, const NetAssign*);
@ -99,7 +98,6 @@ class target_vvm : public target_t {
virtual void proc_utask(ostream&os, const NetUTask*); virtual void proc_utask(ostream&os, const NetUTask*);
virtual bool proc_wait(ostream&os, const NetEvWait*); virtual bool proc_wait(ostream&os, const NetEvWait*);
virtual void proc_while(ostream&os, const NetWhile*); virtual void proc_while(ostream&os, const NetWhile*);
virtual void proc_event(ostream&os, const NetPEvent*);
virtual void proc_delay(ostream&os, const NetPDelay*); virtual void proc_delay(ostream&os, const NetPDelay*);
virtual void end_design(ostream&os, const Design*); virtual void end_design(ostream&os, const Design*);
@ -1749,63 +1747,6 @@ void target_vvm::net_const(ostream&os, const NetConst*gate)
emit_init_value_(gate->pin(idx), gate->value(idx)); emit_init_value_(gate->pin(idx), gate->value(idx));
} }
/*
* The net_event device is a synthetic device type--a fabrication of
* the elaboration phase. An event device receives value changes from
* the attached signal. It is an input only device, its only value
* being the side-effects that threads waiting on events can be
* awakened.
*
* The proc_event method handles the other half of this, the process
* that blocks on the event.
*/
void target_vvm::net_event(ostream&os, const NetNEvent*gate)
{
string gname = mangle(gate->name());
string pevent = mangle(gate->pevent()->name());
os << " /* " << gate->name() << " */" << endl;
bool&printed = pevent_printed_flag[pevent];
if (! printed) {
printed = true;
os << "static vvm_sync " << pevent << ";" << endl;
}
switch (gate->type()) {
case NetNEvent::POSEDGE:
case NetNEvent::POSITIVE:
assert(gate->pin_count() == 1);
os << "static vvm_posedge " << gname
<< "(&" << pevent << ");" << endl;
break;
case NetNEvent::NEGEDGE:
assert(gate->pin_count() == 1);
os << "static vvm_negedge " << gname
<< "(&" << pevent << ");" << endl;
break;
case NetNEvent::ANYEDGE:
assert(gate->pin_count() == 1);
os << "static vvm_anyedge " << gname
<< "(&" << pevent << ");" << endl;
break;
}
/* Connect this device as a receiver to the nexus that is my
source. Write the connect calls into the init code. */
for (unsigned idx = 0 ; idx < gate->pin_count() ; idx += 1) {
string nexus = nexus_from_link(&gate->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&" <<
mangle(gate->name()) << ", " << idx << ");" << endl;
}
}
void target_vvm::net_probe(ostream&os, const NetEvProbe*net) void target_vvm::net_probe(ostream&os, const NetEvProbe*net)
{ {
@ -2446,15 +2387,17 @@ bool target_vvm::proc_wait(ostream&os, const NetEvWait*wait)
{ {
unsigned out_step = ++thread_step_; unsigned out_step = ++thread_step_;
const NetEvent*ev = wait->event();
assert(ev);
string ename = mangle(ev->full_name());
defn << " step_ = &" << thread_class_ << "::step_" defn << " step_ = &" << thread_class_ << "::step_"
<< out_step << "_;" << endl; << out_step << "_;" << endl;
defn << " " << ename << ".wait(this); // "
<< wait->get_line() << ": @" << ev->full_name() << "..." << endl; for (unsigned idx = 0 ; idx < wait->nevents() ; idx+= 1) {
const NetEvent*ev = wait->event(idx);
assert(ev);
string ename = mangle(ev->full_name());
defn << " " << ename << ".wait(this); // "
<< wait->get_line() << ": @" << ev->full_name()
<< "..." << endl;
}
defn << " return false;" << endl; defn << " return false;" << endl;
defn << "}" << endl; defn << "}" << endl;
@ -2521,69 +2464,6 @@ void target_vvm::proc_while(ostream&os, const NetWhile*net)
"_() {" << endl; "_() {" << endl;
} }
/*
* Within a process, the proc_event is a statement that is blocked
* until the event is signalled.
*/
void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
{
thread_step_ += 1;
defn << " step_ = &" << thread_class_ << "::step_" <<
thread_step_ << "_;" << endl;
/* POSITIVE is for the wait construct, and needs to be handled
specially. The structure of the generated code is:
if (event.get(0)==V1) {
return true;
} else {
event.wait(this);
return false;
}
This causes the wait to not even block the thread if the
event value is already positive, otherwise wait for a
rising edge. All the edge triggers look like this:
event.wait(vvm_pevent::POSEDGE, this);
return false;
POSEDGE is replaced with the correct type for the desired
edge. */
const NetNEvent*tmp = proc->first();
if (tmp && (tmp->type() == NetNEvent::POSITIVE)) {
// POSITIVE can have only one input.
assert(0 == proc->next());
defn << " if (B_IS1(" << mangle(tmp->name()) <<
".get(0))) {" << endl;
defn << " return true;" << endl;
defn << " } else {" << endl;
defn << " " << mangle(proc->name()) <<
".wait(this);" << endl;
defn << " return false;" << endl;
defn << " }" << endl;
} else {
/* The canonical wait for an edge puts the thread into
the correct wait object, then returns false from the
thread to suspend execution. When things are ready to
proceed, the correct vvm_pevent will send a wakeup to
start the next basic block. */
defn << " " << mangle(proc->name()) << ".wait(this);" << endl;
defn << " return false;" << endl;
}
defn << "}" << endl;
os << " bool step_" << thread_step_ << "_();" << endl;
defn << "bool " << thread_class_ << "::step_" << thread_step_ <<
"_() {" << endl;
proc->emit_proc_recurse(os, this);
}
/* /*
* A delay suspends the thread for a period of time. * A delay suspends the thread for a period of time.
@ -2629,6 +2509,19 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.133 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.132 2000/04/10 05:26:06 steve * Revision 1.132 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: target.cc,v 1.34 2000/04/10 05:26:06 steve Exp $" #ident "$Id: target.cc,v 1.35 2000/04/12 04:23:58 steve Exp $"
#endif #endif
# include "target.h" # include "target.h"
@ -155,13 +155,6 @@ void target_t::net_const(ostream&os, const NetConst*)
"Unhandled CONSTANT node." << endl; "Unhandled CONSTANT node." << endl;
} }
void target_t::net_event(ostream&os, const NetNEvent*net)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled EVENT net node." << endl;
net->dump_node(cerr, 4);
}
void target_t::net_probe(ostream&os, const NetEvProbe*net) void target_t::net_probe(ostream&os, const NetEvProbe*net)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -225,13 +218,6 @@ void target_t::proc_delay(ostream&os, const NetPDelay*)
"Unhandled proc_delay." << endl; "Unhandled proc_delay." << endl;
} }
void target_t::proc_event(ostream&os, const NetPEvent*net)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled proc_event." << endl;
net->dump(cerr, 4);
}
void target_t::proc_forever(ostream&os, const NetForever*) void target_t::proc_forever(ostream&os, const NetForever*)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -353,6 +339,19 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/* /*
* $Log: target.cc,v $ * $Log: target.cc,v $
* Revision 1.35 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.34 2000/04/10 05:26:06 steve * Revision 1.34 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *

View File

@ -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) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: target.h,v 1.33 2000/04/10 05:26:06 steve Exp $" #ident "$Id: target.h,v 1.34 2000/04/12 04:23:58 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -91,7 +91,6 @@ struct target_t {
virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_assign_nb(ostream&os, const NetAssignNB*);
virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
virtual void net_const(ostream&os, const NetConst*); virtual void net_const(ostream&os, const NetConst*);
virtual void net_event(ostream&os, const NetNEvent*);
virtual void net_probe(ostream&os, const NetEvProbe*); virtual void net_probe(ostream&os, const NetEvProbe*);
/* Output a process (called for each process). It is up to the /* Output a process (called for each process). It is up to the
@ -113,8 +112,6 @@ struct target_t {
virtual void proc_utask(ostream&os, const NetUTask*); virtual void proc_utask(ostream&os, const NetUTask*);
virtual bool proc_wait(ostream&os, const NetEvWait*); virtual bool proc_wait(ostream&os, const NetEvWait*);
virtual void proc_while(ostream&os, const NetWhile*); virtual void proc_while(ostream&os, const NetWhile*);
virtual void proc_event(ostream&os, const NetPEvent*);
virtual void proc_delay(ostream&os, const NetPDelay*); virtual void proc_delay(ostream&os, const NetPDelay*);
/* Done with the design. */ /* Done with the design. */
@ -155,6 +152,19 @@ extern const struct target *target_table[];
/* /*
* $Log: target.h,v $ * $Log: target.h,v $
* Revision 1.34 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.33 2000/04/10 05:26:06 steve * Revision 1.33 2000/04/10 05:26:06 steve
* All events now use the NetEvent class. * All events now use the NetEvent class.
* *