Propogate constant 0 in low bits of adders.

This commit is contained in:
steve 1999-12-30 04:19:12 +00:00
parent 4558a7d8d0
commit b6d1bb1fa7
5 changed files with 181 additions and 7 deletions

153
cprop.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: cprop.cc,v 1.4 1999/12/17 06:18:15 steve Exp $"
#ident "$Id: cprop.cc,v 1.5 1999/12/30 04:19:12 steve Exp $"
#endif
# include "netlist.h"
@ -72,9 +72,147 @@ static verinum::V driven_value(const NetObj::Link&lnk)
struct cprop_functor : public functor_t {
unsigned count;
virtual void lpm_add_sub(Design*des, NetAddSub*obj);
virtual void lpm_ff(Design*des, NetFF*obj);
virtual void lpm_logic(Design*des, NetLogic*obj);
};
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
if (obj->attribute("LPM_Direction") != "ADD")
return;
// If the low bit on the A side is 0, then eliminate it from
// the adder, and pass the B side directly to the
// result. Don't reduce the adder smaller then a 1-bit
// adder. These will be eliminated later.
while ((obj->width() > 1)
&& all_drivers_constant(obj->pin_DataA(0))
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// Now do the same thing on the B side.
while ((obj->width() > 1)
&& all_drivers_constant(obj->pin_DataB(0))
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataA(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// If the adder is only 1 bit wide, then replace it with the
// simple logic gate.
if (obj->width() == 1) {
NetLogic*tmp;
if (obj->pin_Cout().is_linked()) {
tmp = new NetLogic(des->local_symbol(obj->name()), 3,
NetLogic::AND);
connect(tmp->pin(0), obj->pin_Cout());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
des->add_node(tmp);
}
tmp = new NetLogic(obj->name(), 3, NetLogic::XOR);
connect(tmp->pin(0), obj->pin_Result(0));
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
count += 1;
return;
}
}
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
{
// Look for and count unlinked FF outputs. Note that if the
// Data and Q pins are connected together, they can be removed
// from the circuit.
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_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 (unlinked_count == obj->width()) {
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->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;
}
}
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
switch (obj->type()) {
@ -89,6 +227,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (driven_value(obj->pin(idx)) == verinum::V0) {
connect(obj->pin(0), obj->pin(idx));
delete obj;
count += 1;
return;
}
}
@ -106,6 +245,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (driven_value(obj->pin(idx)) != verinum::V1) {
connect(obj->pin(0), obj->pin(idx));
delete obj;
count += 1;
return;
}
}
@ -114,6 +254,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
// input as the output value and remove the gate.
connect(obj->pin(0), obj->pin(1));
delete obj;
count += 1;
return;
default:
@ -163,8 +304,13 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
void cprop(Design*des)
{
// Continually propogate constants until a scan finds nothing
// to do.
cprop_functor prop;
des->functor(&prop);
do {
prop.count = 0;
des->functor(&prop);
} while (prop.count > 0);
cprop_dc_functor dc;
des->functor(&dc);
@ -172,6 +318,9 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.5 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.4 1999/12/17 06:18:15 steve
* Rewrite the cprop functor to use the functor_t interface.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.cc,v 1.7 1999/12/17 06:18:16 steve Exp $"
#ident "$Id: functor.cc,v 1.8 1999/12/30 04:19:12 steve Exp $"
#endif
# include "functor.h"
@ -35,6 +35,10 @@ void functor_t::process(class Design*, class NetProcTop*)
{
}
void functor_t::lpm_add_sub(class Design*, class NetAddSub*)
{
}
void functor_t::lpm_const(class Design*, class NetConst*)
{
}
@ -83,6 +87,11 @@ void NetNode::functor_node(Design*, functor_t*)
{
}
void NetAddSub::functor_node(Design*des, functor_t*fun)
{
fun->lpm_add_sub(des, this);
}
void NetConst::functor_node(Design*des, functor_t*fun)
{
fun->lpm_const(des, this);
@ -149,6 +158,9 @@ int NetPEvent::match_proc(proc_match_t*that)
/*
* $Log: functor.cc,v $
* Revision 1.8 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.7 1999/12/17 06:18:16 steve
* Rewrite the cprop functor to use the functor_t interface.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.h,v 1.5 1999/12/17 06:18:16 steve Exp $"
#ident "$Id: functor.h,v 1.6 1999/12/30 04:19:12 steve Exp $"
#endif
/*
@ -42,6 +42,9 @@ struct functor_t {
/* This method is called for each process in the design. */
virtual void process(class Design*des, class NetProcTop*);
/* 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 constant. */
virtual void lpm_const(class Design*des, class NetConst*);
@ -64,6 +67,9 @@ struct proc_match_t {
/*
* $Log: functor.h,v $
* Revision 1.6 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.5 1999/12/17 06:18:16 steve
* Rewrite the cprop functor to use the functor_t interface.
*

View File

@ -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.101 1999/12/17 03:38:46 steve Exp $"
#ident "$Id: netlist.cc,v 1.102 1999/12/30 04:19:12 steve Exp $"
#endif
# include <cassert>
@ -145,7 +145,7 @@ bool NetObj::Link::is_linked(const NetObj&that) const
bool NetObj::Link::is_linked(const NetObj::Link&that) const
{
for (const Link*idx = next_ ; this != idx ; idx = idx->next_)
if (idx == &that)
if (idx->is_equal(that))
return true;
return false;
@ -2764,6 +2764,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.102 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.101 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*

View File

@ -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.104 1999/12/17 06:18:16 steve Exp $"
#ident "$Id: netlist.h,v 1.105 1999/12/30 04:19:12 steve Exp $"
#endif
/*
@ -328,6 +328,7 @@ class NetAddSub : public NetNode {
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
virtual void functor_node(Design*des, functor_t*fun);
};
/*
@ -2080,6 +2081,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.105 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.104 1999/12/17 06:18:16 steve
* Rewrite the cprop functor to use the functor_t interface.
*