assignment with blocking event delay.

This commit is contained in:
steve 1999-09-22 02:00:48 +00:00
parent fcfa9d004a
commit da4a7ea80a
4 changed files with 96 additions and 20 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Statement.cc,v 1.14 1999/09/04 19:11:46 steve Exp $"
#ident "$Id: Statement.cc,v 1.15 1999/09/22 02:00:48 steve Exp $"
#endif
# include "Statement.h"
@ -27,12 +27,22 @@ Statement::~Statement()
{
}
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
}
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
: lval_(lval), rval_(ex)
: event_(0), lval_(lval), rval_(ex)
{
if (de) delay_.set_delay(de);
}
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
: event_(ev), lval_(lval), rval_(ex)
{
}
PAssign_::~PAssign_()
{
delete lval_;
@ -40,7 +50,7 @@ PAssign_::~PAssign_()
}
PAssign::PAssign(PExpr*lval, PExpr*ex)
: PAssign_(lval, 0, ex)
: PAssign_(lval, ex)
{
}
@ -49,12 +59,17 @@ PAssign::PAssign(PExpr*lval, PExpr*d, PExpr*ex)
{
}
PAssign::PAssign(PExpr*lval, PEventStatement*d, PExpr*ex)
: PAssign_(lval, d, ex)
{
}
PAssign::~PAssign()
{
}
PAssignNB::PAssignNB(PExpr*lval, PExpr*ex)
: PAssign_(lval, 0, ex)
: PAssign_(lval, ex)
{
}
@ -148,6 +163,9 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.15 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.14 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Statement.h,v 1.18 1999/09/15 01:55:06 steve Exp $"
#ident "$Id: Statement.h,v 1.19 1999/09/22 02:00:48 steve Exp $"
#endif
# include <string>
@ -29,6 +29,7 @@
# include "LineInfo.h"
class PExpr;
class Statement;
class PEventStatement;
/*
* The PProcess is the root of a behavioral process. Each process gets
@ -78,7 +79,9 @@ class Statement : public LineInfo {
*/
class PAssign_ : public Statement {
public:
explicit PAssign_(PExpr*lval, PExpr*ex);
explicit PAssign_(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssign_(PExpr*lval, PEventStatement*de, PExpr*ex);
virtual ~PAssign_() =0;
const PExpr* lval() const { return lval_; }
@ -90,6 +93,7 @@ class PAssign_ : public Statement {
NetExpr*&mux) const;
PDelays delay_;
PEventStatement*event_;
private:
PExpr* lval_;
@ -101,6 +105,7 @@ class PAssign : public PAssign_ {
public:
explicit PAssign(PExpr*lval, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssign(PExpr*lval, PEventStatement*de, PExpr*ex);
~PAssign();
virtual void dump(ostream&out, unsigned ind) const;
@ -260,6 +265,10 @@ class PEventStatement : public Statement {
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
// This method is used to elaborate, but attach a previously
// elaborated statement to the event.
NetProc* elaborate_st(Design*des, const string&path, NetProc*st) const;
private:
svector<PEEvent*>expr_;
Statement*statement_;
@ -337,6 +346,9 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.19 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.18 1999/09/15 01:55:06 steve
* Elaborate non-blocking assignment to memories.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.93 1999/09/20 02:21:10 steve Exp $"
#ident "$Id: elaborate.cc,v 1.94 1999/09/22 02:00:48 steve Exp $"
#endif
/*
@ -1618,11 +1618,15 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
#<d> a = tmp;
end
If the delay is an event delay, then the transform is
similar, with the event delay replacing the time delay. It
is an event delay if the event_ member has a value.
This rewriting of the expression allows me to not bother to
actually and literally represent the delayed assign in the
netlist. The compound statement is exactly equivalent. */
if (rise_time) {
if (rise_time || event_) {
string n = des->local_symbol(path);
unsigned wid = reg->pin_count();
@ -1658,12 +1662,31 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(a2->pin(idx), reg->pin(idx));
/* And build up the complex statement. */
NetPDelay*de = new NetPDelay(rise_time, a2);
/* Generate the delay statement with the final
assignment attached to it. If this is an event delay,
elaborate the PEventStatement. Otherwise, create the
right NetPDelay object. */
NetProc*st;
if (event_) {
st = event_->elaborate_st(des, path, a2);
if (st == 0) {
cerr << event_->get_line() << ": error: "
"unable to elaborate event expression."
<< endl;
des->errors += 1;
return 0;
}
assert(st);
} else {
NetPDelay*de = new NetPDelay(rise_time, a2);
st = de;
}
/* And build up the complex statement. */
NetBlock*bl = new NetBlock(NetBlock::SEQU);
bl->append(a1);
bl->append(de);
bl->append(st);
return bl;
}
@ -2132,14 +2155,9 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
* happens when the source has something like "@(E) ;". Note the null
* statement.
*/
NetProc* PEventStatement::elaborate(Design*des, const string&path) const
NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetProc*enet) const
{
NetProc*enet = 0;
if (statement_) {
enet = statement_->elaborate(des, path);
if (enet == 0)
return 0;
}
/* Create a single NetPEvent, and a unique NetNEvent for each
conjuctive event. An NetNEvent can have many pins only if
@ -2172,6 +2190,18 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const
return pe;
}
NetProc* PEventStatement::elaborate(Design*des, const string&path) const
{
NetProc*enet = 0;
if (statement_) {
enet = statement_->elaborate(des, path);
if (enet == 0)
return 0;
}
return elaborate_st(des, path, enet);
}
/*
* Forever statements are represented directly in the netlist. It is
* theoretically possible to use a while structure with a constant
@ -2583,6 +2613,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.94 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.93 1999/09/20 02:21:10 steve
* Elaborate parameters in phases.
*

19
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.64 1999/09/17 02:06:26 steve Exp $"
#ident "$Id: parse.y,v 1.65 1999/09/22 02:00:48 steve Exp $"
#endif
# include "parse_misc.h"
@ -1578,7 +1578,7 @@ statement
| lpvalue '=' delay expression ';'
{ PExpr*del = (*$3)[0];
if ($3->count() != 1)
yyerror(@1, "Sorry, delay lists not supported here.");
yyerror(@1, "sorry: Delay lists not supported here.");
PAssign*tmp = new PAssign($1,del,$4);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
@ -1587,12 +1587,25 @@ statement
| lpvalue K_LE delay expression ';'
{ PExpr*del = (*$3)[0];
if ($3->count() != 1)
yyerror(@1, "Sorry, delay lists not supported here.");
yyerror(@1, "sorry: Delay lists not supported here.");
PAssignNB*tmp = new PAssignNB($1,del,$4);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lpvalue '=' event_control expression ';'
{ PAssign*tmp = new PAssign($1,$3,$4);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lpvalue K_LE event_control expression ';'
{ yyerror(@1, "sorry: Event controls not supported here.");
PAssignNB*tmp = new PAssignNB($1,$4);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_wait '(' expression ')' statement_opt
{ PEventStatement*tmp;
PEEvent*etmp = new PEEvent(NetNEvent::POSITIVE, $3);