Update DFF support to new data flow.
This commit is contained in:
parent
f884652c19
commit
365cfedd55
|
|
@ -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: compiler.h,v 1.26 2004/10/04 01:10:52 steve Exp $"
|
#ident "$Id: compiler.h,v 1.27 2005/04/24 23:44:01 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <list>
|
# include <list>
|
||||||
|
|
@ -84,6 +84,7 @@ extern bool verbose_flag;
|
||||||
extern bool debug_scopes;
|
extern bool debug_scopes;
|
||||||
extern bool debug_eval_tree;
|
extern bool debug_eval_tree;
|
||||||
extern bool debug_elaborate;
|
extern bool debug_elaborate;
|
||||||
|
extern bool debug_synth2;
|
||||||
|
|
||||||
/* Path to a directory useful for finding subcomponents. */
|
/* Path to a directory useful for finding subcomponents. */
|
||||||
extern const char*basedir;
|
extern const char*basedir;
|
||||||
|
|
@ -136,6 +137,9 @@ extern int load_sys_func_table(const char*path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: compiler.h,v $
|
* $Log: compiler.h,v $
|
||||||
|
* Revision 1.27 2005/04/24 23:44:01 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.26 2004/10/04 01:10:52 steve
|
* Revision 1.26 2004/10/04 01:10:52 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
58
cprop.cc
58
cprop.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: cprop.cc,v 1.51 2005/02/12 22:52:45 steve Exp $"
|
#ident "$Id: cprop.cc,v 1.52 2005/04/24 23:44:01 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -201,54 +201,15 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
|
||||||
// Look for and count unlinked FF outputs. Note that if the
|
// Look for and count unlinked FF outputs. Note that if the
|
||||||
// Data and Q pins are connected together, they can be removed
|
// Data and Q pins are connected together, they can be removed
|
||||||
// from the circuit, since it doesn't do anything.
|
// from the circuit, since it doesn't do anything.
|
||||||
unsigned unlinked_count = 0;
|
|
||||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
|
||||||
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))
|
|
||||||
&& (! obj->pin_Sclr().is_linked())
|
|
||||||
&& (! obj->pin_Sset().is_linked())
|
|
||||||
&& (! obj->pin_Aclr().is_linked())
|
|
||||||
&& (! obj->pin_Aset().is_linked())) {
|
|
||||||
obj->pin_Data(idx).unlink();
|
|
||||||
obj->pin_Q(idx).unlink();
|
|
||||||
}
|
|
||||||
if (! obj->pin_Q(idx).is_linked())
|
|
||||||
unlinked_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the entire FF is unlinked, remove the whole thing.
|
if (connected(obj->pin_Data(), obj->pin_Q())
|
||||||
if (unlinked_count == obj->width()) {
|
&& (! obj->pin_Sclr().is_linked())
|
||||||
|
&& (! obj->pin_Sset().is_linked())
|
||||||
|
&& (! obj->pin_Aclr().is_linked())
|
||||||
|
&& (! obj->pin_Aset().is_linked())) {
|
||||||
|
obj->pin_Data().unlink();
|
||||||
|
obj->pin_Q().unlink();
|
||||||
delete obj;
|
delete obj;
|
||||||
count += 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If some of the FFs are unconnected, make a new FF array
|
|
||||||
// that does not include the useless FF devices.
|
|
||||||
if (unlinked_count > 0) {
|
|
||||||
NetFF*tmp = new NetFF(obj->scope(), obj->name(),
|
|
||||||
obj->width()-unlinked_count);
|
|
||||||
connect(tmp->pin_Clock(), obj->pin_Clock());
|
|
||||||
connect(tmp->pin_Enable(), obj->pin_Enable());
|
|
||||||
connect(tmp->pin_Aload(), obj->pin_Aload());
|
|
||||||
connect(tmp->pin_Aset(), obj->pin_Aset());
|
|
||||||
connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
|
||||||
connect(tmp->pin_Sload(), obj->pin_Sload());
|
|
||||||
connect(tmp->pin_Sset(), obj->pin_Sset());
|
|
||||||
connect(tmp->pin_Sclr(), obj->pin_Sclr());
|
|
||||||
|
|
||||||
unsigned tidx = 0;
|
|
||||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
|
|
||||||
if (obj->pin_Q(idx).is_linked()) {
|
|
||||||
connect(tmp->pin_Data(tidx), obj->pin_Data(idx));
|
|
||||||
connect(tmp->pin_Q(tidx), obj->pin_Q(idx));
|
|
||||||
tidx += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(tidx == obj->width() - unlinked_count);
|
|
||||||
delete obj;
|
|
||||||
des->add_node(tmp);
|
|
||||||
count += 1;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -980,6 +941,9 @@ void cprop(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: cprop.cc,v $
|
* $Log: cprop.cc,v $
|
||||||
|
* Revision 1.52 2005/04/24 23:44:01 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.51 2005/02/12 22:52:45 steve
|
* Revision 1.51 2005/02/12 22:52:45 steve
|
||||||
* Fix copyright notice.
|
* Fix copyright notice.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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: elaborate.cc,v 1.320 2005/03/05 05:38:33 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.321 2005/04/24 23:44:01 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1372,7 +1372,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
unsigned wid = count_lval_width(lv);
|
unsigned wid = count_lval_width(lv);
|
||||||
rv->set_width(wid);
|
bool flag = rv->set_width(wid);
|
||||||
rv = pad_to_width(rv, wid);
|
rv = pad_to_width(rv, wid);
|
||||||
assert(rv->expr_width() >= wid);
|
assert(rv->expr_width() >= wid);
|
||||||
}
|
}
|
||||||
|
|
@ -2942,6 +2942,9 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.321 2005/04/24 23:44:01 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.320 2005/03/05 05:38:33 steve
|
* Revision 1.320 2005/03/05 05:38:33 steve
|
||||||
* Get rval width right for arguments into task calls.
|
* Get rval width right for arguments into task calls.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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: expr_synth.cc,v 1.65 2005/03/12 06:43:35 steve Exp $"
|
#ident "$Id: expr_synth.cc,v 1.66 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -788,14 +788,15 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||||
osig->local_flag(true);
|
osig->local_flag(true);
|
||||||
|
|
||||||
/* Make sure both value operands are the right width. */
|
/* Make sure both value operands are the right width. */
|
||||||
tsig = pad_to_width(des, tsig, width);
|
tsig = crop_to_width(des, pad_to_width(des, tsig, width), width);
|
||||||
fsig = pad_to_width(des, fsig, width);
|
fsig = crop_to_width(des, pad_to_width(des, fsig, width), width);
|
||||||
|
|
||||||
assert(width <= tsig->vector_width());
|
assert(width == tsig->vector_width());
|
||||||
assert(width <= fsig->vector_width());
|
assert(width == fsig->vector_width());
|
||||||
|
|
||||||
perm_string oname = csig->scope()->local_symbol();
|
perm_string oname = csig->scope()->local_symbol();
|
||||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, width);
|
NetMux *mux = new NetMux(csig->scope(), oname, width,
|
||||||
|
2, csig->vector_width());
|
||||||
connect(tsig->pin(0), mux->pin_Data(1));
|
connect(tsig->pin(0), mux->pin_Data(1));
|
||||||
connect(fsig->pin(0), mux->pin_Data(0));
|
connect(fsig->pin(0), mux->pin_Data(0));
|
||||||
connect(osig->pin(0), mux->pin_Result());
|
connect(osig->pin(0), mux->pin_Result());
|
||||||
|
|
@ -842,6 +843,9 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: expr_synth.cc,v $
|
* $Log: expr_synth.cc,v $
|
||||||
|
* Revision 1.66 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.65 2005/03/12 06:43:35 steve
|
* Revision 1.65 2005/03/12 06:43:35 steve
|
||||||
* Update support for LPM_MOD.
|
* Update support for LPM_MOD.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
10
ivl_target.h
10
ivl_target.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: ivl_target.h,v 1.151 2005/04/13 06:35:11 steve Exp $"
|
#ident "$Id: ivl_target.h,v 1.152 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -891,6 +891,11 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
||||||
* are. All the data inputs have the same width, the width of the
|
* are. All the data inputs have the same width, the width of the
|
||||||
* ivl_lpm_q output.
|
* ivl_lpm_q output.
|
||||||
*
|
*
|
||||||
|
* - D-FlipFlop (IVL_LPM_FF)
|
||||||
|
* This data is an edge sensitive register. The ivl_lpm_q output and
|
||||||
|
* single ivl_lpm_data input are the same with, ivl_lpm_width. This
|
||||||
|
* device carries a vector like other LPM devices.
|
||||||
|
*
|
||||||
* - Memory port (IVL_LPM_RAM)
|
* - Memory port (IVL_LPM_RAM)
|
||||||
* These are structural ports into a memory device. They represent
|
* These are structural ports into a memory device. They represent
|
||||||
* address/data ports of a memory device that the context can hook to
|
* address/data ports of a memory device that the context can hook to
|
||||||
|
|
@ -1642,6 +1647,9 @@ _END_DECL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: ivl_target.h,v $
|
* $Log: ivl_target.h,v $
|
||||||
|
* Revision 1.152 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.151 2005/04/13 06:35:11 steve
|
* Revision 1.151 2005/04/13 06:35:11 steve
|
||||||
* Make logic aware of strength.
|
* Make logic aware of strength.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
9
main.cc
9
main.cc
|
|
@ -19,7 +19,7 @@ const char COPYRIGHT[] =
|
||||||
* 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: main.cc,v 1.88 2005/01/22 01:06:55 steve Exp $"
|
#ident "$Id: main.cc,v 1.89 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -112,6 +112,7 @@ bool error_implicit = false;
|
||||||
bool debug_scopes = false;
|
bool debug_scopes = false;
|
||||||
bool debug_eval_tree = false;
|
bool debug_eval_tree = false;
|
||||||
bool debug_elaborate = false;
|
bool debug_elaborate = false;
|
||||||
|
bool debug_synth2 = false;
|
||||||
/*
|
/*
|
||||||
* Verbose messages enabled.
|
* Verbose messages enabled.
|
||||||
*/
|
*/
|
||||||
|
|
@ -318,6 +319,9 @@ static void read_iconfig_file(const char*ipath)
|
||||||
} else if (strcmp(cp,"elaborate") == 0) {
|
} else if (strcmp(cp,"elaborate") == 0) {
|
||||||
debug_elaborate = true;
|
debug_elaborate = true;
|
||||||
cerr << "debug: Enable elaborate debug" << endl;
|
cerr << "debug: Enable elaborate debug" << endl;
|
||||||
|
} else if (strcmp(cp,"synth2") == 0) {
|
||||||
|
debug_synth2 = true;
|
||||||
|
cerr << "debug: Enable synth2 debug" << endl;
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,6 +758,9 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: main.cc,v $
|
* $Log: main.cc,v $
|
||||||
|
* Revision 1.89 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.88 2005/01/22 01:06:55 steve
|
* Revision 1.88 2005/01/22 01:06:55 steve
|
||||||
* Change case compare from logic to an LPM node.
|
* Change case compare from logic to an LPM node.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
29
net_link.cc
29
net_link.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: net_link.cc,v 1.15 2005/01/09 20:16:01 steve Exp $"
|
#ident "$Id: net_link.cc,v 1.16 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -313,6 +313,30 @@ void* Nexus::t_cookie(void*val)const
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Nexus::vector_width() const
|
||||||
|
{
|
||||||
|
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||||
|
const NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj());
|
||||||
|
if (sig == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return sig->vector_width();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet* Nexus::pick_any_net()
|
||||||
|
{
|
||||||
|
for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||||
|
NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj());
|
||||||
|
if (sig != 0)
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char* Nexus::name() const
|
const char* Nexus::name() const
|
||||||
{
|
{
|
||||||
if (name_)
|
if (name_)
|
||||||
|
|
@ -499,6 +523,9 @@ bool NexusSet::intersect(const NexusSet&that) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_link.cc,v $
|
* $Log: net_link.cc,v $
|
||||||
|
* Revision 1.16 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.15 2005/01/09 20:16:01 steve
|
* Revision 1.15 2005/01/09 20:16:01 steve
|
||||||
* Use PartSelect/PV and VP to handle part selects through ports.
|
* Use PartSelect/PV and VP to handle part selects through ports.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
115
netlist.cc
115
netlist.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: netlist.cc,v 1.241 2005/04/08 04:51:16 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.242 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -226,6 +226,15 @@ NetNode::~NetNode()
|
||||||
design_->del_node(this);
|
design_->del_node(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetBus::NetBus(NetScope*s, unsigned pin_count)
|
||||||
|
: NetObj(s, perm_string::literal(""), pin_count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NetBus::~NetBus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||||
: NetObj(s, n, 1), sig_next_(0), sig_prev_(0),
|
: NetObj(s, n, 1), sig_next_(0), sig_prev_(0),
|
||||||
type_(t), port_type_(NOT_A_PORT), signed_(false), msb_(npins-1), lsb_(0),
|
type_(t), port_type_(NOT_A_PORT), signed_(false), msb_(npins-1), lsb_(0),
|
||||||
|
|
@ -588,43 +597,34 @@ unsigned NetReplicate::repeat() const
|
||||||
* like so:
|
* like so:
|
||||||
* 0 -- Clock
|
* 0 -- Clock
|
||||||
* 1 -- Enable
|
* 1 -- Enable
|
||||||
* 2 -- Aload
|
* 2 -- Aset
|
||||||
* 3 -- Aset
|
* 3 -- Aclr
|
||||||
* 4 -- Aclr
|
* 4 -- Sset
|
||||||
* 5 -- Sload
|
* 5 -- Sclr
|
||||||
* 6 -- Sset
|
* 6 -- Data
|
||||||
* 7 -- Sclr
|
* 7 -- Q
|
||||||
*
|
|
||||||
* 8 -- Data[0]
|
|
||||||
* 9 -- Q[0]
|
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NetFF::NetFF(NetScope*s, perm_string n, unsigned wid)
|
NetFF::NetFF(NetScope*s, perm_string n, unsigned width)
|
||||||
: NetNode(s, n, 8 + 2*wid)
|
: NetNode(s, n, 8), width_(width)
|
||||||
{
|
{
|
||||||
pin_Clock().set_dir(Link::INPUT);
|
pin_Clock().set_dir(Link::INPUT);
|
||||||
pin_Clock().set_name(perm_string::literal("Clock"), 0);
|
pin_Clock().set_name(perm_string::literal("Clock"), 0);
|
||||||
pin_Enable().set_dir(Link::INPUT);
|
pin_Enable().set_dir(Link::INPUT);
|
||||||
pin_Enable().set_name(perm_string::literal("Enable"), 0);
|
pin_Enable().set_name(perm_string::literal("Enable"), 0);
|
||||||
pin_Aload().set_dir(Link::INPUT);
|
|
||||||
pin_Aload().set_name(perm_string::literal("Aload"), 0);
|
|
||||||
pin_Aset().set_dir(Link::INPUT);
|
pin_Aset().set_dir(Link::INPUT);
|
||||||
pin_Aset().set_name(perm_string::literal("Aset"), 0);
|
pin_Aset().set_name(perm_string::literal("Aset"), 0);
|
||||||
pin_Aclr().set_dir(Link::INPUT);
|
pin_Aclr().set_dir(Link::INPUT);
|
||||||
pin_Aclr().set_name(perm_string::literal("Aclr"), 0);
|
pin_Aclr().set_name(perm_string::literal("Aclr"), 0);
|
||||||
pin_Sload().set_dir(Link::INPUT);
|
|
||||||
pin_Sload().set_name(perm_string::literal("Sload"), 0);
|
|
||||||
pin_Sset().set_dir(Link::INPUT);
|
pin_Sset().set_dir(Link::INPUT);
|
||||||
pin_Sset().set_name(perm_string::literal("Sset"), 0);
|
pin_Sset().set_name(perm_string::literal("Sset"), 0);
|
||||||
pin_Sclr().set_dir(Link::INPUT);
|
pin_Sclr().set_dir(Link::INPUT);
|
||||||
pin_Sclr().set_name(perm_string::literal("Sclr"), 0);
|
pin_Sclr().set_name(perm_string::literal("Sclr"), 0);
|
||||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
pin_Data().set_dir(Link::INPUT);
|
||||||
pin_Data(idx).set_dir(Link::INPUT);
|
pin_Data().set_name(perm_string::literal("Data"), 0);
|
||||||
pin_Data(idx).set_name(perm_string::literal("Data"), idx);
|
pin_Q().set_dir(Link::OUTPUT);
|
||||||
pin_Q(idx).set_dir(Link::OUTPUT);
|
pin_Q().set_name(perm_string::literal("Q"), 0);
|
||||||
pin_Q(idx).set_name(perm_string::literal("Q"), idx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetFF::~NetFF()
|
NetFF::~NetFF()
|
||||||
|
|
@ -633,7 +633,7 @@ NetFF::~NetFF()
|
||||||
|
|
||||||
unsigned NetFF::width() const
|
unsigned NetFF::width() const
|
||||||
{
|
{
|
||||||
return (pin_count() - 8) / 2;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Clock()
|
Link& NetFF::pin_Clock()
|
||||||
|
|
@ -656,82 +656,64 @@ const Link& NetFF::pin_Enable() const
|
||||||
return pin(1);
|
return pin(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Aload()
|
Link& NetFF::pin_Aset()
|
||||||
{
|
{
|
||||||
return pin(2);
|
return pin(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Aset()
|
|
||||||
{
|
|
||||||
return pin(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Link& NetFF::pin_Aset() const
|
const Link& NetFF::pin_Aset() const
|
||||||
{
|
{
|
||||||
return pin(3);
|
return pin(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Aclr()
|
Link& NetFF::pin_Aclr()
|
||||||
{
|
{
|
||||||
return pin(4);
|
return pin(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Link& NetFF::pin_Aclr() const
|
const Link& NetFF::pin_Aclr() const
|
||||||
{
|
{
|
||||||
return pin(4);
|
return pin(3);
|
||||||
}
|
|
||||||
|
|
||||||
Link& NetFF::pin_Sload()
|
|
||||||
{
|
|
||||||
return pin(5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Sset()
|
Link& NetFF::pin_Sset()
|
||||||
{
|
{
|
||||||
return pin(6);
|
return pin(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Link& NetFF::pin_Sset() const
|
const Link& NetFF::pin_Sset() const
|
||||||
{
|
{
|
||||||
return pin(6);
|
return pin(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Sclr()
|
Link& NetFF::pin_Sclr()
|
||||||
{
|
{
|
||||||
return pin(7);
|
return pin(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Link& NetFF::pin_Sclr() const
|
const Link& NetFF::pin_Sclr() const
|
||||||
|
{
|
||||||
|
return pin(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetFF::pin_Data()
|
||||||
|
{
|
||||||
|
return pin(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link& NetFF::pin_Data() const
|
||||||
|
{
|
||||||
|
return pin(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetFF::pin_Q()
|
||||||
{
|
{
|
||||||
return pin(7);
|
return pin(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link& NetFF::pin_Data(unsigned w)
|
const Link& NetFF::pin_Q() const
|
||||||
{
|
{
|
||||||
unsigned pn = 8 + 2*w;
|
return pin(7);
|
||||||
assert(pn < pin_count());
|
|
||||||
return pin(pn);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Link& NetFF::pin_Data(unsigned w) const
|
|
||||||
{
|
|
||||||
unsigned pn = 8 + 2*w;
|
|
||||||
assert(pn < pin_count());
|
|
||||||
return pin(pn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Link& NetFF::pin_Q(unsigned w)
|
|
||||||
{
|
|
||||||
unsigned pn = 9 + w*2;
|
|
||||||
assert(pn < pin_count());
|
|
||||||
return pin(pn);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Link& NetFF::pin_Q(unsigned w) const
|
|
||||||
{
|
|
||||||
unsigned pn = 9 + w*2;
|
|
||||||
assert(pn < pin_count());
|
|
||||||
return pin(pn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetFF::aset_value(const verinum&val)
|
void NetFF::aset_value(const verinum&val)
|
||||||
|
|
@ -2174,6 +2156,9 @@ const NetProc*NetTaskDef::proc() const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.242 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.241 2005/04/08 04:51:16 steve
|
* Revision 1.241 2005/04/08 04:51:16 steve
|
||||||
* All memory addresses are signed.
|
* All memory addresses are signed.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
62
netlist.h
62
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.340 2005/04/08 04:51:16 steve Exp $"
|
#ident "$Id: netlist.h,v 1.341 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -48,6 +48,7 @@ class ostream;
|
||||||
class Design;
|
class Design;
|
||||||
class Link;
|
class Link;
|
||||||
class Nexus;
|
class Nexus;
|
||||||
|
class NetNet;
|
||||||
class NetNode;
|
class NetNode;
|
||||||
class NetProc;
|
class NetProc;
|
||||||
class NetProcTop;
|
class NetProcTop;
|
||||||
|
|
@ -253,6 +254,12 @@ class Nexus {
|
||||||
Link*first_nlink();
|
Link*first_nlink();
|
||||||
const Link* first_nlink()const;
|
const Link* first_nlink()const;
|
||||||
|
|
||||||
|
/* Get the width of the Nexus, or 0 if there are no vectors
|
||||||
|
(in the form of NetNet objects) linked. */
|
||||||
|
unsigned vector_width() const;
|
||||||
|
|
||||||
|
NetNet* pick_any_net();
|
||||||
|
|
||||||
/* This method returns true if all the possible drivers of
|
/* This method returns true if all the possible drivers of
|
||||||
this nexus are constant. It will also return true if there
|
this nexus are constant. It will also return true if there
|
||||||
are no drivers at all. */
|
are no drivers at all. */
|
||||||
|
|
@ -316,6 +323,22 @@ class NexusSet {
|
||||||
NexusSet& operator= (const NexusSet&);
|
NexusSet& operator= (const NexusSet&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A NetBus is a transparent device that is merely a bunch of pins
|
||||||
|
* used to tie some pins to. It is a convenient way to collect a
|
||||||
|
* bundle of pins and pass that bundle around.
|
||||||
|
*/
|
||||||
|
class NetBus : public NetObj {
|
||||||
|
|
||||||
|
public:
|
||||||
|
NetBus(NetScope*scope, unsigned pin_count);
|
||||||
|
~NetBus();
|
||||||
|
|
||||||
|
private: // not implemented
|
||||||
|
NetBus(const NetBus&);
|
||||||
|
NetBus& operator= (const NetBus&);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A NetNode is a device of some sort, where each pin has a different
|
* A NetNode is a device of some sort, where each pin has a different
|
||||||
* meaning. (i.e., pin(0) is the output to an and gate.) NetNode
|
* meaning. (i.e., pin(0) is the output to an and gate.) NetNode
|
||||||
|
|
@ -699,22 +722,19 @@ class NetModulo : public NetNode {
|
||||||
class NetFF : public NetNode {
|
class NetFF : public NetNode {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetFF(NetScope*s, perm_string n, unsigned width);
|
NetFF(NetScope*s, perm_string n, unsigned vector_width);
|
||||||
~NetFF();
|
~NetFF();
|
||||||
|
|
||||||
unsigned width() const;
|
unsigned width() const;
|
||||||
|
|
||||||
Link& pin_Clock();
|
Link& pin_Clock();
|
||||||
Link& pin_Enable();
|
Link& pin_Enable();
|
||||||
Link& pin_Aload();
|
|
||||||
Link& pin_Aset();
|
Link& pin_Aset();
|
||||||
Link& pin_Aclr();
|
Link& pin_Aclr();
|
||||||
Link& pin_Sload();
|
|
||||||
Link& pin_Sset();
|
Link& pin_Sset();
|
||||||
Link& pin_Sclr();
|
Link& pin_Sclr();
|
||||||
|
Link& pin_Data();
|
||||||
Link& pin_Data(unsigned);
|
Link& pin_Q();
|
||||||
Link& pin_Q(unsigned);
|
|
||||||
|
|
||||||
const Link& pin_Clock() const;
|
const Link& pin_Clock() const;
|
||||||
const Link& pin_Enable() const;
|
const Link& pin_Enable() const;
|
||||||
|
|
@ -722,8 +742,8 @@ class NetFF : public NetNode {
|
||||||
const Link& pin_Aclr() const;
|
const Link& pin_Aclr() const;
|
||||||
const Link& pin_Sset() const;
|
const Link& pin_Sset() const;
|
||||||
const Link& pin_Sclr() const;
|
const Link& pin_Sclr() const;
|
||||||
const Link& pin_Data(unsigned) const;
|
const Link& pin_Data() const;
|
||||||
const Link& pin_Q(unsigned) const;
|
const Link& pin_Q() const;
|
||||||
|
|
||||||
void aset_value(const verinum&val);
|
void aset_value(const verinum&val);
|
||||||
const verinum& aset_value() const;
|
const verinum& aset_value() const;
|
||||||
|
|
@ -736,6 +756,7 @@ class NetFF : public NetNode {
|
||||||
virtual void functor_node(Design*des, functor_t*fun);
|
virtual void functor_node(Design*des, functor_t*fun);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
unsigned width_;
|
||||||
verinum aset_value_;
|
verinum aset_value_;
|
||||||
verinum sset_value_;
|
verinum sset_value_;
|
||||||
};
|
};
|
||||||
|
|
@ -1479,10 +1500,10 @@ class NetProc : public virtual LineInfo {
|
||||||
|
|
||||||
// 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 NetBus&nex_map, NetBus&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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -1614,7 +1635,7 @@ class NetAssignBase : public NetProc {
|
||||||
unsigned lwidth() const;
|
unsigned lwidth() const;
|
||||||
|
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
const NetBus&nex_map, NetBus&nex_out);
|
||||||
|
|
||||||
// This dumps all the lval structures.
|
// This dumps all the lval structures.
|
||||||
void dump_lval(ostream&) const;
|
void dump_lval(ostream&) const;
|
||||||
|
|
@ -1681,10 +1702,10 @@ class NetBlock : public NetProc {
|
||||||
|
|
||||||
// synthesize as asynchronous logic, and return true.
|
// synthesize as asynchronous logic, and return true.
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
const NetBus&nex_map, NetBus&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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
// This version of emit_recurse scans all the statements of
|
// This version of emit_recurse scans all the statements of
|
||||||
|
|
@ -1736,7 +1757,7 @@ class NetCase : public NetProc {
|
||||||
virtual void nex_output(NexusSet&out);
|
virtual void nex_output(NexusSet&out);
|
||||||
|
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
const NetBus&nex_map, NetBus&nex_out);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -1804,10 +1825,10 @@ class NetCondit : public NetProc {
|
||||||
|
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
const NetBus&nex_map, NetBus&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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
|
|
@ -2024,10 +2045,10 @@ class NetEvWait : public NetProc {
|
||||||
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 NetBus&nex_map, NetBus&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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3416,6 +3437,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.341 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.340 2005/04/08 04:51:16 steve
|
* Revision 1.340 2005/04/08 04:51:16 steve
|
||||||
* All memory addresses are signed.
|
* All memory addresses are signed.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
netmisc.h
12
netmisc.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: netmisc.h,v 1.20 2005/01/24 05:28:31 steve Exp $"
|
#ident "$Id: netmisc.h,v 1.21 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -50,6 +50,13 @@ extern NetScope* symbol_search(Design*des, NetScope*start, hname_t path,
|
||||||
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
|
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
|
||||||
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
|
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function transforms an expression by cropping the high bits
|
||||||
|
* off with a part select. The result has the width w passed in. This
|
||||||
|
* function does not pad, use pad_to_width if padding is desired.
|
||||||
|
*/
|
||||||
|
extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function takes as input a NetNet signal and adds a constant
|
* This function takes as input a NetNet signal and adds a constant
|
||||||
* value to it. If the val is 0, then simply return sig. Otherwise,
|
* value to it. If the val is 0, then simply return sig. Otherwise,
|
||||||
|
|
@ -92,6 +99,9 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netmisc.h,v $
|
* $Log: netmisc.h,v $
|
||||||
|
* Revision 1.21 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.20 2005/01/24 05:28:31 steve
|
* Revision 1.20 2005/01/24 05:28:31 steve
|
||||||
* Remove the NetEBitSel and combine all bit/part select
|
* Remove the NetEBitSel and combine all bit/part select
|
||||||
* behavior into the NetESelect node and IVL_EX_SELECT
|
* behavior into the NetESelect node and IVL_EX_SELECT
|
||||||
|
|
|
||||||
|
|
@ -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: pad_to_width.cc,v 1.16 2005/01/12 03:17:37 steve Exp $"
|
#ident "$Id: pad_to_width.cc,v 1.17 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -110,8 +110,31 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid)
|
||||||
|
{
|
||||||
|
NetScope*scope = net->scope();
|
||||||
|
|
||||||
|
if (net->vector_width() <= wid)
|
||||||
|
return net;
|
||||||
|
|
||||||
|
NetPartSelect*ps = new NetPartSelect(net, 0, wid, NetPartSelect::VP);
|
||||||
|
des->add_node(ps);
|
||||||
|
ps->set_line(*net);
|
||||||
|
|
||||||
|
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||||
|
NetNet::WIRE, wid);
|
||||||
|
tmp->local_flag(true);
|
||||||
|
tmp->set_line(*tmp);
|
||||||
|
connect(ps->pin(0), tmp->pin(0));
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pad_to_width.cc,v $
|
* $Log: pad_to_width.cc,v $
|
||||||
|
* Revision 1.17 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.16 2005/01/12 03:17:37 steve
|
* Revision 1.16 2005/01/12 03:17:37 steve
|
||||||
* Properly pad vector widths in pgassign.
|
* Properly pad vector widths in pgassign.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
13
syn-rules.y
13
syn-rules.y
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2005 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -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: syn-rules.y,v 1.32 2005/04/06 05:29:08 steve Exp $"
|
#ident "$Id: syn-rules.y,v 1.33 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -118,11 +118,8 @@ static void hookup_DFF_CE(NetFF*ff, NetESignal*d, NetEvProbe*pclk,
|
||||||
// where lval is really a "reg [7:0]". In other words, part
|
// where lval is really a "reg [7:0]". In other words, part
|
||||||
// selects in the l-value are handled by loff and the lwidth().
|
// selects in the l-value are handled by loff and the lwidth().
|
||||||
|
|
||||||
int loff = a->get_loff();
|
connect(ff->pin_Data(), d->bit(0));
|
||||||
for (unsigned idx = 0 ; idx < ff->width() ; idx += 1) {
|
connect(ff->pin_Q(), a->sig()->pin(0));
|
||||||
connect(ff->pin_Data(idx), d->bit(idx+rval_pinoffset));
|
|
||||||
connect(ff->pin_Q(idx), a->sig()->pin(idx+loff));
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(ff->pin_Clock(), pclk->pin(0));
|
connect(ff->pin_Clock(), pclk->pin(0));
|
||||||
if (ce) connect(ff->pin_Enable(), ce->pin(0));
|
if (ce) connect(ff->pin_Enable(), ce->pin(0));
|
||||||
|
|
@ -207,7 +204,7 @@ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
|
||||||
if (a->sig()) {
|
if (a->sig()) {
|
||||||
// cerr << "new NetFF named " << a->name() << endl;
|
// cerr << "new NetFF named " << a->name() << endl;
|
||||||
NetFF*ff = new NetFF(top->scope(), a->name(),
|
NetFF*ff = new NetFF(top->scope(), a->name(),
|
||||||
a->lwidth());
|
a->sig()->vector_width());
|
||||||
hookup_DFF_CE(ff, d, pclk, ce, a, rval_pinoffset);
|
hookup_DFF_CE(ff, d, pclk, ce, a, rval_pinoffset);
|
||||||
des->add_node(ff);
|
des->add_node(ff);
|
||||||
} else if (a->mem()) {
|
} else if (a->mem()) {
|
||||||
|
|
|
||||||
307
synth2.cc
307
synth2.cc
|
|
@ -17,42 +17,28 @@
|
||||||
* 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.41 2005/02/12 06:25:40 steve Exp $"
|
#ident "$Id: synth2.cc,v 1.42 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
# include "functor.h"
|
# include "functor.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include "netmisc.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
static int debug_synth2=0;
|
|
||||||
|
|
||||||
#ifdef __FUNCTION__
|
|
||||||
|
|
||||||
#define DEBUG_SYNTH2_ENTRY(class) if (debug_synth2) { cerr << "Enter " << class << "::" \
|
|
||||||
<< __FUNCTION__ << endl; dump(cerr, 4); }
|
|
||||||
#define DEBUG_SYNTH2_EXIT(class,val) if (debug_synth2) { cerr << "Exit " << class << "::" \
|
|
||||||
<< __FUNCTION__ << ", result " << val << endl; }
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define DEBUG_SYNTH2_ENTRY(class)
|
|
||||||
#define DEBUG_SYNTH2_EXIT(class,val)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool NetProc::synth_async(Design*des, NetScope*scope,
|
bool NetProc::synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out)
|
const NetBus&nex_map, NetBus&nex_out)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events)
|
const svector<NetEvProbe*>&events)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetProc")
|
|
||||||
|
|
||||||
if (events.count() > 0) {
|
if (events.count() > 0) {
|
||||||
cerr << get_line() << ": error: Events are unaccounted"
|
cerr << get_line() << ": error: Events are unaccounted"
|
||||||
<< " for in process synthesis." << endl;
|
<< " for in process synthesis." << endl;
|
||||||
|
|
@ -63,11 +49,11 @@ bool NetProc::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
return synth_async(des, scope, nex_map, nex_out);
|
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 NetBus&nset, const Nexus*nex)
|
||||||
{
|
{
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
for (idx = 0 ; idx < nset->pin_count() ; idx += 1)
|
for (idx = 0 ; idx < nset.pin_count() ; idx += 1)
|
||||||
if (nset->pin(idx).nexus() == nex)
|
if (nset.pin(idx).nexus() == nex)
|
||||||
return idx;
|
return idx;
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
|
|
@ -84,36 +70,36 @@ static unsigned find_nexus_in_set(const NetNet*nset, const Nexus*nex)
|
||||||
* r-value.
|
* r-value.
|
||||||
*/
|
*/
|
||||||
bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out)
|
const NetBus&nex_map, NetBus&nex_out)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetAssignBase")
|
|
||||||
|
|
||||||
NetNet*rsig = rval_->synthesize(des);
|
NetNet*rsig = rval_->synthesize(des);
|
||||||
assert(rsig);
|
assert(rsig);
|
||||||
|
|
||||||
NetNet*lsig = lval_->sig();
|
NetNet*lsig = lval_->sig();
|
||||||
if (!lsig) {
|
if (!lsig) {
|
||||||
cerr << get_line() << ": error: NetAssignBase::synth_async on unsupported lval ";
|
cerr << get_line() << ": error: "
|
||||||
|
<< "NetAssignBase::synth_async on unsupported lval ";
|
||||||
dump_lval(cerr);
|
dump_lval(cerr);
|
||||||
cerr << endl;
|
cerr << endl;
|
||||||
DEBUG_SYNTH2_EXIT("NetAssignBase",false)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(lval_->more == 0);
|
assert(lval_->more == 0);
|
||||||
|
|
||||||
if (lval_->lwidth() != nex_map->pin_count()) {
|
#if 0
|
||||||
cerr << get_line() << ": error: NetAssignBase::synth_async pin count mismatch, "
|
/* The l-value and r-value map must have the same width. */
|
||||||
<< lval_->lwidth() << " != " << nex_map->pin_count() << endl;
|
if (lval_->lwidth() != nex_map->vector_width()) {
|
||||||
DEBUG_SYNTH2_EXIT("NetAssignBase",false)
|
cerr << get_line() << ": error: Assignment synthesis: "
|
||||||
|
<< "vector width mismatch, "
|
||||||
|
<< lval_->lwidth() << " bits != "
|
||||||
|
<< nex_map->vector_width() << " bits." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(nex_map->pin_count() <= rsig->pin_count());
|
#else
|
||||||
|
/* For now, assume there is exactly one output. */
|
||||||
|
assert(nex_out.pin_count() == 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < lval_->lwidth() ; idx += 1) {
|
connect(nex_out.pin(0), rsig->pin(0));
|
||||||
unsigned off = lval_->get_loff()+idx;
|
|
||||||
unsigned ptr = find_nexus_in_set(nex_map, lsig->pin(off).nexus());
|
|
||||||
connect(nex_out->pin(ptr), rsig->pin(idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This lval_ represents a reg that is a WIRE in the
|
/* This lval_ represents a reg that is a WIRE in the
|
||||||
synthesized results. This function signals the destructor
|
synthesized results. This function signals the destructor
|
||||||
|
|
@ -122,7 +108,6 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
||||||
synthesis can continue to work with it as a WIRE. */
|
synthesis can continue to work with it as a WIRE. */
|
||||||
lval_->turn_sig_to_wire_on_release();
|
lval_->turn_sig_to_wire_on_release();
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetAssignBase",true)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,14 +118,13 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
||||||
* substatements.
|
* substatements.
|
||||||
*/
|
*/
|
||||||
bool NetBlock::synth_async(Design*des, NetScope*scope,
|
bool NetBlock::synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out)
|
const NetBus&nex_map, NetBus&nex_out)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetBlock")
|
|
||||||
if (last_ == 0) {
|
if (last_ == 0) {
|
||||||
DEBUG_SYNTH2_EXIT("NetBlock",true)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
const perm_string tmp1 = perm_string::literal("tmp1");
|
const perm_string tmp1 = perm_string::literal("tmp1");
|
||||||
const perm_string tmp2 = perm_string::literal("tmp2");
|
const perm_string tmp2 = perm_string::literal("tmp2");
|
||||||
|
|
||||||
|
|
@ -182,12 +166,16 @@ bool NetBlock::synth_async(Design*des, NetScope*scope,
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetBlock",flag)
|
DEBUG_SYNTH2_EXIT("NetBlock",flag)
|
||||||
return flag;
|
return flag;
|
||||||
|
#else
|
||||||
|
cerr << get_line() << ": sorry: "
|
||||||
|
"forgot how to implement NetBlock::synth_async" << endl;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetCase::synth_async(Design*des, NetScope*scope,
|
bool NetCase::synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out)
|
const NetBus&nex_map, NetBus&nex_out)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetCase")
|
|
||||||
#if 0
|
#if 0
|
||||||
unsigned cur;
|
unsigned cur;
|
||||||
|
|
||||||
|
|
@ -321,9 +309,9 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetCondit::synth_async(Design*des, NetScope*scope,
|
bool NetCondit::synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out)
|
const NetBus&nex_map, NetBus&nex_out)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetCondit")
|
#if 0
|
||||||
NetNet*ssig = expr_->synthesize(des);
|
NetNet*ssig = expr_->synthesize(des);
|
||||||
assert(ssig);
|
assert(ssig);
|
||||||
|
|
||||||
|
|
@ -377,23 +365,40 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetCondit",true)
|
DEBUG_SYNTH2_EXIT("NetCondit",true)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
cerr << get_line() << ": sorry: "
|
||||||
|
<< "Forgot to implement NetCondit::synth_async" << endl;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEvWait::synth_async(Design*des, NetScope*scope,
|
bool NetEvWait::synth_async(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out)
|
const NetBus&nex_map, NetBus&nex_out)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetEvWait")
|
|
||||||
bool flag = statement_->synth_async(des, scope, nex_map, nex_out);
|
bool flag = statement_->synth_async(des, scope, nex_map, nex_out);
|
||||||
DEBUG_SYNTH2_EXIT("NetEvWait",flag)
|
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method is called when the process is shown to be
|
||||||
|
* asynchronous. Figure out the nexus set of outputs from this
|
||||||
|
* process, and pass that to the synth_async method for the statement
|
||||||
|
* of the process. The statement will connect its output to the
|
||||||
|
* nex_out set, using the nex_map as a guide. Starting from the top,
|
||||||
|
* the nex_map is the same as the nex_map.
|
||||||
|
*/
|
||||||
bool NetProcTop::synth_async(Design*des)
|
bool NetProcTop::synth_async(Design*des)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetProcTop")
|
|
||||||
NexusSet nex_set;
|
NexusSet nex_set;
|
||||||
statement_->nex_output(nex_set);
|
statement_->nex_output(nex_set);
|
||||||
|
|
||||||
|
if (debug_synth2) {
|
||||||
|
cerr << get_line() << ": debug: Process has "
|
||||||
|
<< nex_set.count() << " outputs." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
const perm_string tmp1 = perm_string::literal("tmp");
|
const perm_string tmp1 = perm_string::literal("tmp");
|
||||||
NetNet*nex_out = new NetNet(scope(), tmp1, NetNet::WIRE,
|
NetNet*nex_out = new NetNet(scope(), tmp1, NetNet::WIRE,
|
||||||
nex_set.count());
|
nex_set.count());
|
||||||
|
|
@ -403,8 +408,12 @@ bool NetProcTop::synth_async(Design*des)
|
||||||
bool flag = statement_->synth_async(des, scope(), nex_out, nex_out);
|
bool flag = statement_->synth_async(des, scope(), nex_out, nex_out);
|
||||||
|
|
||||||
delete nex_out;
|
delete nex_out;
|
||||||
DEBUG_SYNTH2_EXIT("NetProcTop",flag)
|
|
||||||
return flag;
|
return flag;
|
||||||
|
#else
|
||||||
|
cerr << get_line() << ": sorry: "
|
||||||
|
<< "forgot to implement NetProcTop::synth_async" << endl;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -422,15 +431,14 @@ bool NetProcTop::synth_async(Design*des)
|
||||||
* the statements may each infer different reset and enable signals.
|
* the statements may each infer different reset and enable signals.
|
||||||
*/
|
*/
|
||||||
bool NetBlock::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
bool NetBlock::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
const NetNet*nex_map, NetNet*nex_out,
|
const NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events_in)
|
const svector<NetEvProbe*>&events_in)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetBlock")
|
|
||||||
if (last_ == 0) {
|
if (last_ == 0) {
|
||||||
DEBUG_SYNTH2_EXIT("NetBlock",true)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
|
|
||||||
const perm_string tmp1 = perm_string::literal("tmp1");
|
const perm_string tmp1 = perm_string::literal("tmp1");
|
||||||
|
|
@ -572,8 +580,14 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
taken up by the smaller NetFF devices. */
|
taken up by the smaller NetFF devices. */
|
||||||
delete ff;
|
delete ff;
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetBlock",flag)
|
|
||||||
return flag;
|
return flag;
|
||||||
|
|
||||||
|
#else
|
||||||
|
cerr << get_line() << ": sorry: "
|
||||||
|
<< "Forgot to implement NetBlock::synth_sync"
|
||||||
|
<< endl;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -583,10 +597,10 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
* expression is connected to an event, or not.
|
* expression is connected to an event, or not.
|
||||||
*/
|
*/
|
||||||
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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events_in)
|
const svector<NetEvProbe*>&events_in)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetCondit")
|
#if 0
|
||||||
/* First try to turn the condition expression into an
|
/* First try to turn the condition expression into an
|
||||||
asynchronous set/reset. If the condition expression has
|
asynchronous set/reset. If the condition expression has
|
||||||
inputs that are included in the sensitivity list, then it
|
inputs that are included in the sensitivity list, then it
|
||||||
|
|
@ -788,15 +802,19 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
|
|
||||||
bool flag = if_->synth_sync(des, scope, ff, nex_map, nex_out, events_in);
|
bool flag = if_->synth_sync(des, scope, ff, nex_map, nex_out, events_in);
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetCondit",flag)
|
|
||||||
return flag;
|
return flag;
|
||||||
|
|
||||||
|
#else
|
||||||
|
cerr << get_line() << ": sorry: "
|
||||||
|
<< "Forgot to implement NetCondit::synth_sync" << endl;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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 NetBus&nex_map, NetBus&nex_out,
|
||||||
const svector<NetEvProbe*>&events_in)
|
const svector<NetEvProbe*>&events_in)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetEvWait")
|
|
||||||
if (events_in.count() > 0) {
|
if (events_in.count() > 0) {
|
||||||
cerr << get_line() << ": error: Events are unaccounted"
|
cerr << get_line() << ": error: Events are unaccounted"
|
||||||
<< " for in process synthesis." << endl;
|
<< " for in process synthesis." << endl;
|
||||||
|
|
@ -814,7 +832,7 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
svector<NetEvProbe*>events (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 is the clock. */
|
||||||
NexusSet*statement_input = statement_ -> nex_input();
|
NexusSet*statement_input = statement_ -> nex_input();
|
||||||
|
|
||||||
/* Search for a clock input. The clock input is the edge event
|
/* Search for a clock input. The clock input is the edge event
|
||||||
|
|
@ -848,62 +866,109 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
<< " are valid clock inputs." << endl;
|
<< " are valid clock inputs." << endl;
|
||||||
cerr << get_line() << ": : Perhaps the clock"
|
cerr << get_line() << ": : Perhaps the clock"
|
||||||
<< " is read by a statement or expression?" << endl;
|
<< " is read by a statement or expression?" << endl;
|
||||||
DEBUG_SYNTH2_EXIT("NetEvWait",false)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ff->pin_Clock(), pclk->pin(0));
|
connect(ff->pin_Clock(), pclk->pin(0));
|
||||||
if (pclk->edge() == NetEvProbe::NEGEDGE)
|
if (pclk->edge() == NetEvProbe::NEGEDGE) {
|
||||||
ff->attribute(perm_string::literal("Clock:LPM_Polarity"), verinum("INVERT"));
|
perm_string polarity = perm_string::literal("Clock:LPM_Polarity");
|
||||||
|
ff->attribute(polarity, verinum("INVERT"));
|
||||||
|
|
||||||
|
if (debug_synth2) {
|
||||||
|
cerr << get_line() << ": debug: "
|
||||||
|
<< "Detected a NEGEDGE clock for the synthesized ff."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Synthesize the input to the DFF. */
|
/* Synthesize the input to the DFF. */
|
||||||
bool flag = statement_->synth_sync(des, scope, ff,
|
bool flag = statement_->synth_sync(des, scope, ff,
|
||||||
nex_map, nex_out, events);
|
nex_map, nex_out, events);
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetEvWait",flag)
|
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method is called for a process that is determined to be
|
||||||
|
* synchronous. Create a NetFF device to hold the output from the
|
||||||
|
* statement, and synthesize that statement in place.
|
||||||
|
*/
|
||||||
bool NetProcTop::synth_sync(Design*des)
|
bool NetProcTop::synth_sync(Design*des)
|
||||||
{
|
{
|
||||||
DEBUG_SYNTH2_ENTRY("NetProcTop")
|
if (debug_synth2) {
|
||||||
|
cerr << get_line() << ": debug: "
|
||||||
|
<< "Process is apparently synchronous. Making NetFFs."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
NexusSet nex_set;
|
NexusSet nex_set;
|
||||||
statement_->nex_output(nex_set);
|
statement_->nex_output(nex_set);
|
||||||
|
|
||||||
|
/* Make a model FF that will connect to the first item in the
|
||||||
|
set, and will also take the initial connection of clocks
|
||||||
|
and resets. */
|
||||||
NetFF*ff = new NetFF(scope(), scope()->local_symbol(),
|
NetFF*ff = new NetFF(scope(), scope()->local_symbol(),
|
||||||
nex_set.count());
|
nex_set[0]->vector_width());
|
||||||
des->add_node(ff);
|
des->add_node(ff);
|
||||||
ff->attribute(perm_string::literal("LPM_FFType"), verinum("DFF"));
|
ff->attribute(perm_string::literal("LPM_FFType"), verinum("DFF"));
|
||||||
|
|
||||||
/* The D inputs to the DFF device will receive the output from
|
NetBus nex_d (scope(), nex_set.count());
|
||||||
the statements of the process. */
|
NetBus nex_q (scope(), nex_set.count());
|
||||||
NetNet*nex_d = new NetNet(scope(), scope()->local_symbol(),
|
|
||||||
NetNet::WIRE, nex_set.count());
|
/* The Q of the NetFF devices is connected to the output that
|
||||||
nex_d->local_flag(true);
|
we are. The nex_q is a bundle of the outputs. We will also
|
||||||
|
pass the nex_q as a map to the statement's synth_sync
|
||||||
|
method to map it to the correct nex_d pin. */
|
||||||
for (unsigned idx = 0 ; idx < nex_set.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < nex_set.count() ; idx += 1) {
|
||||||
connect(nex_d->pin(idx), ff->pin_Data(idx));
|
connect(nex_set[idx], nex_q.pin(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The Q outputs of the DFF will connect to the actual outputs
|
// Connect the input later.
|
||||||
of the process. Thus, the DFF will be between the outputs
|
|
||||||
of the process and the outputs of the substatement. */
|
|
||||||
const perm_string tmpq = perm_string::literal("tmpq");
|
|
||||||
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. */
|
/* Synthesize the input to the DFF. */
|
||||||
bool flag = statement_->synth_sync(des, scope(), ff,
|
bool flag = statement_->synth_sync(des, scope(), ff,
|
||||||
nex_q, nex_d,
|
nex_q, nex_d,
|
||||||
svector<NetEvProbe*>());
|
svector<NetEvProbe*>());
|
||||||
|
if (! flag) {
|
||||||
|
delete ff;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
delete nex_q;
|
|
||||||
|
|
||||||
DEBUG_SYNTH2_EXIT("NetProcTop",flag)
|
NetNet*tmp = nex_d.pin(0).nexus()->pick_any_net();
|
||||||
return flag;
|
assert(tmp);
|
||||||
|
|
||||||
|
tmp = crop_to_width(des, tmp, ff->width());
|
||||||
|
connect(tmp->pin(0), ff->pin_Data());
|
||||||
|
connect(nex_q.pin(0), ff->pin_Q());
|
||||||
|
|
||||||
|
for (unsigned idx = 1 ; idx < nex_set.count() ; idx += 1) {
|
||||||
|
NetFF*ff2 = new NetFF(scope(), scope()->local_symbol(),
|
||||||
|
nex_set[idx]->vector_width());
|
||||||
|
des->add_node(ff2);
|
||||||
|
|
||||||
|
tmp = nex_d.pin(idx).nexus()->pick_any_net();
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
tmp = crop_to_width(des, tmp, ff2->width());
|
||||||
|
|
||||||
|
connect(nex_q.pin(idx), ff2->pin_Q());
|
||||||
|
connect(tmp->pin(0), ff2->pin_Data());
|
||||||
|
|
||||||
|
connect(ff->pin_Clock(), ff2->pin_Clock());
|
||||||
|
if (ff->pin_Enable().is_linked())
|
||||||
|
connect(ff->pin_Enable(), ff2->pin_Enable());
|
||||||
|
if (ff->pin_Aset().is_linked())
|
||||||
|
connect(ff->pin_Aset(), ff2->pin_Aset());
|
||||||
|
if (ff->pin_Aclr().is_linked())
|
||||||
|
connect(ff->pin_Aclr(), ff2->pin_Aclr());
|
||||||
|
if (ff->pin_Sset().is_linked())
|
||||||
|
connect(ff->pin_Sset(), ff2->pin_Sset());
|
||||||
|
if (ff->pin_Sclr().is_linked())
|
||||||
|
connect(ff->pin_Sclr(), ff2->pin_Sclr());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class synth2_f : public functor_t {
|
class synth2_f : public functor_t {
|
||||||
|
|
@ -978,84 +1043,14 @@ void synth2_f::process(class Design*des, class NetProcTop*top)
|
||||||
|
|
||||||
void synth2(Design*des)
|
void synth2(Design*des)
|
||||||
{
|
{
|
||||||
debug_synth2 = atoi(des->get_flag("ivl-synth2-debug"));
|
|
||||||
synth2_f synth_obj;
|
synth2_f synth_obj;
|
||||||
des->functor(&synth_obj);
|
des->functor(&synth_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: synth2.cc,v $
|
* $Log: synth2.cc,v $
|
||||||
* Revision 1.41 2005/02/12 06:25:40 steve
|
* Revision 1.42 2005/04/24 23:44:02 steve
|
||||||
* Restructure NetMux devices to pass vectors.
|
* Update DFF support to new data flow.
|
||||||
* Generate NetMux devices from ternary expressions,
|
|
||||||
* Reduce NetMux devices to bufif when appropriate.
|
|
||||||
*
|
*
|
||||||
* Revision 1.40 2004/12/11 02:31:27 steve
|
|
||||||
* Rework of internals to carry vectors through nexus instead
|
|
||||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
|
||||||
* down this path.
|
|
||||||
*
|
|
||||||
* Revision 1.39 2004/10/04 01:10:55 steve
|
|
||||||
* Clean up spurious trailing white space.
|
|
||||||
*
|
|
||||||
* Revision 1.38 2004/08/28 15:08:32 steve
|
|
||||||
* Do not change reg to wire in NetAssign_ unless synthesizing.
|
|
||||||
*
|
|
||||||
* Revision 1.37 2004/03/15 18:40:12 steve
|
|
||||||
* Only include DEBUG_SYNTH2 if __FUNCTION__ defined.
|
|
||||||
*
|
|
||||||
* Revision 1.36 2004/02/20 18:53:35 steve
|
|
||||||
* Addtrbute keys are perm_strings.
|
|
||||||
*
|
|
||||||
* Revision 1.35 2004/02/18 17:11:58 steve
|
|
||||||
* Use perm_strings for named langiage items.
|
|
||||||
*
|
|
||||||
* Revision 1.34 2003/12/20 00:59:31 steve
|
|
||||||
* Synthesis debug messages.
|
|
||||||
*
|
|
||||||
* Revision 1.33 2003/12/17 16:52:39 steve
|
|
||||||
* Debug dumps for synth2.
|
|
||||||
*
|
|
||||||
* Revision 1.32 2003/10/27 02:18:04 steve
|
|
||||||
* Handle special case of FF with enable and constant data.
|
|
||||||
*
|
|
||||||
* Revision 1.31 2003/08/28 04:11:19 steve
|
|
||||||
* Spelling patch.
|
|
||||||
*
|
|
||||||
* Revision 1.30 2003/08/15 02:23:53 steve
|
|
||||||
* Add synthesis support for synchronous reset.
|
|
||||||
*
|
|
||||||
* Revision 1.29 2003/08/14 02:41:05 steve
|
|
||||||
* Fix dangling pointer in NexusSet handling blocks.
|
|
||||||
*
|
|
||||||
* Revision 1.28 2003/08/10 17:04:23 steve
|
|
||||||
* Detect asynchronous FF inputs that are expressions.
|
|
||||||
*
|
|
||||||
* Revision 1.27 2003/06/23 00:14:44 steve
|
|
||||||
* ivl_synthesis_cell cuts off synthesis within a module.
|
|
||||||
*
|
|
||||||
* Revision 1.26 2003/06/21 01:21:43 steve
|
|
||||||
* Harmless fixup of warnings.
|
|
||||||
*
|
|
||||||
* Revision 1.25 2003/04/03 04:30:00 steve
|
|
||||||
* Prevent overrun comparing verinums to zero.
|
|
||||||
*
|
|
||||||
* Revision 1.24 2003/03/25 04:04:29 steve
|
|
||||||
* Handle defaults in synthesized case statements.
|
|
||||||
*
|
|
||||||
* Revision 1.23 2003/03/06 00:28:42 steve
|
|
||||||
* All NetObj objects have lex_string base names.
|
|
||||||
*
|
|
||||||
* Revision 1.22 2003/02/26 01:29:24 steve
|
|
||||||
* LPM objects store only their base names.
|
|
||||||
*
|
|
||||||
* Revision 1.21 2003/01/27 05:09:17 steve
|
|
||||||
* Spelling fixes.
|
|
||||||
*
|
|
||||||
* Revision 1.20 2002/11/09 23:29:29 steve
|
|
||||||
* Handle nested-if chip enables.
|
|
||||||
*
|
|
||||||
* Revision 1.19 2002/11/09 20:22:57 steve
|
|
||||||
* Detect synthesis conflicts blocks statements share outputs.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
19
t-dll-api.cc
19
t-dll-api.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: t-dll-api.cc,v 1.124 2005/04/13 06:35:11 steve Exp $"
|
#ident "$Id: t-dll-api.cc,v 1.125 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -819,11 +819,8 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
||||||
return net->u_.ff.d.pin;
|
return net->u_.ff.d.pin;
|
||||||
|
|
||||||
case IVL_LPM_FF:
|
case IVL_LPM_FF:
|
||||||
assert(idx < net->u_.ff.width);
|
assert(idx == 0);
|
||||||
if (net->u_.ff.width == 1)
|
return net->u_.ff.d.pin;
|
||||||
return net->u_.ff.d.pin;
|
|
||||||
else
|
|
||||||
return net->u_.ff.d.pins[idx];
|
|
||||||
|
|
||||||
case IVL_LPM_CONCAT:
|
case IVL_LPM_CONCAT:
|
||||||
assert(idx < net->u_.concat.inputs);
|
assert(idx < net->u_.concat.inputs);
|
||||||
|
|
@ -969,11 +966,8 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
|
||||||
return net->u_.ff.q.pin;
|
return net->u_.ff.q.pin;
|
||||||
|
|
||||||
case IVL_LPM_FF:
|
case IVL_LPM_FF:
|
||||||
assert(idx < net->u_.ff.width);
|
assert(idx == 0);
|
||||||
if (net->u_.ff.width == 1)
|
return net->u_.ff.q.pin;
|
||||||
return net->u_.ff.q.pin;
|
|
||||||
else
|
|
||||||
return net->u_.ff.q.pins[idx];
|
|
||||||
|
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
assert(idx == 0);
|
assert(idx == 0);
|
||||||
|
|
@ -2038,6 +2032,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll-api.cc,v $
|
* $Log: t-dll-api.cc,v $
|
||||||
|
* Revision 1.125 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.124 2005/04/13 06:35:11 steve
|
* Revision 1.124 2005/04/13 06:35:11 steve
|
||||||
* Make logic aware of strength.
|
* Make logic aware of strength.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
42
t-dll.cc
42
t-dll.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: t-dll.cc,v 1.147 2005/04/06 05:29:08 steve Exp $"
|
#ident "$Id: t-dll.cc,v 1.148 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1500,36 +1500,17 @@ void dll_target::lpm_ff(const NetFF*net)
|
||||||
obj->u_.ff.sset_value = 0;
|
obj->u_.ff.sset_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->u_.ff.width == 1) {
|
nex = net->pin_Q().nexus();
|
||||||
nex = net->pin_Q(0).nexus();
|
assert(nex->t_cookie());
|
||||||
assert(nex->t_cookie());
|
obj->u_.ff.q.pin = (ivl_nexus_t) nex->t_cookie();
|
||||||
obj->u_.ff.q.pin = (ivl_nexus_t) nex->t_cookie();
|
nexus_lpm_add(obj->u_.ff.q.pin, obj, 0,
|
||||||
nexus_lpm_add(obj->u_.ff.q.pin, obj, 0,
|
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
|
||||||
|
|
||||||
nex = net->pin_Data(0).nexus();
|
nex = net->pin_Data().nexus();
|
||||||
assert(nex->t_cookie());
|
assert(nex->t_cookie());
|
||||||
obj->u_.ff.d.pin = (ivl_nexus_t) nex->t_cookie();
|
obj->u_.ff.d.pin = (ivl_nexus_t) nex->t_cookie();
|
||||||
nexus_lpm_add(obj->u_.ff.d.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
nexus_lpm_add(obj->u_.ff.d.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
|
||||||
} else {
|
|
||||||
obj->u_.ff.q.pins = new ivl_nexus_t [obj->u_.ff.width * 2];
|
|
||||||
obj->u_.ff.d.pins = obj->u_.ff.q.pins + obj->u_.ff.width;
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < obj->u_.ff.width ; idx += 1) {
|
|
||||||
nex = net->pin_Q(idx).nexus();
|
|
||||||
assert(nex->t_cookie());
|
|
||||||
obj->u_.ff.q.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
|
||||||
nexus_lpm_add(obj->u_.ff.q.pins[idx], obj, 0,
|
|
||||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
|
||||||
|
|
||||||
nex = net->pin_Data(idx).nexus();
|
|
||||||
assert(nex->t_cookie());
|
|
||||||
obj->u_.ff.d.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
|
||||||
nexus_lpm_add(obj->u_.ff.d.pins[idx], obj, 0,
|
|
||||||
IVL_DR_HiZ, IVL_DR_HiZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dll_target::lpm_ram_dq(const NetRamDq*net)
|
void dll_target::lpm_ram_dq(const NetRamDq*net)
|
||||||
|
|
@ -2090,6 +2071,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll.cc,v $
|
* $Log: t-dll.cc,v $
|
||||||
|
* Revision 1.148 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.147 2005/04/06 05:29:08 steve
|
* Revision 1.147 2005/04/06 05:29:08 steve
|
||||||
* Rework NetRamDq and IVL_LPM_RAM nodes.
|
* Rework NetRamDq and IVL_LPM_RAM nodes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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: stub.c,v 1.122 2005/04/13 06:35:11 steve Exp $"
|
#ident "$Id: stub.c,v 1.123 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -410,6 +410,50 @@ static void show_lpm_concat(ivl_lpm_t net)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_lpm_ff(ivl_lpm_t net)
|
||||||
|
{
|
||||||
|
ivl_nexus_t nex;
|
||||||
|
unsigned width = ivl_lpm_width(net);
|
||||||
|
|
||||||
|
fprintf(out, " LPM_FF %s: <width=%u>\n",
|
||||||
|
ivl_lpm_basename(net), width);
|
||||||
|
|
||||||
|
nex = ivl_lpm_clk(net);
|
||||||
|
fprintf(out, " clk: %s\n", ivl_nexus_name(nex));
|
||||||
|
if (width_of_nexus(nex) != 1) {
|
||||||
|
fprintf(out, " clk: ERROR: Nexus width is %u\n",
|
||||||
|
width_of_nexus(nex));
|
||||||
|
stub_errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ivl_lpm_enable(net)) {
|
||||||
|
nex = ivl_lpm_enable(net);
|
||||||
|
fprintf(out, " CE: %s\n", ivl_nexus_name(nex));
|
||||||
|
if (width_of_nexus(nex) != 1) {
|
||||||
|
fprintf(out, " CE: ERROR: Nexus width is %u\n",
|
||||||
|
width_of_nexus(nex));
|
||||||
|
stub_errors += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nex = ivl_lpm_data(net,0);
|
||||||
|
fprintf(out, " D: %s\n", ivl_nexus_name(nex));
|
||||||
|
if (width_of_nexus(nex) != width) {
|
||||||
|
fprintf(out, " D: ERROR: Nexus width is %u\n",
|
||||||
|
width_of_nexus(nex));
|
||||||
|
stub_errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nex = ivl_lpm_q(net,0);
|
||||||
|
fprintf(out, " Q: %s\n", ivl_nexus_name(nex));
|
||||||
|
if (width_of_nexus(nex) != width) {
|
||||||
|
fprintf(out, " Q: ERROR: Nexus width is %u\n",
|
||||||
|
width_of_nexus(nex));
|
||||||
|
stub_errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void show_lpm_mod(ivl_lpm_t net)
|
static void show_lpm_mod(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
unsigned width = ivl_lpm_width(net);
|
unsigned width = ivl_lpm_width(net);
|
||||||
|
|
@ -478,7 +522,7 @@ static void show_lpm_mux(ivl_lpm_t net)
|
||||||
ivl_nexus_name(nex),
|
ivl_nexus_name(nex),
|
||||||
ivl_lpm_selects(net));
|
ivl_lpm_selects(net));
|
||||||
if (ivl_lpm_selects(net) != width_of_nexus(nex)) {
|
if (ivl_lpm_selects(net) != width_of_nexus(nex)) {
|
||||||
fprintf(out, " S: ERROR: Nexus width is %uj\n",
|
fprintf(out, " S: ERROR: Nexus width is %u\n",
|
||||||
width_of_nexus(nex));
|
width_of_nexus(nex));
|
||||||
stub_errors += 1;
|
stub_errors += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -708,8 +752,6 @@ static void show_lpm_ufunc(ivl_lpm_t net)
|
||||||
|
|
||||||
static void show_lpm(ivl_lpm_t net)
|
static void show_lpm(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
unsigned idx;
|
|
||||||
unsigned width = ivl_lpm_width(net);
|
|
||||||
|
|
||||||
switch (ivl_lpm_type(net)) {
|
switch (ivl_lpm_type(net)) {
|
||||||
|
|
||||||
|
|
@ -726,6 +768,10 @@ static void show_lpm(ivl_lpm_t net)
|
||||||
show_lpm_cmp_eeq(net);
|
show_lpm_cmp_eeq(net);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_LPM_FF:
|
||||||
|
show_lpm_ff(net);
|
||||||
|
break;
|
||||||
|
|
||||||
case IVL_LPM_CMP_GE:
|
case IVL_LPM_CMP_GE:
|
||||||
show_lpm_cmp_ge(net);
|
show_lpm_cmp_ge(net);
|
||||||
break;
|
break;
|
||||||
|
|
@ -762,41 +808,6 @@ static void show_lpm(ivl_lpm_t net)
|
||||||
show_lpm_sub(net);
|
show_lpm_sub(net);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IVL_LPM_FF: {
|
|
||||||
|
|
||||||
fprintf(out, " LPM_FF %s: <width=%u>\n",
|
|
||||||
ivl_lpm_basename(net), width);
|
|
||||||
|
|
||||||
if (ivl_lpm_enable(net))
|
|
||||||
fprintf(out, " clk: %s CE: %s\n",
|
|
||||||
ivl_nexus_name(ivl_lpm_clk(net)),
|
|
||||||
ivl_nexus_name(ivl_lpm_enable(net)));
|
|
||||||
else
|
|
||||||
fprintf(out, " clk: %s\n",
|
|
||||||
ivl_nexus_name(ivl_lpm_clk(net)));
|
|
||||||
|
|
||||||
if (ivl_lpm_async_clr(net))
|
|
||||||
fprintf(out, " Aclr: %s\n",
|
|
||||||
ivl_nexus_name(ivl_lpm_async_clr(net)));
|
|
||||||
|
|
||||||
if (ivl_lpm_async_set(net)) {
|
|
||||||
fprintf(out, " Aset: %s\n",
|
|
||||||
ivl_nexus_name(ivl_lpm_async_set(net)));
|
|
||||||
if (ivl_lpm_aset_value(net))
|
|
||||||
show_expression(ivl_lpm_aset_value(net), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (idx = 0 ; idx < width ; idx += 1)
|
|
||||||
fprintf(out, " Data %u: %s\n", idx,
|
|
||||||
ivl_nexus_name(ivl_lpm_data(net, idx)));
|
|
||||||
|
|
||||||
for (idx = 0 ; idx < width ; idx += 1)
|
|
||||||
fprintf(out, " Q %u: %s\n", idx,
|
|
||||||
ivl_nexus_name(ivl_lpm_q(net, idx)));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IVL_LPM_MOD:
|
case IVL_LPM_MOD:
|
||||||
show_lpm_mod(net);
|
show_lpm_mod(net);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1342,6 +1353,9 @@ int target_design(ivl_design_t des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: stub.c,v $
|
* $Log: stub.c,v $
|
||||||
|
* Revision 1.123 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.122 2005/04/13 06:35:11 steve
|
* Revision 1.122 2005/04/13 06:35:11 steve
|
||||||
* Make logic aware of strength.
|
* Make logic aware of strength.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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: vvp_scope.c,v 1.125 2005/04/06 05:29:09 steve Exp $"
|
#ident "$Id: vvp_scope.c,v 1.126 2005/04/24 23:44:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# include "vvp_priv.h"
|
||||||
|
|
@ -431,7 +431,6 @@ static void draw_C8_to_string(char*result, size_t nresult,
|
||||||
static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||||
{
|
{
|
||||||
static char result[2048];
|
static char result[2048];
|
||||||
unsigned idx;
|
|
||||||
unsigned nptr_pin = ivl_nexus_ptr_pin(nptr);
|
unsigned nptr_pin = ivl_nexus_ptr_pin(nptr);
|
||||||
ivl_net_const_t cptr;
|
ivl_net_const_t cptr;
|
||||||
ivl_net_logic_t lptr;
|
ivl_net_logic_t lptr;
|
||||||
|
|
@ -551,15 +550,6 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||||
if (lpm) switch (ivl_lpm_type(lpm)) {
|
if (lpm) switch (ivl_lpm_type(lpm)) {
|
||||||
|
|
||||||
case IVL_LPM_FF:
|
case IVL_LPM_FF:
|
||||||
for (idx = 0 ; idx < ivl_lpm_width(lpm) ; idx += 1)
|
|
||||||
if (ivl_lpm_q(lpm, idx) == nex) {
|
|
||||||
sprintf(result, "L_%s.%s/%u",
|
|
||||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(lpm))),
|
|
||||||
vvp_mangle_id(ivl_lpm_basename(lpm)), idx);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IVL_LPM_RAM:
|
case IVL_LPM_RAM:
|
||||||
case IVL_LPM_ADD:
|
case IVL_LPM_ADD:
|
||||||
case IVL_LPM_CONCAT:
|
case IVL_LPM_CONCAT:
|
||||||
|
|
@ -1591,86 +1581,41 @@ static void draw_lpm_ff(ivl_lpm_t net)
|
||||||
ivl_expr_t aset_expr = 0;
|
ivl_expr_t aset_expr = 0;
|
||||||
const char*aset_bits = 0;
|
const char*aset_bits = 0;
|
||||||
|
|
||||||
unsigned width, idx;
|
ivl_nexus_t nex;
|
||||||
|
unsigned width;
|
||||||
|
|
||||||
width = ivl_lpm_width(net);
|
width = ivl_lpm_width(net);
|
||||||
|
|
||||||
/* Q C CE D RS --> Q+ */
|
|
||||||
fprintf(vvp_out, "L_%s.%s/def .udp/sequ \"DFF\", 5, 2,"
|
|
||||||
" \"?" "r" "1" "0" "00" "0\","
|
|
||||||
" \"?" "r" "1" "1" "00" "1\","
|
|
||||||
" \"?" "r" "1" "x" "00" "x\","
|
|
||||||
" \"0" "r" "x" "0" "00" "0\","
|
|
||||||
" \"1" "r" "x" "1" "00" "1\","
|
|
||||||
" \"?" "*" "0" "?" "00" "-\","
|
|
||||||
" \"?" "_" "?" "?" "00" "-\","
|
|
||||||
" \"?" "?" "?" "?" "01" "1\","
|
|
||||||
" \"?" "?" "?" "?" "1?" "0\","
|
|
||||||
" \"?" "?" "1" "?" "00" "-\","
|
|
||||||
" \"?" "?" "?" "?" "00" "-\""
|
|
||||||
";\n",
|
|
||||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
|
|
||||||
vvp_mangle_id(ivl_lpm_basename(net)));
|
|
||||||
|
|
||||||
aset_expr = ivl_lpm_aset_value(net);
|
aset_expr = ivl_lpm_aset_value(net);
|
||||||
if (aset_expr) {
|
if (aset_expr) {
|
||||||
assert(ivl_expr_width(aset_expr) == width);
|
assert(ivl_expr_width(aset_expr) == width);
|
||||||
aset_bits = ivl_expr_bits(aset_expr);
|
aset_bits = ivl_expr_bits(aset_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx = 0 ; idx < width ; idx += 1) {
|
|
||||||
ivl_nexus_t tmp;
|
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%s.%s/%u .udp ",
|
fprintf(vvp_out, "L_%p .dff ", net);
|
||||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
|
|
||||||
vvp_mangle_id(ivl_lpm_basename(net)), idx);
|
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%s.%s/def, ",
|
nex = ivl_lpm_data(net,0);
|
||||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
|
assert(nex);
|
||||||
vvp_mangle_id(ivl_lpm_basename(net)));
|
draw_input_from_net(nex);
|
||||||
|
|
||||||
tmp = ivl_lpm_clk(net);
|
nex = ivl_lpm_clk(net);
|
||||||
draw_input_from_net(tmp);
|
assert(nex);
|
||||||
|
fprintf(vvp_out, ", ");
|
||||||
|
draw_input_from_net(nex);
|
||||||
|
|
||||||
tmp = ivl_lpm_enable(net);
|
nex = ivl_lpm_enable(net);
|
||||||
|
if (nex) {
|
||||||
fprintf(vvp_out, ", ");
|
fprintf(vvp_out, ", ");
|
||||||
if (tmp)
|
draw_input_from_net(nex);
|
||||||
draw_input_from_net(tmp);
|
} else {
|
||||||
else
|
fprintf(vvp_out, ", C4<1>");
|
||||||
fprintf(vvp_out, "C<1>");
|
|
||||||
|
|
||||||
tmp = ivl_lpm_data(net, idx);
|
|
||||||
assert(tmp);
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
draw_input_from_net(tmp);
|
|
||||||
|
|
||||||
/* Connect reset input. This may be the Aclr input, or
|
|
||||||
an Aset to zero. */
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
tmp = ivl_lpm_async_clr(net);
|
|
||||||
if (tmp) {
|
|
||||||
draw_input_from_net(tmp);
|
|
||||||
} else {
|
|
||||||
tmp = ivl_lpm_async_set(net);
|
|
||||||
if (aset_bits && (aset_bits[idx] == '0'))
|
|
||||||
draw_input_from_net(tmp);
|
|
||||||
else
|
|
||||||
fprintf(vvp_out, "C<0>");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect set input */
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
tmp = ivl_lpm_async_set(net);
|
|
||||||
if (aset_bits && (aset_bits[idx] != '1'))
|
|
||||||
tmp = 0;
|
|
||||||
|
|
||||||
if (tmp)
|
|
||||||
draw_input_from_net(tmp);
|
|
||||||
else
|
|
||||||
fprintf(vvp_out, "C<0>");
|
|
||||||
|
|
||||||
fprintf(vvp_out, ";\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stub asynchronous input for now. */
|
||||||
|
fprintf(vvp_out, ", C4<z>");
|
||||||
|
|
||||||
|
fprintf(vvp_out, ";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_lpm_shiftl(ivl_lpm_t net)
|
static void draw_lpm_shiftl(ivl_lpm_t net)
|
||||||
|
|
@ -1987,6 +1932,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_scope.c,v $
|
* $Log: vvp_scope.c,v $
|
||||||
|
* Revision 1.126 2005/04/24 23:44:02 steve
|
||||||
|
* Update DFF support to new data flow.
|
||||||
|
*
|
||||||
* Revision 1.125 2005/04/06 05:29:09 steve
|
* Revision 1.125 2005/04/06 05:29:09 steve
|
||||||
* Rework NetRamDq and IVL_LPM_RAM nodes.
|
* Rework NetRamDq and IVL_LPM_RAM nodes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue