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:
parent
b0d0cdbd7d
commit
b1fd927acb
76
PExpr.cc
76
PExpr.cc
|
|
@ -17,13 +17,17 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "Module.h"
|
||||
# include <typeinfo>
|
||||
|
||||
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 constant = repeat_? repeat_->is_constant(mod) : true;
|
||||
|
|
@ -83,21 +92,16 @@ PEConcat::~PEConcat()
|
|||
delete repeat_;
|
||||
}
|
||||
|
||||
PEEvent::PEEvent(NetNEvent::Type t, PExpr*e)
|
||||
PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e)
|
||||
: type_(t), expr_(e)
|
||||
{
|
||||
}
|
||||
|
||||
PEEvent::PEEvent(const string&n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PEEvent::~PEEvent()
|
||||
{
|
||||
}
|
||||
|
||||
NetNEvent::Type PEEvent::type() const
|
||||
PEEvent::edge_t PEEvent::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
|
@ -107,9 +111,18 @@ PExpr* PEEvent::expr() const
|
|||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
const PENumber*obj = dynamic_cast<const PENumber*>(that);
|
||||
|
|
@ -143,6 +172,20 @@ bool PENumber::is_constant(Module*) const
|
|||
return true;
|
||||
}
|
||||
|
||||
PEString::PEString(const string&s)
|
||||
: text_(s)
|
||||
{
|
||||
}
|
||||
|
||||
PEString::~PEString()
|
||||
{
|
||||
}
|
||||
|
||||
string PEString::value() const
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
|
||||
bool PEString::is_constant(Module*) const
|
||||
{
|
||||
return true;
|
||||
|
|
@ -164,6 +207,19 @@ bool PETernary::is_constant(Module*) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
|
|
|||
59
PExpr.h
59
PExpr.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -44,7 +44,9 @@ class NetScope;
|
|||
*/
|
||||
|
||||
class PExpr : public LineInfo {
|
||||
|
||||
public:
|
||||
PExpr();
|
||||
virtual ~PExpr();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
|
@ -86,6 +88,9 @@ class PExpr : public LineInfo {
|
|||
// of expresions.
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private: // not implemented
|
||||
PExpr(const PExpr&);
|
||||
PExpr& operator= (const PExpr&);
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&, const PExpr&);
|
||||
|
|
@ -93,8 +98,7 @@ ostream& operator << (ostream&, const PExpr&);
|
|||
class PEConcat : public PExpr {
|
||||
|
||||
public:
|
||||
PEConcat(const svector<PExpr*>&p, PExpr*r =0)
|
||||
: parms_(p), repeat_(r) { }
|
||||
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
|
||||
~PEConcat();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
|
@ -122,30 +126,28 @@ class PEConcat : public PExpr {
|
|||
class PEEvent : public PExpr {
|
||||
|
||||
public:
|
||||
enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE};
|
||||
|
||||
// Use this constructor to create events based on edges or levels.
|
||||
PEEvent(NetNEvent::Type t, PExpr*e);
|
||||
// Use this to create named events.
|
||||
PEEvent(const string&n);
|
||||
PEEvent(edge_t t, PExpr*e);
|
||||
|
||||
~PEEvent();
|
||||
|
||||
NetNEvent::Type type() const;
|
||||
PExpr* expr() const;
|
||||
string name() const;
|
||||
edge_t type() const;
|
||||
PExpr* expr() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
NetNEvent::Type type_;
|
||||
PExpr*expr_;
|
||||
string name_;
|
||||
edge_t type_;
|
||||
PExpr *expr_;
|
||||
};
|
||||
|
||||
class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(const string&s)
|
||||
: text_(s), msb_(0), lsb_(0), idx_(0) { }
|
||||
explicit PEIdent(const string&s);
|
||||
~PEIdent();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
|
|
@ -165,8 +167,7 @@ class PEIdent : public PExpr {
|
|||
virtual bool is_constant(Module*) const;
|
||||
verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
// XXXX
|
||||
string name() const { return text_; }
|
||||
string name() const;
|
||||
|
||||
private:
|
||||
string text_;
|
||||
|
|
@ -190,11 +191,10 @@ class PEIdent : public PExpr {
|
|||
class PENumber : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENumber(verinum*vp)
|
||||
: value_(vp) { assert(vp); }
|
||||
~PENumber() { delete value_; }
|
||||
explicit PENumber(verinum*vp);
|
||||
~PENumber();
|
||||
|
||||
const verinum& value() const { return *value_; }
|
||||
const verinum& value() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
|
|
@ -216,10 +216,10 @@ class PENumber : public PExpr {
|
|||
class PEString : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEString(const string&s)
|
||||
: text_(s) { }
|
||||
explicit PEString(const string&s);
|
||||
~PEString();
|
||||
|
||||
string value() const { return text_; }
|
||||
string value() const;
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
|
||||
|
|
@ -358,6 +358,19 @@ class PECallFunction : public PExpr {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add support for integer division.
|
||||
*
|
||||
|
|
|
|||
36
Statement.cc
36
Statement.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "Statement.h"
|
||||
|
|
@ -122,6 +122,11 @@ PCase::~PCase()
|
|||
delete[]items_;
|
||||
}
|
||||
|
||||
PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
|
||||
: expr_(ex), if_(i), else_(e)
|
||||
{
|
||||
}
|
||||
|
||||
PCondit::~PCondit()
|
||||
{
|
||||
delete expr_;
|
||||
|
|
@ -129,6 +134,17 @@ PCondit::~PCondit()
|
|||
delete else_;
|
||||
}
|
||||
|
||||
|
||||
PDelayStatement::PDelayStatement(PExpr*d, Statement*st)
|
||||
: delay_(d), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PDelayStatement::~PDelayStatement()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
|
|
@ -146,6 +162,11 @@ PEventStatement::~PEventStatement()
|
|||
// delete the events and the statement?
|
||||
}
|
||||
|
||||
void PEventStatement::set_statement(Statement*st)
|
||||
{
|
||||
statement_ = st;
|
||||
}
|
||||
|
||||
PForever::PForever(Statement*s)
|
||||
: statement_(s)
|
||||
{
|
||||
|
|
@ -189,6 +210,19 @@ PWhile::~PWhile()
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
|
|
|||
24
Statement.h
24
Statement.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -225,8 +225,7 @@ class PCase : public Statement {
|
|||
class PCondit : public Statement {
|
||||
|
||||
public:
|
||||
PCondit(PExpr*ex, Statement*i, Statement*e)
|
||||
: expr_(ex), if_(i), else_(e) { }
|
||||
PCondit(PExpr*ex, Statement*i, Statement*e);
|
||||
~PCondit();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
|
|
@ -246,8 +245,8 @@ class PCondit : public Statement {
|
|||
class PDelayStatement : public Statement {
|
||||
|
||||
public:
|
||||
PDelayStatement(PExpr*d, Statement*st)
|
||||
: delay_(d), statement_(st) { }
|
||||
PDelayStatement(PExpr*d, Statement*st);
|
||||
~PDelayStatement();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
|
|
@ -274,7 +273,7 @@ class PEventStatement : public Statement {
|
|||
|
||||
~PEventStatement();
|
||||
|
||||
void set_statement(Statement*st) { statement_ = st; }
|
||||
void set_statement(Statement*st);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
|
|
@ -382,6 +381,19 @@ class PWhile : public Statement {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -555,8 +555,14 @@ void NetEvTrig::dump(ostream&o, unsigned ind) const
|
|||
|
||||
void NetEvWait::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "@" << event_->name()
|
||||
<< " // " << get_line() << endl;
|
||||
assert(nevents() > 0);
|
||||
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_)
|
||||
statement_->dump(o, ind+2);
|
||||
else
|
||||
|
|
@ -948,6 +954,19 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
160
elaborate.cc
160
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -1541,12 +1541,66 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
|
|||
*
|
||||
* NetEvWait ---/---> NetEvent <----\---- NetEvProbe
|
||||
* ... | | ...
|
||||
* NetEvWait ---+ +-----NetEvProbe
|
||||
* NetEvWait ---+ +---- NetEvProbe
|
||||
* | ...
|
||||
* +---- NetEvTrig
|
||||
*
|
||||
* That is, many NetEvWait statements may wait on a single 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*enet) const
|
||||
{
|
||||
|
|
@ -1573,10 +1627,11 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
|
|||
|
|
||||
+---> <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);
|
||||
|
||||
|
|
@ -1592,7 +1647,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
|
|||
NetEvent*ev = new NetEvent(scope->local_symbol());
|
||||
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(),
|
||||
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);
|
||||
bl->append(co);
|
||||
bl->append(enet);
|
||||
|
||||
ev->set_line(*this);
|
||||
bl->set_line(*this);
|
||||
we->set_line(*this);
|
||||
co->set_line(*this);
|
||||
|
||||
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
|
||||
in an expression. Make a named event reference. */
|
||||
|
||||
if (expr_.count() == 1) {
|
||||
assert(expr_[0]->expr());
|
||||
PEIdent*id = dynamic_cast<PEIdent*>(expr_[0]->expr());
|
||||
NetEvent*ev;
|
||||
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);
|
||||
return pr;
|
||||
}
|
||||
|
|
@ -1643,28 +1691,32 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
|
|||
object. */
|
||||
|
||||
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) {
|
||||
if (expr_[idx]->expr() == 0) {
|
||||
cerr << get_line() << ": sorry: block on named events "
|
||||
<< "not supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(expr_[idx]->expr());
|
||||
|
||||
/* If the expression is an identifier that matches a
|
||||
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())) {
|
||||
NetEvent*ev = scope->find_event(id->name());
|
||||
if (ev) {
|
||||
cerr << get_line() << ": sorry: block on named events "
|
||||
<< "not supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
NetEvent*tmp = scope->find_event(id->name());
|
||||
if (tmp) {
|
||||
wa->add_event(tmp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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,
|
||||
0, 0, 0, 0);
|
||||
if (expr == 0) {
|
||||
|
|
@ -1675,22 +1727,22 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
|
|||
}
|
||||
assert(expr);
|
||||
|
||||
unsigned pins = (expr_[idx]->type() == NetNEvent::ANYEDGE)
|
||||
unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE)
|
||||
? expr->pin_count() : 1;
|
||||
|
||||
NetEvProbe*pr;
|
||||
switch (expr_[idx]->type()) {
|
||||
case NetNEvent::POSEDGE:
|
||||
case PEEvent::POSEDGE:
|
||||
pr = new NetEvProbe(des->local_symbol(path), ev,
|
||||
NetEvProbe::POSEDGE, pins);
|
||||
break;
|
||||
|
||||
case NetNEvent::NEGEDGE:
|
||||
case PEEvent::NEGEDGE:
|
||||
pr = new NetEvProbe(des->local_symbol(path), ev,
|
||||
NetEvProbe::NEGEDGE, pins);
|
||||
break;
|
||||
|
||||
case NetNEvent::ANYEDGE:
|
||||
case PEEvent::ANYEDGE:
|
||||
pr = new NetEvProbe(des->local_symbol(path), ev,
|
||||
NetEvProbe::ANYEDGE, pins);
|
||||
break;
|
||||
|
|
@ -1703,6 +1755,17 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
|
|||
connect(pr->pin(p), expr->pin(p));
|
||||
|
||||
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;
|
||||
|
|
@ -2161,6 +2224,19 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
31
emit.cc
31
emit.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -110,11 +110,6 @@ void NetRamDq::emit_node(ostream&o, struct target_t*tgt) const
|
|||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
tgt->proc_repeat(o, this);
|
||||
|
|
@ -432,6 +416,19 @@ bool emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
50
net_event.cc
50
net_event.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -82,23 +82,63 @@ const NetEvent* NetEvProbe::event() const
|
|||
return event_;
|
||||
}
|
||||
|
||||
NetEvWait::NetEvWait(NetEvent*ev, NetProc*pr)
|
||||
: event_(ev), statement_(pr)
|
||||
NetEvWait::NetEvWait(NetProc*pr)
|
||||
: statement_(pr), nevents_(0), events_(0)
|
||||
{
|
||||
}
|
||||
|
||||
NetEvWait::~NetEvWait()
|
||||
{
|
||||
if (events_) delete[]events_;
|
||||
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 $
|
||||
* 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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
31
netlist.h
31
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -1312,18 +1312,23 @@ class NetEvTrig : public NetProc {
|
|||
class NetEvWait : public NetProc {
|
||||
|
||||
public:
|
||||
explicit NetEvWait(NetEvent*tgt, NetProc*st);
|
||||
explicit NetEvWait(NetProc*st);
|
||||
~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;
|
||||
bool emit_recurse(ostream&, struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
NetEvent*event_;
|
||||
NetProc*statement_;
|
||||
|
||||
unsigned nevents_;
|
||||
NetEvent**events_;
|
||||
};
|
||||
|
||||
class NetEvProbe : public NetNode {
|
||||
|
|
@ -1440,11 +1445,8 @@ class NetPEvent : public NetProc {
|
|||
const NetNEvent* next() const;
|
||||
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual bool emit_proc(ostream&, struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
void emit_proc_recurse(ostream&, struct target_t*) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
NetProc*statement_;
|
||||
|
|
@ -1477,8 +1479,6 @@ class NetNEvent : public NetNode {
|
|||
Type type() const;
|
||||
const NetPEvent*pevent() const;
|
||||
|
||||
virtual void emit_node(ostream&, struct target_t*) const;
|
||||
|
||||
void dump_proc(ostream&) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
|
||||
|
|
@ -2399,6 +2399,19 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
17
parse.y
17
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -398,10 +398,11 @@ dr_strength1 : K_supply1 | K_strong1 | K_pull1 | K_weak1 ;
|
|||
|
||||
event_control
|
||||
: '@' IDENTIFIER
|
||||
{ PEEvent*tmpe = new PEEvent($2);
|
||||
tmpe->set_file(@2.text);
|
||||
tmpe->set_lineno(@2.first_line);
|
||||
{ PEIdent*tmpi = new PEIdent($2);
|
||||
tmpi->set_file(@2.text);
|
||||
tmpi->set_lineno(@2.first_line);
|
||||
delete[]$2;
|
||||
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
|
||||
PEventStatement*tmps = new PEventStatement(tmpe);
|
||||
tmps->set_file(@1.text);
|
||||
tmps->set_lineno(@1.first_line);
|
||||
|
|
@ -433,7 +434,7 @@ event_expression_list
|
|||
|
||||
event_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_lineno(@1.first_line);
|
||||
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
|
||||
|
|
@ -441,7 +442,7 @@ event_expression
|
|||
$$ = tl;
|
||||
}
|
||||
| K_negedge expression
|
||||
{ PEEvent*tmp = new PEEvent(NetNEvent::NEGEDGE, $2);
|
||||
{ PEEvent*tmp = new PEEvent(PEEvent::NEGEDGE, $2);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
|
||||
|
|
@ -449,7 +450,7 @@ event_expression
|
|||
$$ = tl;
|
||||
}
|
||||
| expression
|
||||
{ PEEvent*tmp = new PEEvent(NetNEvent::ANYEDGE, $1);
|
||||
{ PEEvent*tmp = new PEEvent(PEEvent::ANYEDGE, $1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
|
||||
|
|
@ -1860,7 +1861,7 @@ statement
|
|||
}
|
||||
| K_wait '(' expression ')' statement_opt
|
||||
{ PEventStatement*tmp;
|
||||
PEEvent*etmp = new PEEvent(NetNEvent::POSITIVE, $3);
|
||||
PEEvent*etmp = new PEEvent(PEEvent::POSITIVE, $3);
|
||||
tmp = new PEventStatement(etmp);
|
||||
tmp->set_statement($5);
|
||||
$$ = tmp;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -81,24 +81,21 @@ void PECallFunction::dump(ostream &out) const
|
|||
|
||||
void PEEvent::dump(ostream&out) const
|
||||
{
|
||||
if (expr_) {
|
||||
switch (type_) {
|
||||
case NetNEvent::ANYEDGE:
|
||||
break;
|
||||
case NetNEvent::POSEDGE:
|
||||
out << "posedge ";
|
||||
break;
|
||||
case NetNEvent::NEGEDGE:
|
||||
out << "negedge ";
|
||||
break;
|
||||
case NetNEvent::POSITIVE:
|
||||
out << "positive ";
|
||||
break;
|
||||
}
|
||||
out << *expr_;
|
||||
} else {
|
||||
out << "<event " << name_ << ">";
|
||||
switch (type_) {
|
||||
case NetNEvent::ANYEDGE:
|
||||
break;
|
||||
case NetNEvent::POSEDGE:
|
||||
out << "posedge ";
|
||||
break;
|
||||
case NetNEvent::NEGEDGE:
|
||||
out << "negedge ";
|
||||
break;
|
||||
case NetNEvent::POSITIVE:
|
||||
out << "positive ";
|
||||
break;
|
||||
}
|
||||
out << *expr_;
|
||||
|
||||
}
|
||||
|
||||
void PENumber::dump(ostream&out) const
|
||||
|
|
@ -736,6 +733,19 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
|
|
|||
17
t-null.cc
17
t-null.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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_const(ostream&, const NetConst*) { }
|
||||
void net_esignal(ostream&, const NetESignal*) { }
|
||||
void net_event(ostream&, const NetNEvent*) { }
|
||||
bool proc_block(ostream&, const NetBlock*) { return true; }
|
||||
void proc_condit(ostream&, const NetCondit*) { }
|
||||
void proc_delay(ostream&, const NetPDelay*) { }
|
||||
void proc_event(ostream&, const NetPEvent*) { }
|
||||
void proc_forever(ostream&, const NetForever*) { }
|
||||
void proc_repeat(ostream&, const NetRepeat*) { }
|
||||
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 };
|
||||
/*
|
||||
* $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
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
45
t-verilog.cc
45
t-verilog.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -45,7 +45,6 @@ class target_verilog : public target_t {
|
|||
virtual void start_process(ostream&os, const NetProcTop*);
|
||||
virtual bool proc_block(ostream&os, const NetBlock*);
|
||||
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 end_design(ostream&os, const Design*);
|
||||
private:
|
||||
|
|
@ -192,35 +191,6 @@ void target_verilog::proc_delay(ostream&os, const NetPDelay*net)
|
|||
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)
|
||||
{
|
||||
|
|
@ -272,6 +242,19 @@ const struct target tgt_verilog = {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
153
t-vvm.cc
153
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -80,7 +80,6 @@ class target_vvm : public target_t {
|
|||
virtual void net_assign_nb(ostream&os, const NetAssignNB*);
|
||||
virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
|
||||
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 bool process(ostream&os, const NetProcTop*);
|
||||
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 bool proc_wait(ostream&os, const NetEvWait*);
|
||||
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 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));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
|
|
@ -2446,15 +2387,17 @@ bool target_vvm::proc_wait(ostream&os, const NetEvWait*wait)
|
|||
{
|
||||
unsigned out_step = ++thread_step_;
|
||||
|
||||
const NetEvent*ev = wait->event();
|
||||
assert(ev);
|
||||
|
||||
string ename = mangle(ev->full_name());
|
||||
|
||||
defn << " step_ = &" << thread_class_ << "::step_"
|
||||
<< 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 << "}" << endl;
|
||||
|
|
@ -2521,69 +2464,6 @@ void target_vvm::proc_while(ostream&os, const NetWhile*net)
|
|||
"_() {" << 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.
|
||||
|
|
@ -2629,6 +2509,19 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
29
target.cc
29
target.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -155,13 +155,6 @@ void target_t::net_const(ostream&os, const NetConst*)
|
|||
"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)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -225,13 +218,6 @@ void target_t::proc_delay(ostream&os, const NetPDelay*)
|
|||
"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*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -353,6 +339,19 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
18
target.h
18
target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -91,7 +91,6 @@ struct target_t {
|
|||
virtual void net_assign_nb(ostream&os, const NetAssignNB*);
|
||||
virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
|
||||
virtual void net_const(ostream&os, const NetConst*);
|
||||
virtual void net_event(ostream&os, const NetNEvent*);
|
||||
virtual void net_probe(ostream&os, const NetEvProbe*);
|
||||
|
||||
/* 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 bool proc_wait(ostream&os, const NetEvWait*);
|
||||
virtual void proc_while(ostream&os, const NetWhile*);
|
||||
|
||||
virtual void proc_event(ostream&os, const NetPEvent*);
|
||||
virtual void proc_delay(ostream&os, const NetPDelay*);
|
||||
|
||||
/* Done with the design. */
|
||||
|
|
@ -155,6 +152,19 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $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
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue