Add to synth2 support for synthesis of

synchronous logic. This includes DFF enables
 modeled by if/then/else.
This commit is contained in:
steve 2002-09-16 00:30:33 +00:00
parent 8fbacc966e
commit eb81062d85
4 changed files with 220 additions and 11 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.133 2002/08/12 00:27:10 steve Exp $"
#ident "$Id: Makefile.in,v 1.134 2002/09/16 00:30:33 steve Exp $"
#
#
SHELL = /bin/sh
@ -126,7 +126,7 @@ net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \
set_width.o sync.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o \

View File

@ -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.261 2002/09/12 15:49:43 steve Exp $"
#ident "$Id: netlist.h,v 1.262 2002/09/16 00:30:33 steve Exp $"
#endif
/*
@ -1214,10 +1214,17 @@ class NetProc : public LineInfo {
// process. Most process types are not.
virtual bool is_asynchronous();
// Return true if this represents the root of a synchronous
// process. Most process types are not.
virtual bool is_synchronous();
// synthesize as asynchronous logic, and return true.
virtual bool synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out);
virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out);
virtual void dump(ostream&, unsigned ind) const;
private:
@ -1530,6 +1537,9 @@ class NetCondit : public NetProc {
bool synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out);
bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out);
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
virtual void dump(ostream&, unsigned ind) const;
@ -1735,11 +1745,18 @@ class NetEvWait : public NetProc {
// process. This method checks.
virtual bool is_asynchronous();
// It is possible that this is the root of a synchronous
// process? This method checks.
virtual bool is_synchronous();
virtual void nex_output(NexusSet&out);
virtual bool synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out);
virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out);
virtual void dump(ostream&, unsigned ind) const;
private:
@ -2116,13 +2133,20 @@ class NetProcTop : public LineInfo, public Attrib {
NetScope*scope();
const NetScope*scope() const;
/* Return true of this process represents combinational logic. */
/* Return true if this process represents combinational logic. */
bool is_asynchronous();
/* Create asynchronous logic from this thread and return true,
or return false if that cannot be done. */
bool synth_async(Design*des);
/* Return true if this process represents synchronous logic. */
bool is_synchronous();
/* Create synchronous logic from this thread and return true,
or return false if that cannot be done. */
bool synth_sync(Design*des);
void dump(ostream&, unsigned ind) const;
bool emit(struct target_t*tgt) const;
@ -3027,6 +3051,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.262 2002/09/16 00:30:33 steve
* Add to synth2 support for synthesis of
* synchronous logic. This includes DFF enables
* modeled by if/then/else.
*
* Revision 1.261 2002/09/12 15:49:43 steve
* Add support for binary nand operator.
*

75
sync.cc Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sync.cc,v 1.1 2002/09/16 00:30:33 steve Exp $"
#endif
# include "config.h"
# include "functor.h"
# include "netlist.h"
# include <assert.h>
/*
* Most process statements are not roots of synchronous logic.
*/
bool NetProc::is_synchronous()
{
return false;
}
bool NetEvWait::is_synchronous()
{
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
NetEvent*ev = events_[idx];
if (ev->nprobe() == 0)
return false;
for (unsigned pdx = 0 ; pdx < ev->nprobe() ; pdx += 1) {
NetEvProbe*pr = ev->probe(pdx);
/* No level sensitive clocks. */
if (pr->edge() == NetEvProbe::ANYEDGE)
return false;
}
}
/* So we know that there is a clock source. Check that the
input to the storage is asynchronous. */
return true; //statement_->is_asynchronous();
}
bool NetProcTop::is_synchronous()
{
if (type_ == NetProcTop::KINITIAL)
return false;
return statement_->is_synchronous();
}
/*
* $Log: sync.cc,v $
* Revision 1.1 2002/09/16 00:30:33 steve
* Add to synth2 support for synthesis of
* synchronous logic. This includes DFF enables
* modeled by if/then/else.
*
*/

119
synth2.cc
View File

