diff --git a/netlist.cc b/netlist.cc index ce3dae1e8..f870c7655 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.cc,v 1.87 1999/11/18 03:52:19 steve Exp $" +#ident "$Id: netlist.cc,v 1.88 1999/11/19 03:02:25 steve Exp $" #endif # include @@ -77,6 +77,7 @@ ostream& operator<< (ostream&o, NetNet::Type t) void connect(NetObj::Link&l, NetObj::Link&r) { + assert(&l != &r); NetObj::Link* cur = &l; do { NetObj::Link*tmp = cur->next_; @@ -242,6 +243,16 @@ const NetNet* find_link_signal(const NetObj*net, unsigned pin, unsigned&bidx) return 0; } +NetObj::Link* find_next_output(NetObj::Link*lnk) +{ + for (NetObj::Link*cur = lnk->next_link() + ; cur != lnk ; cur = cur->next_link()) + if (cur->get_dir() == NetObj::Link::OUTPUT) + return cur; + + return 0; +} + NetObj::NetObj(const string&n, unsigned np) : name_(n), npins_(np), delay1_(0), delay2_(0), delay3_(0), mark_(false) { @@ -2348,6 +2359,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.88 1999/11/19 03:02:25 steve + * Detect flip-flops connected to opads and turn + * them into OUTFF devices. Inprove support for + * the XNF-LCA attribute in the process. + * * Revision 1.87 1999/11/18 03:52:19 steve * Turn NetTmp objects into normal local NetNet objects, * and add the nodangle functor to clean up the local diff --git a/netlist.h b/netlist.h index c0bc66785..ce973d7f3 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.89 1999/11/18 03:52:19 steve Exp $" +#ident "$Id: netlist.h,v 1.90 1999/11/19 03:02:25 steve Exp $" #endif /* @@ -1924,6 +1924,9 @@ extern unsigned count_inputs(const NetObj::Link&pin); extern unsigned count_outputs(const NetObj::Link&pin); extern unsigned count_signals(const NetObj::Link&pin); +/* Find the next link that is an output into the nexus. */ +extern NetObj::Link* find_next_output(NetObj::Link*lnk); + /* Find the signal connected to the given node pin. There should always be exactly one signal. The bidx parameter get filled with the signal index of the Net, in case it is a vector. */ @@ -1937,6 +1940,11 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.90 1999/11/19 03:02:25 steve + * Detect flip-flops connected to opads and turn + * them into OUTFF devices. Inprove support for + * the XNF-LCA attribute in the process. + * * Revision 1.89 1999/11/18 03:52:19 steve * Turn NetTmp objects into normal local NetNet objects, * and add the nodangle functor to clean up the local diff --git a/t-xnf.cc b/t-xnf.cc index c23181748..32c85b3f2 100644 --- a/t-xnf.cc +++ b/t-xnf.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-xnf.cc,v 1.17 1999/11/17 18:52:09 steve Exp $" +#ident "$Id: t-xnf.cc,v 1.18 1999/11/19 03:02:25 steve Exp $" #endif /* XNF BACKEND @@ -149,6 +149,12 @@ string target_xnf::choose_sig_name(const NetObj::Link*lnk) if ((cursig->pin_count() == 1) && (sig->pin_count() > 1)) continue; + if ((cursig->pin_count() > 1) && (sig->pin_count() == 1)) { + sig = cursig; + pin = cur->get_pin(); + continue; + } + if (cursig->local_flag() && !sig->local_flag()) continue; @@ -219,8 +225,11 @@ void target_xnf::draw_sym_with_lcaname(ostream&os, string lca, os << "SYM, " << mangle(net->name()) << ", " << lcaname << ", LIBVER=2.0.0" << endl; - for (idx = 0 ; idx < net->pin_count() ; idx += 1) - draw_pin(os, scrape_pin_name(lca), net->pin(idx)); + for (idx = 0 ; idx < net->pin_count() ; idx += 1) { + string usename = scrape_pin_name(lca); + if (usename == "") continue; + draw_pin(os, usename, net->pin(idx)); + } os << "END" << endl; } @@ -481,7 +490,13 @@ void target_xnf::lpm_ff(ostream&os, const NetFF*net) // XXXX For now, only support DFF assert(type == "DFF"); - // XXXX For now, I do not now how to deal with XNF-LCA attributes. + + string lcaname = net->attribute("XNF-LCA"); + if (lcaname != "") { + draw_sym_with_lcaname(os, lcaname, net); + return; + } + assert(net->attribute("XNF-LCA") == ""); for (unsigned idx = 0 ; idx < net->width() ; idx += 1) { @@ -638,6 +653,11 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj }; /* * $Log: t-xnf.cc,v $ + * Revision 1.18 1999/11/19 03:02:25 steve + * Detect flip-flops connected to opads and turn + * them into OUTFF devices. Inprove support for + * the XNF-LCA attribute in the process. + * * Revision 1.17 1999/11/17 18:52:09 steve * Add algorithm for choosing nexus name from attached signals. * diff --git a/xnfio.cc b/xnfio.cc index e3296078c..c0aa1db7b 100644 --- a/xnfio.cc +++ b/xnfio.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: xnfio.cc,v 1.6 1999/11/18 02:58:37 steve Exp $" +#ident "$Id: xnfio.cc,v 1.7 1999/11/19 03:02:25 steve Exp $" #endif # include "functor.h" @@ -49,7 +49,7 @@ static bool is_a_pad(const NetNet*net) * really lame to not do the obvious optimization. */ -static void make_obuf(Design*des, NetNet*net) +static NetLogic* make_obuf(Design*des, NetNet*net) { assert(net->pin_count() == 1); @@ -59,7 +59,7 @@ static void make_obuf(Design*des, NetNet*net) if (count_outputs(net->pin(0)) <= 0) { cerr << net->get_line() << ":warning: No outputs to OPAD: " << net->name() << endl; - return; + return 0; } assert(count_outputs(net->pin(0)) > 0); @@ -79,7 +79,7 @@ static void make_obuf(Design*des, NetNet*net) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { tmp->attribute("XNF-LCA", "OBUF:O,I"); - return; + return tmp; } // Try to use an existing INV as an OBUF. Certain @@ -92,7 +92,7 @@ static void make_obuf(Design*des, NetNet*net) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { tmp->attribute("XNF-LCA", "OBUF:O,~I"); - return; + return tmp; } // Try to use an existing bufif1 as an OBUFT. Of course @@ -104,7 +104,7 @@ static void make_obuf(Design*des, NetNet*net) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { tmp->attribute("XNF-LCA", "OBUFT:O,I,~T"); - return; + return tmp; } if ((tmp->type() == NetLogic::BUFIF0) @@ -112,7 +112,7 @@ static void make_obuf(Design*des, NetNet*net) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { tmp->attribute("XNF-LCA", "OBUFT:O,I,T"); - return; + return tmp; } } @@ -136,9 +136,53 @@ static void make_obuf(Design*des, NetNet*net) // this case and create a new signal. if (count_signals(buf->pin(1)) == 0) { NetNet*tmp = new NetNet(des->local_symbol("$"), NetNet::WIRE); + tmp->local_flag(true); connect(buf->pin(1), tmp->pin(0)); des->add_signal(tmp); } + + return buf; +} + +static void absorb_OFF(Design*des, NetLogic*buf) +{ + /* If the nexus connects is not a simple point-to-point link, + then I can't drag it into the IOB. Give up. */ + if (count_outputs(buf->pin(1)) != 1) + return; + if (count_inputs(buf->pin(1)) != 1) + return; + + NetObj::Link*drv = find_next_output(&buf->pin(1)); + assert(drv); + + NetFF*ff = dynamic_cast(drv->get_obj()); + if (ff == 0) + return; + if (ff->width() != 1) + return; + if (ff->attribute("LPM_FFType") != "DFF") + return; + + /* Connect the flip-flop output to the buffer output and + delete the buffer. The XNF OUTFF can buffer the pin. */ + connect(ff->pin_Q(0), buf->pin(0)); + delete buf; + + /* Finally, build up an XNF-LCA value that defines this + devices as an OUTFF and gives each pin an XNF name. */ + char**names = new char*[ff->pin_count()]; + for (unsigned idx = 0 ; idx < ff->pin_count() ; idx += 1) + names[idx] = ""; + + names[ff->pin_Clock().get_pin()] = "C"; + names[ff->pin_Data(0).get_pin()] = "D"; + names[ff->pin_Q(0).get_pin()] = "Q"; + string lname = string("OUTFF:") + names[0]; + for (unsigned idx = 1 ; idx < ff->pin_count() ; idx += 1) + lname = lname + "," + names[idx]; + delete[]names; + ff->attribute("XNF-LCA", lname); } static void make_ibuf(Design*des, NetNet*net) @@ -192,6 +236,7 @@ static void make_ibuf(Design*des, NetNet*net) void xnfio_f::signal(Design*des, NetNet*net) { + NetNode*buf; if (! is_a_pad(net)) return; @@ -204,9 +249,13 @@ void xnfio_f::signal(Design*des, NetNet*net) make_ibuf(des, net); break; case 'o': - case 'O': - make_obuf(des, net); - break; + case 'O': { + NetLogic*buf = make_obuf(des, net); + if (buf == 0) break; + absorb_OFF(des, buf); + break; + } + // FIXME: Only IPAD and OPAD supported. Need to // add support for IOPAD. default: @@ -223,6 +272,11 @@ void xnfio(Design*des) /* * $Log: xnfio.cc,v $ + * Revision 1.7 1999/11/19 03:02:25 steve + * Detect flip-flops connected to opads and turn + * them into OUTFF devices. Inprove support for + * the XNF-LCA attribute in the process. + * * Revision 1.6 1999/11/18 02:58:37 steve * Handle (with a warning) unconnected opads. *