Catch some simple identity compareoptimizations.

This commit is contained in:
steve 2000-04-20 00:28:03 +00:00
parent 74c43032b3
commit 2094a2f466
8 changed files with 195 additions and 8 deletions

View File

@ -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 File

@ -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 File

@ -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 File

@ -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.
*

56
link_const.cc Normal file
View File

@ -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 File

@ -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 File

@ -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 File

@ -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.
*