Skip to content

Commit

Permalink
Synthesize async set/reset is certain cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
steve committed Sep 26, 2002
1 parent 9faabfe commit 879a5a4
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 14 deletions.
15 changes: 11 additions & 4 deletions netlist.h
Expand Up @@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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

/*
Expand Down Expand Up @@ -51,6 +51,7 @@ class NetProc;
class NetProcTop;
class NetRelease;
class NetScope;
class NetEvProbe;
class NetExpr;
class NetESignal;
class NetFuncDef;
Expand Down Expand Up @@ -1223,7 +1224,8 @@ class NetProc : public LineInfo {
const NetNet*nex_map, NetNet*nex_out);

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;

Expand Down Expand Up @@ -1538,7 +1540,8 @@ class NetCondit : public NetProc {
const NetNet*nex_map, NetNet*nex_out);

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 int match_proc(struct proc_match_t*);
Expand Down Expand Up @@ -1755,7 +1758,8 @@ class NetEvWait : public NetProc {
const NetNet*nex_map, NetNet*nex_out);

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;

Expand Down Expand Up @@ -3051,6 +3055,9 @@ extern ostream& operator << (ostream&, NetNet::Type);

/*
* $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
* Add to synth2 support for synthesis of
* synchronous logic. This includes DFF enables
Expand Down
101 changes: 91 additions & 10 deletions synth2.cc
Expand Up @@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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

# include "config.h"
Expand All @@ -34,8 +34,15 @@ bool NetProc::synth_async(Design*des, NetScope*scope,
}

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. */
return synth_async(des, scope, nex_map, nex_out);
}
Expand Down Expand Up @@ -278,8 +285,64 @@ bool NetProcTop::synth_async(Design*des)
}

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
combinational if, and I should synthesize it that way. */
if (if_ && else_) {
Expand All @@ -296,24 +359,30 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,

assert(expr_);

/* Synthesize the enable expression. */
NetNet*ce = expr_->synthesize(des);
assert(ce->pin_count() == 1);

connect(ff->pin_Enable(), ce->pin(0));

return true;
}

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,
which I cannot synthesize. */
assert(nevents_ == 1);
NetEvent*ev = events_[0];

assert(ev->nprobe() >= 1);
svector<NetEvProbe*>events (ev->nprobe() - 1);

/* Get the input set from the substatement. This will be used
to figure out which of the probes in the clock. */
Expand All @@ -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
that is not also an input to the substatement. */
NetEvProbe*pclk = 0;
unsigned event_idx = 0;
for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) {
NetEvProbe*tmp = ev->probe(idx);
assert(tmp->pin_count() == 1);
Expand All @@ -338,6 +408,9 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
des->errors += 1;
}
pclk = tmp;

} else {
events[event_idx++] = tmp;
}
}

Expand All @@ -353,15 +426,18 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
if (pclk->edge() == NetEvProbe::NEGEDGE)
ff->attribute("Clock:LPM_Polarity", verinum("INVERT"));

#if 0
if (ev->nprobe() > 1) {
cerr << get_line() << ": sorry: I don't know how "
<< "to synthesize asynchronous DFF controls."
<< endl;
return false;
}
#endif

/* 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;
}
Expand Down Expand Up @@ -396,7 +472,9 @@ bool NetProcTop::synth_sync(Design*des)
}

/* 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;

Expand Down Expand Up @@ -474,6 +552,9 @@ void synth2(Design*des)

/*
* $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
* More detailed check of process edge events.
*
Expand Down

0 comments on commit 879a5a4

Please sign in to comment.