@ -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.8 2002/08/18 22:07:16 steve Exp $"
#ident "$Id: synth2.cc,v 1.9 2002/09/16 00:30:33 steve Exp $"
#endif
# include "config.h"
@ -27,6 +27,19 @@
# include "compiler.h"
# include <assert.h>
bool NetProc::synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out)
{
return false;
}
bool NetProc::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out)
{
/* Synthesize the input to the DFF. */
return synth_async(des, scope, nex_map, nex_out);
}
static unsigned find_nexus_in_set(const NetNet*nset, const Nexus*nex)
{
unsigned idx = 0;
@ -241,12 +254,6 @@ bool NetEvWait::synth_async(Design*des, NetScope*scope,
return statement_->synth_async(des, scope, nex_map, nex_out);
}
bool NetProc::synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out)
{
return false;
}
bool NetProcTop::synth_async(Design*des)
{
NexusSet nex_set;
@ -263,6 +270,92 @@ bool NetProcTop::synth_async(Design*des)
return flag;
}
bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out)
{
/* If this is an if/then/else, then it is likely a
combinational if, and I should synthesize it that way. */
if (if_ && else_) {
return synth_async(des, scope, nex_map, nex_out);
}
assert(if_);
assert(!else_);
/* Synthesize the input to the DFF. */
bool flag = if_->synth_async(des, scope, nex_map, nex_out);
if (flag == false)
return flag;
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)
{
/* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope, ff, nex_map, nex_out);
assert(nevents_ == 1);
NetEvent*ev = events_[0];
assert(ev->nprobe() == 1);
NetEvProbe*pclk = ev->probe(0);
assert(pclk->pin_count() == 1);
connect(ff->pin_Clock(), pclk->pin(0));
if (pclk->edge() == NetEvProbe::NEGEDGE)
ff->attribute("Clock:LPM_Polarity", verinum("INVERT"));
return flag;
}
bool NetProcTop::synth_sync(Design*des)
{
NexusSet nex_set;
statement_->nex_output(nex_set);
NetFF*ff = new NetFF(scope(), scope()->local_hsymbol().c_str(),
nex_set.count());
des->add_node(ff);
ff->attribute("LPM_FFType", verinum("DFF"));
/* The D inputs to the DFF device will receive the output from
the statments of the process. */
NetNet*nex_d = new NetNet(scope(), scope()->local_hsymbol().c_str(),
NetNet::WIRE, nex_set.count());
nex_d->local_flag(true);
for (unsigned idx = 0 ; idx < nex_set.count() ; idx += 1) {
connect(nex_d->pin(idx), ff->pin_Data(idx));
}
/* The Q outputs of the DFF will connect to the actual outputs
of the process. Thus, the DFF will be between the outputs
of the process and the outputs of the substatement. */
NetNet*nex_q = new NetNet(scope(), "tmpq", NetNet::WIRE,
nex_set.count());
for (unsigned idx = 0 ; idx < nex_set.count() ; idx += 1) {
connect(nex_set[idx], nex_q->pin(idx));
connect(nex_q->pin(idx), ff->pin_Q(idx));
}
/* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope(), ff, nex_q, nex_d);
delete nex_q;
return flag;
}
class synth2_f : public functor_t {
public:
@ -281,6 +374,13 @@ void synth2_f::process(class Design*des, class NetProcTop*top)
if (top->attribute("ivl_synthesis_off").as_ulong() != 0)
return;
if (top->is_synchronous()) do {
bool flag = top->synth_sync(des);
assert(flag);
des->delete_process(top);
return;
} while (0);
if (! top->is_asynchronous()) {
bool synth_error_flag = false;
if (top->attribute("ivl_combinational").as_ulong() != 0) {
@ -324,6 +424,11 @@ void synth2(Design*des)
/*
* $Log: synth2.cc,v $
* Revision 1.9 2002/09/16 00:30:33 steve
* Add to synth2 support for synthesis of
* synchronous logic. This includes DFF enables
* modeled by if/then/else.
*
* Revision 1.8 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*