Add to synth2 support for synthesis of
synchronous logic. This includes DFF enables modeled by if/then/else.
This commit is contained in:
parent
8fbacc966e
commit
eb81062d85
|
|
@ -16,7 +16,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# 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
|
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_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 \
|
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
||||||
parse.o parse_misc.o pform.o pform_dump.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 \
|
verinum.o verireal.o target.o targets.o \
|
||||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||||
PExpr.o PGate.o \
|
PExpr.o PGate.o \
|
||||||
|
|
|
||||||
33
netlist.h
33
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.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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1214,10 +1214,17 @@ class NetProc : public LineInfo {
|
||||||
// process. Most process types are not.
|
// process. Most process types are not.
|
||||||
virtual bool is_asynchronous();
|
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.
|
// synthesize as asynchronous logic, and return true.
|
||||||
virtual bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
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;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -1530,6 +1537,9 @@ class NetCondit : public NetProc {
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
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 bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -1735,11 +1745,18 @@ class NetEvWait : public NetProc {
|
||||||
// process. This method checks.
|
// process. This method checks.
|
||||||
virtual bool is_asynchronous();
|
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 void nex_output(NexusSet&out);
|
||||||
|
|
||||||
virtual bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
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;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -2116,13 +2133,20 @@ class NetProcTop : public LineInfo, public Attrib {
|
||||||
NetScope*scope();
|
NetScope*scope();
|
||||||
const NetScope*scope() const;
|
const NetScope*scope() const;
|
||||||
|
|
||||||
/* Return true of this process represents combinational logic. */
|
/* Return true if this process represents combinational logic. */
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
|
|
||||||
/* Create asynchronous logic from this thread and return true,
|
/* Create asynchronous logic from this thread and return true,
|
||||||
or return false if that cannot be done. */
|
or return false if that cannot be done. */
|
||||||
bool synth_async(Design*des);
|
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;
|
void dump(ostream&, unsigned ind) const;
|
||||||
bool emit(struct target_t*tgt) const;
|
bool emit(struct target_t*tgt) const;
|
||||||
|
|
||||||
|
|
@ -3027,6 +3051,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $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
|
* Revision 1.261 2002/09/12 15:49:43 steve
|
||||||
* Add support for binary nand operator.
|
* Add support for binary nand operator.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
119
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.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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -27,6 +27,19 @@
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <assert.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)
|
static unsigned find_nexus_in_set(const NetNet*nset, const Nexus*nex)
|
||||||
{
|
{
|
||||||
unsigned idx = 0;
|
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);
|
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)
|
bool NetProcTop::synth_async(Design*des)
|
||||||
{
|
{
|
||||||
NexusSet nex_set;
|
NexusSet nex_set;
|
||||||
|
|
@ -263,6 +270,92 @@ bool NetProcTop::synth_async(Design*des)
|
||||||
return flag;
|
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 {
|
class synth2_f : public functor_t {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -281,6 +374,13 @@ void synth2_f::process(class Design*des, class NetProcTop*top)
|
||||||
if (top->attribute("ivl_synthesis_off").as_ulong() != 0)
|
if (top->attribute("ivl_synthesis_off").as_ulong() != 0)
|
||||||
return;
|
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()) {
|
if (! top->is_asynchronous()) {
|
||||||
bool synth_error_flag = false;
|
bool synth_error_flag = false;
|
||||||
if (top->attribute("ivl_combinational").as_ulong() != 0) {
|
if (top->attribute("ivl_combinational").as_ulong() != 0) {
|
||||||
|
|
@ -324,6 +424,11 @@ void synth2(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: synth2.cc,v $
|
* $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
|
* Revision 1.8 2002/08/18 22:07:16 steve
|
||||||
* Detect temporaries in sequential block synthesis.
|
* Detect temporaries in sequential block synthesis.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue