Synthesize async set/reset is certain cases.

This commit is contained in:
steve 2002-09-26 01:13:14 +00:00
parent 9faabfe995
commit 879a5a4cbe
2 changed files with 102 additions and 14 deletions

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.262 2002/09/16 00:30:33 steve Exp $" #ident "$Id: netlist.h,v 1.263 2002/09/26 01:13:14 steve Exp $"
#endif #endif
/* /*
@ -51,6 +51,7 @@ class NetProc;
class NetProcTop; class NetProcTop;
class NetRelease; class NetRelease;
class NetScope; class NetScope;
class NetEvProbe;
class NetExpr; class NetExpr;
class NetESignal; class NetESignal;
class NetFuncDef; class NetFuncDef;
@ -1223,7 +1224,8 @@ class NetProc : public LineInfo {
const NetNet*nex_map, NetNet*nex_out); const NetNet*nex_map, NetNet*nex_out);
virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff, virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out); const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events);
virtual void dump(ostream&, unsigned ind) const; virtual void dump(ostream&, unsigned ind) const;
@ -1538,7 +1540,8 @@ class NetCondit : public NetProc {
const NetNet*nex_map, NetNet*nex_out); const NetNet*nex_map, NetNet*nex_out);
bool synth_sync(Design*des, NetScope*scope, NetFF*ff, bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out); const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events);
virtual bool emit_proc(struct target_t*) const; virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*); virtual int match_proc(struct proc_match_t*);
@ -1755,7 +1758,8 @@ class NetEvWait : public NetProc {
const NetNet*nex_map, NetNet*nex_out); const NetNet*nex_map, NetNet*nex_out);
virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff, virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out); const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events);
virtual void dump(ostream&, unsigned ind) const; virtual void dump(ostream&, unsigned ind) const;
@ -3051,6 +3055,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.263 2002/09/26 01:13:14 steve
* Synthesize async set/reset is certain cases.
*
* Revision 1.262 2002/09/16 00:30:33 steve * Revision 1.262 2002/09/16 00:30:33 steve
* Add to synth2 support for synthesis of * Add to synth2 support for synthesis of
* synchronous logic. This includes DFF enables * synchronous logic. This includes DFF enables

101
synth2.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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: synth2.cc,v 1.11 2002/09/24 00:58:35 steve Exp $" #ident "$Id: synth2.cc,v 1.12 2002/09/26 01:13:14 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -34,8 +34,15 @@ bool NetProc::synth_async(Design*des, NetScope*scope,
} }
bool NetProc::synth_sync(Design*des, NetScope*scope, NetFF*ff, bool NetProc::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out) const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events)
{ {
if (events.count() > 0) {
cerr << get_line() << ": error: Events are unaccounted"
<< " for in process synthesis." << endl;
des->errors += 1;
}
/* Synthesize the input to the DFF. */ /* Synthesize the input to the DFF. */
return synth_async(des, scope, nex_map, nex_out); return synth_async(des, scope, nex_map, nex_out);
} }
@ -278,8 +285,64 @@ bool NetProcTop::synth_async(Design*des)
} }
bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff, bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out) const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events_in)
{ {
/* Synthesize the enable expression. */
NetNet*ce = expr_->synthesize(des);
assert(ce->pin_count() == 1);
/* Try first to turn the ce into an asynchronous set/reset
input. If the ce is linked to a probe, then that probe is a
set/reset input. */
for (unsigned idx = 0 ; idx < events_in.count() ; idx += 1) {
NetEvProbe*ev = events_in[idx];
if (connected(ce->pin(0), ev->pin(0))) {
assert(ev->edge() == NetEvProbe::POSEDGE);
/* Synthesize the true clause to figure out what
kind of set/reset we have. */
NetNet*asig = new NetNet(scope, scope->local_hsymbol(),
NetNet::WIRE, nex_map->pin_count());
asig->local_flag(true);
if_->synth_async(des, scope, nex_map, asig);
assert(asig->pin_count() == 1);
assert(asig->pin(0).nexus()->drivers_constant());
switch (asig->pin(0).nexus()->driven_value()) {
case verinum::V0:
cerr << get_line() << ": debug: Detected an"
<< " asynchronous reset." << endl;
connect(ff->pin_Aclr(), ce->pin(0));
break;
case verinum::V1:
cerr << get_line() << ": debug: Detected an"
<< " asynchronous set." << endl;
connect(ff->pin_Aset(), ce->pin(0));
break;
default:
assert(0);
}
delete asig;
assert(events_in.count() == 1);
return else_->synth_sync(des, scope, ff, nex_map,
nex_out, svector<NetEvProbe*>(0));
}
}
/* Failed to find an asynchronous set/reset, so any events
input are probably in error. */
if (events_in.count() > 0) {
cerr << get_line() << ": error: Events are unaccounted"
<< " for in process synthesis." << endl;
des->errors += 1;
}
/* If this is an if/then/else, then it is likely a /* If this is an if/then/else, then it is likely a
combinational if, and I should synthesize it that way. */ combinational if, and I should synthesize it that way. */
if (if_ && else_) { if (if_ && else_) {
@ -296,24 +359,30 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
assert(expr_); assert(expr_);
/* Synthesize the enable expression. */
NetNet*ce = expr_->synthesize(des);
assert(ce->pin_count() == 1);
connect(ff->pin_Enable(), ce->pin(0)); connect(ff->pin_Enable(), ce->pin(0));
return true; return true;
} }
bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff, bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out) const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events_in)
{ {
if (events_in.count() > 0) {
cerr << get_line() << ": error: Events are unaccounted"
<< " for in process synthesis." << endl;
des->errors += 1;
}
assert(events_in.count() == 0);
/* This can't be other then one unless there are named events, /* This can't be other then one unless there are named events,
which I cannot synthesize. */ which I cannot synthesize. */
assert(nevents_ == 1); assert(nevents_ == 1);
NetEvent*ev = events_[0]; NetEvent*ev = events_[0];
assert(ev->nprobe() >= 1); assert(ev->nprobe() >= 1);
svector<NetEvProbe*>events (ev->nprobe() - 1);
/* Get the input set from the substatement. This will be used /* Get the input set from the substatement. This will be used
to figure out which of the probes in the clock. */ to figure out which of the probes in the clock. */
@ -322,6 +391,7 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
/* Search for a clock input. The clock input is the edge event /* Search for a clock input. The clock input is the edge event
that is not also an input to the substatement. */ that is not also an input to the substatement. */
NetEvProbe*pclk = 0; NetEvProbe*pclk = 0;
unsigned event_idx = 0;
for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) {
NetEvProbe*tmp = ev->probe(idx); NetEvProbe*tmp = ev->probe(idx);
assert(tmp->pin_count() == 1); assert(tmp->pin_count() == 1);
@ -338,6 +408,9 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
des->errors += 1; des->errors += 1;
} }
pclk = tmp; pclk = tmp;
} else {
events[event_idx++] = tmp;
} }
} }
@ -353,15 +426,18 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
if (pclk->edge() == NetEvProbe::NEGEDGE) if (pclk->edge() == NetEvProbe::NEGEDGE)
ff->attribute("Clock:LPM_Polarity", verinum("INVERT")); ff->attribute("Clock:LPM_Polarity", verinum("INVERT"));
#if 0
if (ev->nprobe() > 1) { if (ev->nprobe() > 1) {
cerr << get_line() << ": sorry: I don't know how " cerr << get_line() << ": sorry: I don't know how "
<< "to synthesize asynchronous DFF controls." << "to synthesize asynchronous DFF controls."
<< endl; << endl;
return false; return false;
} }
#endif
/* Synthesize the input to the DFF. */ /* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope, ff, nex_map, nex_out); bool flag = statement_->synth_sync(des, scope, ff,
nex_map, nex_out, events);
return flag; return flag;
} }
@ -396,7 +472,9 @@ bool NetProcTop::synth_sync(Design*des)
} }
/* Synthesize the input to the DFF. */ /* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope(), ff, nex_q, nex_d); bool flag = statement_->synth_sync(des, scope(), ff,
nex_q, nex_d,
svector<NetEvProbe*>());
delete nex_q; delete nex_q;
@ -474,6 +552,9 @@ void synth2(Design*des)
/* /*
* $Log: synth2.cc,v $ * $Log: synth2.cc,v $
* Revision 1.12 2002/09/26 01:13:14 steve
* Synthesize async set/reset is certain cases.
*
* Revision 1.11 2002/09/24 00:58:35 steve * Revision 1.11 2002/09/24 00:58:35 steve
* More detailed check of process edge events. * More detailed check of process edge events.
* *