Permalink
Browse files

Catch some simple identity compareoptimizations.

  • Loading branch information...
1 parent 74c4303 commit 2094a2f46600747ec1b95638b44d217243dde488 steve committed Apr 20, 2000
Showing with 195 additions and 8 deletions.
  1. +3 −2 Makefile.in
  2. +30 −1 expr_synth.cc
  3. +13 −1 functor.cc
  4. +7 −1 functor.h
  5. +56 −0 link_const.cc
  6. +5 −1 netlist.h
  7. +11 −1 netmisc.h
  8. +70 −1 xnfio.cc
View
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
-#ident "$Id: Makefile.in,v 1.44 2000/04/12 20:02:52 steve Exp $"
+#ident "$Id: Makefile.in,v 1.45 2000/04/20 00:28:03 steve Exp $"
#
#
SHELL = /bin/sh
@@ -71,7 +71,8 @@ FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_net.o elab_pexpr.o elab_scope.o emit.o eval.o eval_tree.o \
-expr_synth.o functor.o lexor.o lexor_keyword.o mangle.o netlist.o \
+expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
+mangle.o netlist.o \
net_design.o net_event.o net_scope.o net_udp.o nexus_from_link.o \
pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
View
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: expr_synth.cc,v 1.11 2000/04/16 23:32:18 steve Exp $"
+#ident "$Id: expr_synth.cc,v 1.12 2000/04/20 00:28:03 steve Exp $"
#endif
# include "netlist.h"
@@ -133,6 +133,32 @@ NetNet* NetEBComp::synthesize(Design*des)
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, 1);
osig->local_flag(true);
+ /* Handle the special case of a single bit equality
+ operation. Make an XNOR gate instead of a comparator. */
+ if ((width == 1) && ((op_ == 'e') || (op_ == 'E'))) {
+ NetLogic*gate = new NetLogic(des->local_symbol(path),
+ 3, NetLogic::XNOR);
+ connect(gate->pin(0), osig->pin(0));
+ connect(gate->pin(1), lsig->pin(0));
+ connect(gate->pin(2), rsig->pin(0));
+ des->add_node(gate);
+ return osig;
+ }
+
+ /* Handle the special case of a single bit inequality
+ operation. This is similar to single bit equality, but uses
+ an XOR instead of an XNOR gate. */
+ if ((width == 1) && ((op_ == 'n') || (op_ == 'N'))) {
+ NetLogic*gate = new NetLogic(des->local_symbol(path),
+ 3, NetLogic::XOR);
+ connect(gate->pin(0), osig->pin(0));
+ connect(gate->pin(1), lsig->pin(0));
+ connect(gate->pin(2), rsig->pin(0));
+ des->add_node(gate);
+ return osig;
+ }
+
+
NetCompare*dev = new NetCompare(des->local_symbol(path), width);
des->add_node(dev);
@@ -283,6 +309,9 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
+ * Revision 1.12 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
* Revision 1.11 2000/04/16 23:32:18 steve
* Synthesis of comparator in expressions.
*
View
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: functor.cc,v 1.16 2000/04/18 04:50:19 steve Exp $"
+#ident "$Id: functor.cc,v 1.17 2000/04/20 00:28:03 steve Exp $"
#endif
# include "functor.h"
@@ -43,6 +43,10 @@ void functor_t::lpm_add_sub(class Design*, class NetAddSub*)
{
}
+void functor_t::lpm_compare(class Design*, class NetCompare*)
+{
+}
+
void functor_t::lpm_const(class Design*, class NetConst*)
{
}
@@ -120,6 +124,11 @@ void NetAddSub::functor_node(Design*des, functor_t*fun)
fun->lpm_add_sub(des, this);
}
+void NetCompare::functor_node(Design*des, functor_t*fun)
+{
+ fun->lpm_compare(des, this);
+}
+
void NetConst::functor_node(Design*des, functor_t*fun)
{
fun->lpm_const(des, this);
@@ -208,6 +217,9 @@ int proc_match_t::event_wait(NetEvWait*)
/*
* $Log: functor.cc,v $
+ * Revision 1.17 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
* Revision 1.16 2000/04/18 04:50:19 steve
* Clean up unneeded NetEvent objects.
*
View
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: functor.h,v 1.12 2000/04/18 04:50:19 steve Exp $"
+#ident "$Id: functor.h,v 1.13 2000/04/20 00:28:03 steve Exp $"
#endif
/*
@@ -47,6 +47,9 @@ struct functor_t {
/* This method is called for each structural adder. */
virtual void lpm_add_sub(class Design*des, class NetAddSub*);
+ /* This method is called for each structural comparator. */
+ virtual void lpm_compare(class Design*des, class NetCompare*);
+
/* This method is called for each structural constant. */
virtual void lpm_const(class Design*des, class NetConst*);
@@ -76,6 +79,9 @@ struct proc_match_t {
/*
* $Log: functor.h,v $
+ * Revision 1.13 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
* Revision 1.12 2000/04/18 04:50:19 steve
* Clean up unneeded NetEvent objects.
*
View
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2000 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
+ */
+#if !defined(WINNT) && !defined(macintosh)
+#ident "$Id: link_const.cc,v 1.1 2000/04/20 00:28:03 steve Exp $"
+#endif
+
+# include "netlist.h"
+# include "netmisc.h"
+
+NetConst* link_const_value(NetObj::Link&pin, unsigned&idx)
+{
+ NetConst*robj = 0;
+ unsigned ridx = 0;
+
+ for (NetObj::Link*cur = pin.next_link()
+ ; *cur != pin ; cur = cur->next_link()) {
+
+ NetConst*tmp;
+ if ((tmp = dynamic_cast<NetConst*>(cur->get_obj())) == 0)
+ continue;
+
+ if (robj != 0)
+ continue;
+
+ robj = tmp;
+ ridx = cur->get_pin();
+ }
+
+ idx = ridx;
+ return robj;
+}
+
+
+/*
+ * $Log: link_const.cc,v $
+ * Revision 1.1 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
+ */
+
View
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: netlist.h,v 1.125 2000/04/18 04:50:20 steve Exp $"
+#ident "$Id: netlist.h,v 1.126 2000/04/20 00:28:03 steve Exp $"
#endif
/*
@@ -403,6 +403,7 @@ class NetCompare : public NetNode {
const NetObj::Link& pin_DataA(unsigned idx) const;
const NetObj::Link& pin_DataB(unsigned idx) const;
+ virtual void functor_node(Design*, functor_t*);
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
@@ -2390,6 +2391,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
+ * Revision 1.126 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
* Revision 1.125 2000/04/18 04:50:20 steve
* Clean up unneeded NetEvent objects.
*
View
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: netmisc.h,v 1.4 2000/03/16 19:03:03 steve Exp $"
+#ident "$Id: netmisc.h,v 1.5 2000/04/20 00:28:03 steve Exp $"
#endif
# include "netlist.h"
@@ -41,9 +41,19 @@ extern NetNet*pad_to_width(Design*des, const string&p, NetNet*n, unsigned w);
*/
extern string nexus_from_link(const NetObj::Link*lnk);
+/*
+ * Check to see if the link has a constant value driven to it. If
+ * there is only a NetConst driving this pin, the return a pointer to
+ * that NetConst object. Also, return the index of the bit in that
+ * constant through the idx parameter.
+ */
+extern NetConst* link_const_value(NetObj::Link&pin, unsigned&idx);
/*
* $Log: netmisc.h,v $
+ * Revision 1.5 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
* Revision 1.4 2000/03/16 19:03:03 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
View
@@ -17,18 +17,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: xnfio.cc,v 1.11 2000/02/23 02:56:56 steve Exp $"
+#ident "$Id: xnfio.cc,v 1.12 2000/04/20 00:28:03 steve Exp $"
#endif
# include "functor.h"
# include "netlist.h"
+# include "netmisc.h"
+# include <strstream>
class xnfio_f : public functor_t {
public:
void signal(Design*des, NetNet*sig);
+ void lpm_compare(Design*des, NetCompare*dev);
private:
+ bool compare_sideb_const(Design*des, NetCompare*dev);
};
static bool is_a_pad(const NetNet*net)
@@ -277,6 +281,68 @@ void xnfio_f::signal(Design*des, NetNet*net)
}
}
+/*
+ * Attempt some XNF specific optimizations on comparators.
+ */
+void xnfio_f::lpm_compare(Design*des, NetCompare*dev)
+{
+ if (compare_sideb_const(des, dev))
+ return;
+
+ return;
+}
+
+bool xnfio_f::compare_sideb_const(Design*des, NetCompare*dev)
+{
+ /* Even if side B is all constant, if there are more then 4
+ signals on side A we will not be able to fit the operation
+ into a function unit, so we might as well accept a
+ comparator. Give up. */
+ if (dev->width() > 4)
+ return false;
+
+ verinum side (verinum::V0, dev->width());
+
+ /* Is the B side all constant? */
+ for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) {
+ NetConst*cobj;
+ unsigned cidx;
+ cobj = link_const_value(dev->pin_DataB(idx), cidx);
+ if (cobj == 0)
+ return false;
+
+ side.set(idx, cobj->value(cidx));
+ }
+
+ /* Handle the special case of comparing A to 0. Use an N-input
+ NOR gate to return 0 if any of the bits is not 0. */
+ if ((side.as_ulong() == 0) && (count_inputs(dev->pin_AEB()) > 0)) {
+ NetLogic*sub = new NetLogic(dev->name(), dev->width()+1,
+ NetLogic::NOR);
+ connect(sub->pin(0), dev->pin_AEB());
+ for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
+ connect(sub->pin(idx+1), dev->pin_DataA(idx));
+ delete dev;
+ des->add_node(sub);
+ return true;
+ }
+
+ /* Handle the special case of comparing A to 0. Use an N-input
+ NOR gate to return 0 if any of the bits is not 0. */
+ if ((side.as_ulong() == 0) && (count_inputs(dev->pin_ANEB()) > 0)) {
+ NetLogic*sub = new NetLogic(dev->name(), dev->width()+1,
+ NetLogic::OR);
+ connect(sub->pin(0), dev->pin_ANEB());
+ for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
+ connect(sub->pin(idx+1), dev->pin_DataA(idx));
+ delete dev;
+ des->add_node(sub);
+ return true;
+ }
+
+ return false;
+}
+
void xnfio(Design*des)
{
xnfio_f xnfio_obj;
@@ -285,6 +351,9 @@ void xnfio(Design*des)
/*
* $Log: xnfio.cc,v $
+ * Revision 1.12 2000/04/20 00:28:03 steve
+ * Catch some simple identity compareoptimizations.
+ *
* Revision 1.11 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*

0 comments on commit 2094a2f

Please sign in to comment.