Implement LPM_COMPARE nodes as two-input vector functors.

This commit is contained in:
steve 2005-01-16 04:20:32 +00:00
parent 1c3668ea7f
commit bf6a5d0f50
8 changed files with 145 additions and 161 deletions

View File

@ -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.48 2004/12/11 02:31:25 steve Exp $" #ident "$Id: cprop.cc,v 1.49 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -73,6 +73,8 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj) void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{ {
#if 0
/* XXXX Need to reimplement this code to account for vectors. */
NetScope*scope = obj->scope(); NetScope*scope = obj->scope();
unsigned const_count = 0; unsigned const_count = 0;
@ -191,6 +193,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
delete obj; delete obj;
des->add_node(tmp); des->add_node(tmp);
count += 1; count += 1;
#endif
} }
void cprop_functor::lpm_ff(Design*des, NetFF*obj) void cprop_functor::lpm_ff(Design*des, NetFF*obj)
@ -958,6 +961,9 @@ void cprop(Design*des)
/* /*
* $Log: cprop.cc,v $ * $Log: cprop.cc,v $
* Revision 1.49 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.48 2004/12/11 02:31:25 steve * Revision 1.48 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead * Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes * of single bits. Make the ivl, tgt-vvp and vvp initial changes

View File

@ -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: elab_net.cc,v 1.141 2005/01/13 00:23:10 steve Exp $" #ident "$Id: elab_net.cc,v 1.142 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -581,41 +581,23 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
delete rexp; delete rexp;
} }
unsigned dwidth = lsig->pin_count(); unsigned dwidth = lsig->vector_width();
if (rsig->pin_count() > dwidth) dwidth = rsig->pin_count(); if (rsig->vector_width() > dwidth) dwidth = rsig->vector_width();
/* Operands of binary compare need to be padded to equal /* Operands of binary compare need to be padded to equal
size. Figure the pad bit needed to extend the narrowest size. Figure the pad bit needed to extend the narrowest
vector. */ vector. */
NetNet*padbit = 0; if (lsig->vector_width() < dwidth)
if (lsig->pin_count() != rsig->pin_count()) { lsig = pad_to_width(des, lsig, dwidth);
unsigned lwid = lsig->pin_count(); if (rsig->vector_width() < dwidth)
unsigned rwid = rsig->pin_count(); rsig = pad_to_width(des, rsig, dwidth);
padbit = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
padbit->local_flag(true);
if (lsig->get_signed() && (lwid < rwid)) {
connect(padbit->pin(0), lsig->pin(lwid-1));
} else if (rsig->get_signed() && (rwid < lwid)) {
connect(padbit->pin(0), rsig->pin(rwid-1));
} else {
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
verinum::V0);
des->add_node(tmp);
connect(tmp->pin(0), padbit->pin(0));
}
}
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
osig->set_line(*this);
osig->local_flag(true); osig->local_flag(true);
NetNode*gate; NetNode*gate;
//NetNode*gate_t;
switch (op_) { switch (op_) {
case '<': case '<':
@ -624,14 +606,8 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
case 'G': { case 'G': {
NetCompare*cmp = new NetCompare*cmp = new
NetCompare(scope, scope->local_symbol(), dwidth); NetCompare(scope, scope->local_symbol(), dwidth);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) connect(cmp->pin_DataA(), lsig->pin(0));
connect(cmp->pin_DataA(idx), lsig->pin(idx)); connect(cmp->pin_DataB(), rsig->pin(0));
for (unsigned idx = lsig->pin_count(); idx < dwidth ; idx += 1)
connect(cmp->pin_DataA(idx), padbit->pin(0));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(cmp->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = rsig->pin_count(); idx < dwidth ; idx += 1)
connect(cmp->pin_DataB(idx), padbit->pin(0));
switch (op_) { switch (op_) {
case '<': case '<':
@ -660,7 +636,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
case 'N': // Case equals (!==) case 'N': // Case equals (!==)
// The comparison generates gates to bitwise compare // The comparison generates gates to bitwise compare
// each pair, and AND all the comparison results. // each pair, and AND all the comparison results.
#if 0
gate = new NetLogic(scope, scope->local_symbol(), gate = new NetLogic(scope, scope->local_symbol(),
1+dwidth, 1+dwidth,
(op_ == 'E')? NetLogic::AND : NetLogic::NAND, 1); (op_ == 'E')? NetLogic::AND : NetLogic::NAND, 1);
@ -688,6 +664,11 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
tmp->local_flag(true); tmp->local_flag(true);
connect(cmp->pin(0), tmp->pin(0)); connect(cmp->pin(0), tmp->pin(0));
} }
#else
cerr << get_line() << ": internal error: Forgot how to "
<< "elab_net === operators." << endl;
des->errors += 1;
#endif
break; break;
@ -707,19 +688,8 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
/* Oh well, do the general case with a NetCompare. */ /* Oh well, do the general case with a NetCompare. */
{ NetCompare*cmp = new NetCompare(scope, scope->local_symbol(), { NetCompare*cmp = new NetCompare(scope, scope->local_symbol(),
dwidth); dwidth);
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) { connect(cmp->pin_DataA(), lsig->pin(0));
connect(cmp->pin_DataB(), rsig->pin(0));
if (idx < lsig->pin_count())
connect(cmp->pin_DataA(idx), lsig->pin(idx));
else
connect(cmp->pin_DataA(idx), padbit->pin(0));
if (idx < rsig->pin_count())
connect(cmp->pin_DataB(idx), rsig->pin(idx));
else
connect(cmp->pin_DataB(idx), padbit->pin(0));
}
connect(cmp->pin_AEB(), osig->pin(0)); connect(cmp->pin_AEB(), osig->pin(0));
gate = cmp; gate = cmp;
} }
@ -741,19 +711,8 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
/* Oh well, do the general case with a NetCompare. */ /* Oh well, do the general case with a NetCompare. */
{ NetCompare*cmp = new NetCompare(scope, scope->local_symbol(), { NetCompare*cmp = new NetCompare(scope, scope->local_symbol(),
dwidth); dwidth);
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) { connect(cmp->pin_DataA(), lsig->pin(0));
connect(cmp->pin_DataB(), rsig->pin(0));
if (idx < lsig->pin_count())
connect(cmp->pin_DataA(idx), lsig->pin(idx));
else
connect(cmp->pin_DataA(idx), padbit->pin(0));
if (idx < rsig->pin_count())
connect(cmp->pin_DataB(idx), rsig->pin(idx));
else
connect(cmp->pin_DataB(idx), padbit->pin(0));
}
connect(cmp->pin_ANEB(), osig->pin(0)); connect(cmp->pin_ANEB(), osig->pin(0));
gate = cmp; gate = cmp;
} }
@ -2523,6 +2482,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $Log: elab_net.cc,v $
* Revision 1.142 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.141 2005/01/13 00:23:10 steve * Revision 1.141 2005/01/13 00:23:10 steve
* Fix elaboration of == compared to constants. * Fix elaboration of == compared to constants.
* *

View File

@ -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.60 2004/12/11 02:31:26 steve Exp $" #ident "$Id: expr_synth.cc,v 1.61 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -171,6 +171,8 @@ NetNet* NetEBComp::synthesize(Design*des)
0. We can use an OR gate to do the comparison. Synthesize 0. We can use an OR gate to do the comparison. Synthesize
the non-const side as normal, then or(nor) the signals the non-const side as normal, then or(nor) the signals
together to get result. */ together to get result. */
#if 0
// XXXX Need to check this for vector_width and wide logic.
if ((rcon && (rcon->value() == verinum(0UL,rcon->expr_width()))) if ((rcon && (rcon->value() == verinum(0UL,rcon->expr_width())))
|| (lcon && (lcon->value() == verinum(0UL,lcon->expr_width())))) { || (lcon && (lcon->value() == verinum(0UL,lcon->expr_width())))) {
@ -234,6 +236,7 @@ NetNet* NetEBComp::synthesize(Design*des)
des->add_node(gate); des->add_node(gate);
return osig; return osig;
} }
#endif
NetNet*lsig = left_->synthesize(des); NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des); NetNet*rsig = right_->synthesize(des);
@ -241,9 +244,9 @@ NetNet* NetEBComp::synthesize(Design*des)
NetScope*scope = lsig->scope(); NetScope*scope = lsig->scope();
assert(scope); assert(scope);
unsigned width = lsig->pin_count(); unsigned width = lsig->vector_width();
if (rsig->pin_count() > lsig->pin_count()) if (rsig->vector_width() > width)
width = rsig->pin_count(); width = rsig->vector_width();
lsig = pad_to_width(des, lsig, width); lsig = pad_to_width(des, lsig, width);
rsig = pad_to_width(des, rsig, width); rsig = pad_to_width(des, rsig, width);
@ -281,11 +284,8 @@ NetNet* NetEBComp::synthesize(Design*des)
NetCompare*dev = new NetCompare(scope, scope->local_symbol(), width); NetCompare*dev = new NetCompare(scope, scope->local_symbol(), width);
des->add_node(dev); des->add_node(dev);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) connect(dev->pin_DataA(), lsig->pin(0));
connect(dev->pin_DataA(idx), lsig->pin(idx)); connect(dev->pin_DataB(), rsig->pin(0));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(dev->pin_DataB(idx), rsig->pin(idx));
switch (op_) { switch (op_) {
@ -627,12 +627,11 @@ NetNet* NetEConst::synthesize(Design*des)
perm_string path = scope->local_symbol(); perm_string path = scope->local_symbol();
unsigned width=expr_width(); unsigned width=expr_width();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width-1,0);
osig->local_flag(true); osig->local_flag(true);
osig->set_signed(has_sign()); osig->set_signed(has_sign());
NetConst*con = new NetConst(scope, scope->local_symbol(), value()); NetConst*con = new NetConst(scope, scope->local_symbol(), value());
for (unsigned idx = 0 ; idx < width; idx += 1) connect(osig->pin(0), con->pin(0));
connect(osig->pin(idx), con->pin(idx));
des->add_node(con); des->add_node(con);
return osig; return osig;
@ -857,6 +856,9 @@ NetNet* NetESignal::synthesize(Design*des)
/* /*
* $Log: expr_synth.cc,v $ * $Log: expr_synth.cc,v $
* Revision 1.61 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.60 2004/12/11 02:31:26 steve * Revision 1.60 2004/12/11 02:31:26 steve
* Rework of internals to carry vectors through nexus instead * Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes * of single bits. Make the ivl, tgt-vvp and vvp initial changes

View File

@ -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.229 2005/01/09 20:16:01 steve Exp $" #ident "$Id: netlist.cc,v 1.230 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -957,7 +957,7 @@ const Link& NetCLShift::pin_Distance(unsigned idx) const
} }
NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi) NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi)
: NetNode(s, n, 8+2*wi), width_(wi) : NetNode(s, n, 10), width_(wi)
{ {
signed_flag_ = false; signed_flag_ = false;
pin(0).set_dir(Link::INPUT); pin(0).set_name( pin(0).set_dir(Link::INPUT); pin(0).set_name(
@ -976,12 +976,10 @@ NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi)
perm_string::literal("ALB")); perm_string::literal("ALB"));
pin(7).set_dir(Link::OUTPUT); pin(7).set_name( pin(7).set_dir(Link::OUTPUT); pin(7).set_name(
perm_string::literal("ALEB")); perm_string::literal("ALEB"));
for (unsigned idx = 0 ; idx < width_ ; idx += 1) { pin(8).set_dir(Link::INPUT);
pin(8+idx).set_dir(Link::INPUT); pin(8).set_name(perm_string::literal("DataA"));
pin(8+idx).set_name(perm_string::literal("DataA"), idx); pin(9).set_dir(Link::INPUT);
pin(8+width_+idx).set_dir(Link::INPUT); pin(9).set_name(perm_string::literal("DataB"));
pin(8+width_+idx).set_name(perm_string::literal("DataB"), idx);
}
} }
NetCompare::~NetCompare() NetCompare::~NetCompare()
@ -1083,24 +1081,24 @@ const Link& NetCompare::pin_ALEB() const
return pin(7); return pin(7);
} }
Link& NetCompare::pin_DataA(unsigned idx) Link& NetCompare::pin_DataA()
{ {
return pin(8+idx); return pin(8);
} }
const Link& NetCompare::pin_DataA(unsigned idx) const const Link& NetCompare::pin_DataA() const
{ {
return pin(8+idx); return pin(8);
} }
Link& NetCompare::pin_DataB(unsigned idx) Link& NetCompare::pin_DataB()
{ {
return pin(8+width_+idx); return pin(9);
} }
const Link& NetCompare::pin_DataB(unsigned idx) const const Link& NetCompare::pin_DataB() const
{ {
return pin(8+width_+idx); return pin(9);
} }
NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr, NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr,
@ -2344,6 +2342,9 @@ const NetProc*NetTaskDef::proc() const
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.230 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.229 2005/01/09 20:16:01 steve * Revision 1.229 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.
* *

View File

@ -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.325 2005/01/12 03:17:37 steve Exp $" #ident "$Id: netlist.h,v 1.326 2005/01/16 04:20:32 steve Exp $"
#endif #endif
/* /*
@ -558,8 +558,8 @@ class NetCompare : public NetNode {
Link& pin_ALB(); Link& pin_ALB();
Link& pin_ALEB(); Link& pin_ALEB();
Link& pin_DataA(unsigned idx); Link& pin_DataA();
Link& pin_DataB(unsigned idx); Link& pin_DataB();
const Link& pin_Aclr() const; const Link& pin_Aclr() const;
const Link& pin_Clock() const; const Link& pin_Clock() const;
@ -570,8 +570,8 @@ class NetCompare : public NetNode {
const Link& pin_ALB() const; const Link& pin_ALB() const;
const Link& pin_ALEB() const; const Link& pin_ALEB() const;
const Link& pin_DataA(unsigned idx) const; const Link& pin_DataA() const;
const Link& pin_DataB(unsigned idx) const; const Link& pin_DataB() const;
virtual void functor_node(Design*, functor_t*); virtual void functor_node(Design*, functor_t*);
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
@ -3411,6 +3411,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.326 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.325 2005/01/12 03:17:37 steve * Revision 1.325 2005/01/12 03:17:37 steve
* Properly pad vector widths in pgassign. * Properly pad vector widths in pgassign.
* *

View File

@ -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.134 2005/01/09 20:16:01 steve Exp $" #ident "$Id: t-dll.cc,v 1.135 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1240,104 +1240,90 @@ void dll_target::lpm_compare(const NetCompare*net)
obj->u_.arith.width = net->width(); obj->u_.arith.width = net->width();
obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; obj->u_.arith.signed_flag = net->get_signed()? 1 : 0;
#if 0
obj->u_.arith.q = new ivl_nexus_t[1 + 2 * obj->u_.arith.width]; const Nexus*nex;
obj->u_.arith.a = obj->u_.arith.q + 1;
obj->u_.arith.b = obj->u_.arith.a + obj->u_.arith.width; nex = net->pin_DataA().nexus();
assert(nex->t_cookie());
obj->u_.arith.a = (ivl_nexus_t) nex->t_cookie();
nex = net->pin_DataB().nexus();
assert(nex->t_cookie());
obj->u_.arith.b = (ivl_nexus_t) nex->t_cookie();
if (net->pin_AGEB().is_linked()) { if (net->pin_AGEB().is_linked()) {
const Nexus*nex = net->pin_AGEB().nexus(); nex = net->pin_AGEB().nexus();
obj->type = IVL_LPM_CMP_GE; obj->type = IVL_LPM_CMP_GE;
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[0], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
} else if (net->pin_AGB().is_linked()) { } else if (net->pin_AGB().is_linked()) {
const Nexus*nex = net->pin_AGB().nexus(); nex = net->pin_AGB().nexus();
obj->type = IVL_LPM_CMP_GT; obj->type = IVL_LPM_CMP_GT;
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[0], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
} else if (net->pin_ALEB().is_linked()) { } else if (net->pin_ALEB().is_linked()) {
const Nexus*nex = net->pin_ALEB().nexus(); nex = net->pin_ALEB().nexus();
obj->type = IVL_LPM_CMP_GE; obj->type = IVL_LPM_CMP_GE;
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[0], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
swap_operands = true; swap_operands = true;
} else if (net->pin_ALB().is_linked()) { } else if (net->pin_ALB().is_linked()) {
const Nexus*nex = net->pin_ALB().nexus(); nex = net->pin_ALB().nexus();
obj->type = IVL_LPM_CMP_GT; obj->type = IVL_LPM_CMP_GT;
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[0], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
swap_operands = true; swap_operands = true;
} else if (net->pin_AEB().is_linked()) { } else if (net->pin_AEB().is_linked()) {
const Nexus*nex = net->pin_AEB().nexus(); nex = net->pin_AEB().nexus();
obj->type = IVL_LPM_CMP_EQ; obj->type = IVL_LPM_CMP_EQ;
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[0], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
} else if (net->pin_ANEB().is_linked()) { } else if (net->pin_ANEB().is_linked()) {
const Nexus*nex = net->pin_ANEB().nexus(); nex = net->pin_ANEB().nexus();
obj->type = IVL_LPM_CMP_NE; obj->type = IVL_LPM_CMP_NE;
if (! nex->t_cookie()) {
cerr << "internal error: COMPARE_NE device " <<
net->name()<<" ANEB pin nexus has no cookie."<<endl;
assert(0);
}
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[0] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[0], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
} else { } else {
assert(0); assert(0);
} }
for (unsigned idx = 0 ; idx < net->width() ; idx += 1) { if (swap_operands) {
const Nexus*nex; ivl_nexus_t tmp = obj->u_.arith.a;
obj->u_.arith.a = obj->u_.arith.b;
nex = swap_operands obj->u_.arith.b = tmp;
? net->pin_DataB(idx).nexus()
: net->pin_DataA(idx).nexus();
assert(nex->t_cookie());
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
nex = swap_operands
? net->pin_DataA(idx).nexus()
: net->pin_DataB(idx).nexus();
assert(nex->t_cookie());
obj->u_.arith.b[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.b[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
} }
#else
cerr << "XXXX: t-dll.cc: Forgot how to handle lpm_compare." << endl; nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
#endif nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
scope_add_lpm(obj->scope, obj); scope_add_lpm(obj->scope, obj);
} }
@ -2239,6 +2225,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/* /*
* $Log: t-dll.cc,v $ * $Log: t-dll.cc,v $
* Revision 1.135 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.134 2005/01/09 20:16:01 steve * Revision 1.134 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.
* *

View File

@ -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.95 2005/01/09 20:16:01 steve Exp $" #ident "$Id: stub.c,v 1.96 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -179,6 +179,20 @@ void show_expression(ivl_expr_t net, unsigned ind)
} }
} }
/* IVL_LPM_CMP_GE
* This LPM node supports two-input compare.
*/
static void show_lpm_cmp_ge(ivl_lpm_t net)
{
unsigned width = ivl_lpm_width(net);
fprintf(out, " LPM_CMP_GE %s: <width=%u>\n",
ivl_lpm_basename(net), width);
fprintf(out, " O: %s\n", ivl_nexus_name(ivl_lpm_q(net,0)));
fprintf(out, " A: %s\n", ivl_nexus_name(ivl_lpm_data(net,0)));
fprintf(out, " B: %s\n", ivl_nexus_name(ivl_lpm_data(net,1)));
}
/* IVL_LPM_CONCAT /* IVL_LPM_CONCAT
* The concat device takes N inputs (N=ivl_lpm_selects) and generates * The concat device takes N inputs (N=ivl_lpm_selects) and generates
@ -262,6 +276,10 @@ static void show_lpm(ivl_lpm_t net)
break; break;
} }
case IVL_LPM_CMP_GE:
show_lpm_cmp_ge(net);
break;
case IVL_LPM_CMP_NE: { case IVL_LPM_CMP_NE: {
fprintf(out, " LPM_COMPARE(NE) %s: <width=%u>\n", fprintf(out, " LPM_COMPARE(NE) %s: <width=%u>\n",
ivl_lpm_basename(net), width); ivl_lpm_basename(net), width);
@ -827,6 +845,9 @@ int target_design(ivl_design_t des)
/* /*
* $Log: stub.c,v $ * $Log: stub.c,v $
* Revision 1.96 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.95 2005/01/09 20:16:01 steve * Revision 1.95 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.
* *

View File

@ -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.109 2005/01/12 05:31:50 steve Exp $" #ident "$Id: vvp_scope.c,v 1.110 2005/01/16 04:20:32 steve Exp $"
#endif #endif
# include "vvp_priv.h" # include "vvp_priv.h"
@ -432,6 +432,8 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
case IVL_LPM_RAM: case IVL_LPM_RAM:
case IVL_LPM_ADD: case IVL_LPM_ADD:
case IVL_LPM_CONCAT: case IVL_LPM_CONCAT:
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR: case IVL_LPM_SHIFTR:
case IVL_LPM_SUB: case IVL_LPM_SUB:
@ -448,8 +450,6 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
break; break;
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NE:
if (ivl_lpm_q(lpm, 0) == nex) { if (ivl_lpm_q(lpm, 0) == nex) {
@ -1188,7 +1188,7 @@ static void draw_lpm_arith_a_b_inputs(ivl_lpm_t net)
fprintf(vvp_out, ", V_%s", vvp_signal_label(sig)); fprintf(vvp_out, ", V_%s", vvp_signal_label(sig));
sig = 0; sig = 0;
nex = ivl_lpm_datab(net, 0); nex = ivl_lpm_data(net, 1);
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
np = ivl_nexus_ptr(nex,idx); np = ivl_nexus_ptr(nex,idx);
sig = ivl_nexus_ptr_sig(np); sig = ivl_nexus_ptr_sig(np);
@ -1256,6 +1256,7 @@ static void draw_lpm_add(ivl_lpm_t net)
static void draw_lpm_cmp(ivl_lpm_t net) static void draw_lpm_cmp(ivl_lpm_t net)
{ {
const char*src_table[2];
unsigned width; unsigned width;
const char*type = ""; const char*type = "";
const char*signed_string = ivl_lpm_signed(net)? ".s" : ""; const char*signed_string = ivl_lpm_signed(net)? ".s" : "";
@ -1273,14 +1274,10 @@ static void draw_lpm_cmp(ivl_lpm_t net)
assert(0); assert(0);
} }
fprintf(vvp_out, "L_%s.%s .cmp/%s%s %u", draw_lpm_data_inputs(net, 0, 2, src_table);
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))), fprintf(vvp_out, "L_%p .cmp/%s%s %u, %s, %s;\n",
vvp_mangle_id(ivl_lpm_basename(net)), type, net, type, signed_string, width,
signed_string, width); src_table[0], src_table[1]);
draw_lpm_arith_a_b_inputs(net);
fprintf(vvp_out, ";\n");
} }
/* /*
@ -1827,6 +1824,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/* /*
* $Log: vvp_scope.c,v $ * $Log: vvp_scope.c,v $
* Revision 1.110 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.109 2005/01/12 05:31:50 steve * Revision 1.109 2005/01/12 05:31:50 steve
* More robust input code generation for LPM_ADD. * More robust input code generation for LPM_ADD.
* *