Synthesize async set/reset is certain cases.
This commit is contained in:
parent
9faabfe995
commit
879a5a4cbe
15
netlist.h
15
netlist.h
|
|
@ -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
101
synth2.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue