Support shifts and divide.

This commit is contained in:
steve 2005-02-19 02:43:38 +00:00
parent 5fe5d9184d
commit 257e1f9516
10 changed files with 328 additions and 373 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: elab_net.cc,v 1.151 2005/02/12 06:25:40 steve Exp $" #ident "$Id: elab_net.cc,v 1.152 2005/02/19 02:43:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -723,23 +723,23 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
unsigned rwidth = lwidth; unsigned rwidth = lwidth;
if (rwidth == 0) { if (rwidth == 0) {
rwidth = lsig->pin_count(); rwidth = lsig->vector_width();
if (rsig->pin_count() > rwidth) if (rsig->vector_width() > rwidth)
rwidth = rsig->pin_count(); rwidth = rsig->vector_width();
lwidth = rwidth; lwidth = rwidth;
} }
if ((rwidth > lsig->pin_count()) && (rwidth > rsig->pin_count())) { if ((rwidth > lsig->vector_width()) && (rwidth > rsig->vector_width())) {
rwidth = lsig->pin_count(); rwidth = lsig->vector_width();
if (rsig->pin_count() > rwidth) if (rsig->vector_width() > rwidth)
rwidth = rsig->pin_count(); rwidth = rsig->vector_width();
} }
// Create a device with the calculated dimensions. // Create a device with the calculated dimensions.
NetDivide*div = new NetDivide(scope, scope->local_symbol(), rwidth, NetDivide*div = new NetDivide(scope, scope->local_symbol(), rwidth,
lsig->pin_count(), lsig->vector_width(),
rsig->pin_count()); rsig->vector_width());
des->add_node(div); des->add_node(div);
div->set_signed(lsig->get_signed() && rsig->get_signed()); div->set_signed(lsig->get_signed() && rsig->get_signed());
@ -747,10 +747,8 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
// Connect the left and right inputs of the divider to the // Connect the left and right inputs of the divider to the
// nets that are the left and right expressions. // nets that are the left and right expressions.
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) connect(div->pin_DataA(), lsig->pin(0));
connect(div->pin_DataA(idx), lsig->pin(idx)); connect(div->pin_DataB(), rsig->pin(0));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(div->pin_DataB(idx), rsig->pin(idx));
// Make an output signal that is the width of the l-value. // Make an output signal that is the width of the l-value.
@ -763,24 +761,9 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
osig->local_flag(true); osig->local_flag(true);
osig->set_signed(div->get_signed()); osig->set_signed(div->get_signed());
for (unsigned idx = 0 ; idx < rwidth ; idx += 1) connect(div->pin_Result(), osig->pin(0));
connect(div->pin_Result(idx), osig->pin(idx));
// If the lvalue is larger then the result, then pad the
// output with constant 0. This can happen for example in
// cases like this:
// wire [3;0] a, b;
// wire [7:0] r = a / b;
if (rwidth < osig->pin_count()) {
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
verinum::V0);
des->add_node(tmp);
for (unsigned idx = rwidth ; idx < osig->pin_count() ; idx += 1)
connect(osig->pin(idx), tmp->pin(0));
}
return osig; return osig;
} }
@ -1004,8 +987,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0); NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
if (lsig == 0) return 0; if (lsig == 0) return 0;
if (lsig->pin_count() > lwidth) if (lsig->vector_width() > lwidth)
lwidth = lsig->pin_count(); lwidth = lsig->vector_width();
bool right_flag = op_ == 'r' || op_ == 'R'; bool right_flag = op_ == 'r' || op_ == 'R';
bool signed_flag = op_ == 'R'; bool signed_flag = op_ == 'R';
@ -1013,56 +996,123 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
/* Handle the special case of a constant shift amount. There /* Handle the special case of a constant shift amount. There
is no reason in this case to create a gate at all, just is no reason in this case to create a gate at all, just
connect the lsig to the osig with the bit positions connect the lsig to the osig with the bit positions
shifted. */ shifted. Use a NetPartSelect to select the parts of the
left expression that survive the shift, and a NetConcat to
concatenate a constant for padding. */
if (verinum*rval = right_->eval_const(des, scope)) { if (verinum*rval = right_->eval_const(des, scope)) {
assert(rval->is_defined()); assert(rval->is_defined());
unsigned dist = rval->as_ulong(); unsigned dist = rval->as_ulong();
if (dist > lwidth)
dist = lwidth;
/* Very special case, constant 0 shift. */ /* Very special case: constant 0 shift. Simply return
the left signal again. */
if (dist == 0) return lsig; if (dist == 0) return lsig;
/* Another very special case: constant shift the entire
value away. The result is a const. */
if (dist > lwidth) {
assert(0);
}
/* The construction that I'm making will ultimately
connect its output to the osig here. This will be the
result that I return from this function. */
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, lwidth); NetNet::WIRE, lwidth);
osig->local_flag(true); osig->local_flag(true);
NetConst*zero = new NetConst(scope, scope->local_symbol(),
verinum::V0);
des->add_node(zero);
if (op_ == 'l') { /* Make the constant zero's that I'm going to pad to the
/* Left shift means put some zeros on the bottom top or bottom of the left expression. Attach a signal
of the vector. */ to its output so that I don't have to worry about it
unsigned idx; later. If the left expression is less then the
for (idx = 0 ; idx < dist ; idx += 1) desired width (and we are doing right shifts) then we
connect(osig->pin(idx), zero->pin(0)); can combine the expression padding with the distance
for ( ; (idx<lwidth) && ((idx-dist) < lsig->pin_count()) padding to reduce nodes. */
; idx += 1) unsigned pad_width = dist;
connect(osig->pin(idx), lsig->pin(idx-dist)); unsigned part_width = lwidth - dist;
for ( ; idx < lwidth ; idx += 1) if (op_ == 'r' || op_ == 'R') {
connect(osig->pin(idx), zero->pin(0)); if (lsig->vector_width() < lwidth) {
pad_width += lwidth - lsig->vector_width();
part_width -= lwidth - lsig->vector_width();
}
} else {
} else if (op_ == 'R') { /* The left net must be the same width as the
/* Signed right shift. */ result. The part select that I'm about to make relies
unsigned idx; on that. */
unsigned keep = lsig->pin_count()-dist; lsig = pad_to_width(des, lsig, lwidth);
for (idx = 0 ; idx < keep ; idx += 1)
connect(osig->pin(idx), lsig->pin(idx+dist)); }
for (idx = keep ; idx < lwidth ; idx += 1)
connect(osig->pin(idx), lsig->pin(keep+dist-1)); NetNet*zero = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, pad_width);
zero->local_flag(true);
zero->set_line(*this);
if (op_ == 'R') {
NetPartSelect*sign_bit
= new NetPartSelect(lsig, lsig->vector_width()-1,
1, NetPartSelect::VP);
des->add_node(sign_bit);
NetReplicate*sign_pad
= new NetReplicate(scope, scope->local_symbol(),
pad_width, pad_width);
des->add_node(sign_pad);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 1);
connect(sign_bit->pin(0), tmp->pin(0));
connect(sign_bit->pin(0), sign_pad->pin(1));
connect(zero->pin(0), sign_pad->pin(0));
} else { } else {
/* Unsigned right shift. */ NetConst*zero_c = new NetConst(scope, scope->local_symbol(),
assert(op_ == 'r'); verinum(verinum::V0, pad_width));
unsigned idx; des->add_node(zero_c);
unsigned keep = lsig->pin_count()-dist; connect(zero->pin(0), zero_c->pin(0));
for (idx = 0 ; idx < keep ; idx += 1)
connect(osig->pin(idx), lsig->pin(idx+dist));
for (idx = keep ; idx < lwidth ; idx += 1)
connect(osig->pin(idx), zero->pin(0));
} }
/* Make a concatenation operator that will join the
part-selected right expression at the pad values. */
NetConcat*cc = new NetConcat(scope, scope->local_symbol(),
lwidth, 2);
cc->set_line(*this);
des->add_node(cc);
connect(cc->pin(0), osig->pin(0));
/* Make the part select of the left expression and
connect it to the lsb or msb of the concatenation,
depending on the direction of the shift. */
NetPartSelect*part;
switch (op_) {
case 'l': // Left shift === {lsig, zero}
part = new NetPartSelect(lsig, 0, part_width,
NetPartSelect::VP);
connect(cc->pin(1), zero->pin(0));
connect(cc->pin(2), part->pin(0));
break;
case 'R':
case 'r': // right-shift === {zero, lsig}
part = new NetPartSelect(lsig, dist, part_width,
NetPartSelect::VP);
connect(cc->pin(1), part->pin(0));
connect(cc->pin(2), zero->pin(0));
break;
default:
assert(0);
}
des->add_node(part);
/* Attach a signal to the part select output (NetConcat
input) */
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, part_width);
tmp->local_flag(true);
tmp->set_line(*this);
connect(part->pin(0), tmp->pin(0));
return osig; return osig;
} }
@ -1078,39 +1128,31 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
// Make the shift device itself, and the output // Make the shift device itself, and the output
// NetNet. Connect the Result output pins to the osig signal // NetNet. Connect the Result output pins to the osig signal
NetCLShift*gate = new NetCLShift(scope, scope->local_symbol(), NetCLShift*gate = new NetCLShift(scope, scope->local_symbol(),
lwidth, rsig->pin_count(), lwidth, rsig->vector_width(),
right_flag, signed_flag); right_flag, signed_flag);
des->add_node(gate);
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, lwidth); NetNet::WIRE, lwidth);
osig->local_flag(true); osig->local_flag(true);
osig->set_signed(signed_flag);
for (unsigned idx = 0 ; idx < lwidth ; idx += 1) connect(osig->pin(0), gate->pin_Result());
connect(osig->pin(idx), gate->pin_Result(idx));
// Connect the lsig (the left expression) to the Data input, // Connect the lsig (the left expression) to the Data input,
// and pad it if necessary with constant zeros. // and pad it if necessary with constant zeros.
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) assert(lsig->vector_width() == lwidth);
connect(lsig->pin(idx), gate->pin_Data(idx)); connect(lsig->pin(0), gate->pin_Data());
if (lsig->pin_count() < lwidth) {
NetConst*zero = new NetConst(scope, scope->local_symbol(),
verinum::V0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
tmp->local_flag(true);
des->add_node(zero);
connect(zero->pin(0), tmp->pin(0));
for (unsigned idx = lsig->pin_count() ; idx < lwidth ; idx += 1)
connect(zero->pin(0), gate->pin_Data(idx));
}
// Connect the rsig (the shift amount expression) to the // Connect the rsig (the shift amount expression) to the
// Distance input. // Distance input.
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1) connect(rsig->pin(0), gate->pin_Distance());
connect(rsig->pin(idx), gate->pin_Distance(idx));
des->add_node(gate); if (debug_elaborate) {
cerr << get_line() << ": debug: "
<< "Elaborate LPM_SHIFT: width="<<gate->width()
<< ", swidth="<< gate->width_dist() << endl;
}
return osig; return osig;
} }
@ -2462,6 +2504,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $Log: elab_net.cc,v $
* Revision 1.152 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.151 2005/02/12 06:25:40 steve * Revision 1.151 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors. * Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions, * Generate NetMux devices from ternary expressions,

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: elaborate.cc,v 1.318 2005/02/10 04:56:58 steve Exp $" #ident "$Id: elaborate.cc,v 1.319 2005/02/19 02:43:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -94,7 +94,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
assert(lval->pin_count() == 1); assert(lval->pin_count() == 1);
if (debug_elaborate) { if (debug_elaborate) {
cerr << lval->get_line() << ": debug: PGassign: elaborated l-value" cerr << get_line() << ": debug: PGassign: elaborated l-value"
<< " width=" << lval->vector_width() << endl; << " width=" << lval->vector_width() << endl;
} }
@ -2938,6 +2938,9 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.319 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.318 2005/02/10 04:56:58 steve * Revision 1.318 2005/02/10 04:56:58 steve
* distinguish between single port namy instances, and single instances many sub-ports. * distinguish between single port namy instances, and single instances many sub-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: expr_synth.cc,v 1.63 2005/02/12 06:25:40 steve Exp $" #ident "$Id: expr_synth.cc,v 1.64 2005/02/19 02:43:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -371,16 +371,13 @@ NetNet* NetEBDiv::synthesize(Design*des)
case '/': { case '/': {
NetDivide*div = new NetDivide(scope, scope->local_symbol(), NetDivide*div = new NetDivide(scope, scope->local_symbol(),
expr_width(), expr_width(),
lsig->pin_count(), lsig->vector_width(),
rsig->pin_count()); rsig->vector_width());
des->add_node(div); des->add_node(div);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) connect(div->pin_DataA(), lsig->pin(0));
connect(div->pin_DataA(idx), lsig->pin(idx)); connect(div->pin_DataB(), rsig->pin(0));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1) connect(div->pin_Result(),osig->pin(0));
connect(div->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(div->pin_Result(idx), osig->pin(idx));
break; break;
} }
@ -562,20 +559,18 @@ NetNet* NetEBShift::synthesize(Design*des)
assert(op() == 'l'); assert(op() == 'l');
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(), NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
osig->pin_count(), osig->vector_width(),
rsig->pin_count(), rsig->vector_width(),
right_flag, signed_flag); right_flag, signed_flag);
dev->set_line(*this);
des->add_node(dev); des->add_node(dev);
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) connect(dev->pin_Result(), osig->pin(0));
connect(dev->pin_Result(idx), osig->pin(idx));
assert(lsig->pin_count() >= dev->width()); assert(lsig->vector_width() == dev->width());
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) connect(dev->pin_Data(), lsig->pin(0));
connect(dev->pin_Data(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < dev->width_dist() ; idx += 1) connect(dev->pin_Distance(), rsig->pin(0));
connect(dev->pin_Distance(idx), rsig->pin(idx));
return osig; return osig;
} }
@ -850,6 +845,9 @@ NetNet* NetESignal::synthesize(Design*des)
/* /*
* $Log: expr_synth.cc,v $ * $Log: expr_synth.cc,v $
* Revision 1.64 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.63 2005/02/12 06:25:40 steve * Revision 1.63 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors. * Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions, * Generate NetMux devices from ternary expressions,

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: ivl_target.h,v 1.142 2005/02/14 01:51:39 steve Exp $" #ident "$Id: ivl_target.h,v 1.143 2005/02/19 02:43:38 steve Exp $"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -766,6 +766,11 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* the concatentation. The ivl_lpm_size function returns the number of * the concatentation. The ivl_lpm_size function returns the number of
* inputs help by the device. * inputs help by the device.
* *
* - Divide (IVL_LPM_DIVIDE)
* The divide operators take two inputs and generate an output. The
* ivl_lpm_width returns the width of the result. The width of the
* inputs are their own.
*
* - Multiply (IVL_LPM_MULT) * - Multiply (IVL_LPM_MULT)
* The multiply takes two inputs and generates an output. Unlike other * The multiply takes two inputs and generates an output. Unlike other
* arithmetic nodes, the width only refers to the output. The inputs * arithmetic nodes, the width only refers to the output. The inputs
@ -833,6 +838,12 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* vector. The ivl_lpm_size() returns the number of times the input is * vector. The ivl_lpm_size() returns the number of times the input is
* repeated to get the desired width. The ivl core assures that the * repeated to get the desired width. The ivl core assures that the
* input vector is exactly ivl_lpm_width() / ivl_lpm_size() bits. * input vector is exactly ivl_lpm_width() / ivl_lpm_size() bits.
*
* - Shifts (IVL_LPM_SHIFTL/SHIFTR)
* This node takes two inputs, a vector and a shift distance. The
* ivl_lpm_data(0) nexus is the vector input, and the ivl_lpm_data(1)
* the shift distance. The vector input is the same width as the
* output, but the distance has its own width.
*/ */
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */ extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
@ -858,7 +869,7 @@ extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
/* IVL_LPM_FF IVL_LPM_RAM */ /* IVL_LPM_FF IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
/* IVL_LPM_ADD IVL_LPM_CONCAT IVL_LPM_FF IVL_LPM_PART IVL_LPM_MULT /* IVL_LPM_ADD IVL_LPM_CONCAT IVL_LPM_FF IVL_LPM_PART IVL_LPM_MULT
IVL_LPM_MUX IVL_LPM_RAM IVL_LPM_SUB */ IVL_LPM_MUX IVL_LPM_RAM IVL_LPM_SHIFTL IVL_LPM_SHIFTR IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */ /* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
@ -1516,6 +1527,9 @@ _END_DECL
/* /*
* $Log: ivl_target.h,v $ * $Log: ivl_target.h,v $
* Revision 1.143 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.142 2005/02/14 01:51:39 steve * Revision 1.142 2005/02/14 01:51:39 steve
* Handle bit selects in l-values to assignments. * Handle bit selects in l-values to assignments.
* *

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.237 2005/02/12 06:25:40 steve Exp $" #ident "$Id: netlist.cc,v 1.238 2005/02/19 02:43:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -842,39 +842,23 @@ const Link& NetAddSub::pin_Result() const
/* /*
* The pinout for the NetCLShift is: * The pinout for the NetCLShift is:
* 0 -- Direction * 0 -- Result
* 1 -- Underflow * 1 -- Data
* 2 -- Overflow * 2 -- Distance
* 3 -- Data(0)
* 3+W -- Result(0)
* 3+2W -- Distance(0)
*/ */
NetCLShift::NetCLShift(NetScope*s, perm_string n, NetCLShift::NetCLShift(NetScope*s, perm_string n,
unsigned width, unsigned width_dist, unsigned width, unsigned width_dist,
bool right_flag, bool signed_flag) bool right_flag, bool signed_flag)
: NetNode(s, n, 3+2*width+width_dist), : NetNode(s, n, 3),
width_(width), width_dist_(width_dist), width_(width), width_dist_(width_dist),
right_flag_(right_flag), signed_flag_(signed_flag) right_flag_(right_flag), signed_flag_(signed_flag)
{ {
pin(0).set_dir(Link::INPUT); pin(0).set_name( pin(0).set_dir(Link::OUTPUT);
perm_string::literal("Direction"), 0); pin(0).set_name(perm_string::literal("Result"), 0);
pin(1).set_dir(Link::OUTPUT); pin(1).set_name( pin(1).set_dir(Link::INPUT);
perm_string::literal("Underflow"), 0); pin(1).set_name(perm_string::literal("Data"), 0);
pin(2).set_dir(Link::OUTPUT); pin(2).set_name( pin(2).set_dir(Link::INPUT);
perm_string::literal("Overflow"), 0); pin(2).set_name(perm_string::literal("Distance"), 0);
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
pin(3+idx).set_dir(Link::INPUT);
pin(3+idx).set_name(perm_string::literal("Data"), idx);
pin(3+width_+idx).set_dir(Link::OUTPUT);
pin(3+width_+idx).set_name(perm_string::literal("Result"), idx);
}
for (unsigned idx = 0 ; idx < width_dist_ ; idx += 1) {
pin(3+2*width_+idx).set_dir(Link::INPUT);
pin(3+2*width_+idx).set_name(perm_string::literal("Distance"), idx);
}
} }
NetCLShift::~NetCLShift() NetCLShift::~NetCLShift()
@ -901,74 +885,36 @@ bool NetCLShift::signed_flag() const
return signed_flag_; return signed_flag_;
} }
#if 0 Link& NetCLShift::pin_Data()
Link& NetCLShift::pin_Direction()
{
return pin(0);
}
const Link& NetCLShift::pin_Direction() const
{
return pin(0);
}
#endif
Link& NetCLShift::pin_Underflow()
{ {
return pin(1); return pin(1);
} }
const Link& NetCLShift::pin_Underflow() const const Link& NetCLShift::pin_Data() const
{ {
return pin(1); return pin(1);
} }
Link& NetCLShift::pin_Overflow() Link& NetCLShift::pin_Result()
{
return pin(0);
}
const Link& NetCLShift::pin_Result() const
{
return pin(0);
}
Link& NetCLShift::pin_Distance()
{ {
return pin(2); return pin(2);
} }
const Link& NetCLShift::pin_Overflow() const const Link& NetCLShift::pin_Distance() const
{ {
return pin(2); return pin(2);
} }
Link& NetCLShift::pin_Data(unsigned idx)
{
assert(idx < width_);
return pin(3+idx);
}
const Link& NetCLShift::pin_Data(unsigned idx) const
{
assert(idx < width_);
return pin(3+idx);
}
Link& NetCLShift::pin_Result(unsigned idx)
{
assert(idx < width_);
return pin(3+width_+idx);
}
const Link& NetCLShift::pin_Result(unsigned idx) const
{
assert(idx < width_);
return pin(3+width_+idx);
}
Link& NetCLShift::pin_Distance(unsigned idx)
{
assert(idx < width_dist_);
return pin(3+2*width_+idx);
}
const Link& NetCLShift::pin_Distance(unsigned idx) const
{
assert(idx < width_dist_);
return pin(3+2*width_+idx);
}
NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi) NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi)
: NetNode(s, n, 10), width_(wi) : NetNode(s, n, 10), width_(wi)
{ {
@ -1116,22 +1062,15 @@ const Link& NetCompare::pin_DataB() const
NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr, NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr,
unsigned wa, unsigned wb) unsigned wa, unsigned wb)
: NetNode(sc, n, wr+wa+wb), : NetNode(sc, n, 3),
width_r_(wr), width_a_(wa), width_b_(wb), signed_flag_(false) width_r_(wr), width_a_(wa), width_b_(wb), signed_flag_(false)
{ {
unsigned p = 0; pin(0).set_dir(Link::OUTPUT);
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) { pin(0).set_name(perm_string::literal("Result"), 0);
pin(p).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("Result"), idx); pin(1).set_name(perm_string::literal("DataA"), 0);
} pin(2).set_dir(Link::INPUT);
for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) { pin(2).set_name(perm_string::literal("DataB"), 0);
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("DataA"), idx);
}
for (unsigned idx = 0 ; idx < width_b_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("DataB"), idx);
}
} }
NetDivide::~NetDivide() NetDivide::~NetDivide()
@ -1163,40 +1102,34 @@ bool NetDivide::get_signed() const
return signed_flag_; return signed_flag_;
} }
Link& NetDivide::pin_Result(unsigned idx) Link& NetDivide::pin_Result()
{ {
assert(idx < width_r_); return pin(0);
return pin(idx);
} }
const Link& NetDivide::pin_Result(unsigned idx) const const Link& NetDivide::pin_Result() const
{ {
assert(idx < width_r_); return pin(0);
return pin(idx);
} }
Link& NetDivide::pin_DataA(unsigned idx) Link& NetDivide::pin_DataA()
{ {
assert(idx < width_a_); return pin(1);
return pin(idx+width_r_);
} }
const Link& NetDivide::pin_DataA(unsigned idx) const const Link& NetDivide::pin_DataA() const
{ {
assert(idx < width_a_); return pin(1);
return pin(idx+width_r_);
} }
Link& NetDivide::pin_DataB(unsigned idx) Link& NetDivide::pin_DataB()
{ {
assert(idx < width_b_); return pin(2);
return pin(idx+width_r_+width_a_);
} }
const Link& NetDivide::pin_DataB(unsigned idx) const const Link& NetDivide::pin_DataB() const
{ {
assert(idx < width_b_); return pin(2);
return pin(idx+width_r_+width_a_);
} }
NetMult::NetMult(NetScope*sc, perm_string n, unsigned wr, NetMult::NetMult(NetScope*sc, perm_string n, unsigned wr,
@ -2258,6 +2191,9 @@ const NetProc*NetTaskDef::proc() const
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.238 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.237 2005/02/12 06:25:40 steve * Revision 1.237 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors. * Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions, * Generate NetMux devices from ternary expressions,

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.334 2005/02/12 06:25:40 steve Exp $" #ident "$Id: netlist.h,v 1.335 2005/02/19 02:43:38 steve Exp $"
#endif #endif
/* /*
@ -506,19 +506,13 @@ class NetCLShift : public NetNode {
bool right_flag() const; bool right_flag() const;
bool signed_flag() const; bool signed_flag() const;
Link& pin_Direction(); Link& pin_Data();
Link& pin_Underflow(); Link& pin_Result();
Link& pin_Overflow(); Link& pin_Distance();
Link& pin_Data(unsigned idx);
Link& pin_Result(unsigned idx);
Link& pin_Distance(unsigned idx);
const Link& pin_Direction() const; const Link& pin_Data() const;
const Link& pin_Underflow() const; const Link& pin_Result() const;
const Link& pin_Overflow() const; const Link& pin_Distance() const;
const Link& pin_Data(unsigned idx) const;
const Link& pin_Result(unsigned idx) const;
const Link& pin_Distance(unsigned idx) const;
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const; virtual bool emit_node(struct target_t*) const;
@ -639,13 +633,13 @@ class NetDivide : public NetNode {
void set_signed(bool); void set_signed(bool);
bool get_signed() const; bool get_signed() const;
Link& pin_DataA(unsigned idx); Link& pin_DataA();
Link& pin_DataB(unsigned idx); Link& pin_DataB();
Link& pin_Result(unsigned idx); Link& pin_Result();
const Link& pin_DataA(unsigned idx) const; const Link& pin_DataA() const;
const Link& pin_DataB(unsigned idx) const; const Link& pin_DataB() const;
const Link& pin_Result(unsigned idx) const; const Link& pin_Result() const;
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const; virtual bool emit_node(struct target_t*) const;
@ -3420,6 +3414,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.335 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.334 2005/02/12 06:25:40 steve * Revision 1.334 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors. * Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions, * Generate NetMux devices from ternary expressions,

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-api.cc,v 1.118 2005/02/12 06:25:40 steve Exp $" #ident "$Id: t-dll-api.cc,v 1.119 2005/02/19 02:43:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -770,8 +770,11 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR: case IVL_LPM_SHIFTR:
assert(idx < net->u_.shift.width); assert(idx <= 1);
return net->u_.shift.d[idx]; if (idx == 0)
return net->u_.shift.d;
else
return net->u_.shift.s;
case IVL_LPM_FF: case IVL_LPM_FF:
case IVL_LPM_RAM: case IVL_LPM_RAM:
@ -933,8 +936,8 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR: case IVL_LPM_SHIFTR:
assert(idx < net->u_.shift.width); assert(idx == 0);
return net->u_.shift.q[idx]; return net->u_.shift.q;
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
assert(idx < net->u_.ufunc.port_wid[0]); assert(idx < net->u_.ufunc.port_wid[0]);
@ -978,11 +981,6 @@ extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx)
assert(idx == 0); assert(idx == 0);
return net->u_.mux.s; return net->u_.mux.s;
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
assert(idx < net->u_.shift.select);
return net->u_.shift.s[idx];
default: default:
assert(0); assert(0);
return 0; return 0;
@ -996,9 +994,6 @@ extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
return net->u_.ff.swid; return net->u_.ff.swid;
case IVL_LPM_MUX: case IVL_LPM_MUX:
return net->u_.mux.swid; return net->u_.mux.swid;
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
return net->u_.shift.select;
case IVL_LPM_CONCAT: case IVL_LPM_CONCAT:
return net->u_.concat.inputs; return net->u_.concat.inputs;
default: default:
@ -1992,6 +1987,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
/* /*
* $Log: t-dll-api.cc,v $ * $Log: t-dll-api.cc,v $
* Revision 1.119 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.118 2005/02/12 06:25:40 steve * Revision 1.118 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors. * Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions, * Generate NetMux devices from ternary expressions,

101
t-dll.cc
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.141 2005/02/13 01:15:07 steve Exp $" #ident "$Id: t-dll.cc,v 1.142 2005/02/19 02:43:38 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1211,46 +1211,26 @@ void dll_target::lpm_clshift(const NetCLShift*net)
obj->u_.shift.width = net->width(); obj->u_.shift.width = net->width();
obj->u_.shift.select = net->width_dist(); obj->u_.shift.select = net->width_dist();
unsigned nex_count = obj->u_.shift.width * 2 + obj->u_.shift.select;
obj->u_.shift.q = new ivl_nexus_t[nex_count];
obj->u_.shift.d = obj->u_.shift.q + obj->u_.shift.width;
obj->u_.shift.s = obj->u_.shift.d + obj->u_.shift.width;
for (unsigned idx = 0 ; idx < nex_count ; idx += 1)
obj->u_.shift.q[idx] = 0;
for (unsigned idx = 0 ; idx < net->width() ; idx += 1) {
const Nexus*nex; const Nexus*nex;
nex = net->pin_Result(idx).nexus(); nex = net->pin_Result().nexus();
assert(nex && nex->t_cookie()); assert(nex->t_cookie());
obj->u_.shift.q[idx] = (ivl_nexus_t) nex->t_cookie(); obj->u_.shift.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.shift.q[idx], obj, 0, nexus_lpm_add(obj->u_.shift.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
IVL_DR_STRONG, IVL_DR_STRONG);
}
for (unsigned idx = 0 ; idx < net->width() ; idx += 1) { nex = net->pin_Data().nexus();
const Nexus*nex; assert(nex->t_cookie());
nex = net->pin_Data(idx).nexus(); obj->u_.shift.d = (ivl_nexus_t) nex->t_cookie();
assert(nex && nex->t_cookie()); nexus_lpm_add(obj->u_.shift.d, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
obj->u_.shift.d[idx] = (ivl_nexus_t) nex->t_cookie(); nex = net->pin_Distance().nexus();
nexus_lpm_add(obj->u_.shift.q[idx], obj, 0, assert(nex->t_cookie());
IVL_DR_HiZ, IVL_DR_HiZ);
}
for (unsigned idx = 0 ; idx < net->width_dist() ; idx += 1) { obj->u_.shift.s = (ivl_nexus_t) nex->t_cookie();
const Nexus*nex; nexus_lpm_add(obj->u_.shift.s, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
nex = net->pin_Distance(idx).nexus();
assert(nex && nex->t_cookie());
obj->u_.shift.s[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.shift.s[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
}
scope_add_lpm(obj->scope, obj); scope_add_lpm(obj->scope, obj);
} }
@ -1373,62 +1353,28 @@ void dll_target::lpm_divide(const NetDivide*net)
obj->u_.arith.width = wid; obj->u_.arith.width = wid;
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[3 * obj->u_.arith.width];
obj->u_.arith.a = obj->u_.arith.q + obj->u_.arith.width;
obj->u_.arith.b = obj->u_.arith.a + obj->u_.arith.width;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
const Nexus*nex; const Nexus*nex;
nex = net->pin_Result(idx).nexus(); nex = net->pin_Result().nexus();
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.q[idx] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[idx], obj, 0, nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
IVL_DR_STRONG, IVL_DR_STRONG);
if (idx < net->width_a()) { nex = net->pin_DataA().nexus();
nex = net->pin_DataA(idx).nexus();
assert(nex);
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.a = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0, nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
IVL_DR_HiZ, IVL_DR_HiZ);
} else if (obj->u_.arith.signed_flag) { nex = net->pin_DataB().nexus();
/* If this is signed divide, sign extend the perand. */
nex = net->pin_DataA(net->width_a()-1).nexus();
assert(nex);
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie(); obj->u_.arith.b = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0, nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
IVL_DR_HiZ, IVL_DR_HiZ);
} else {
/* Unsigned divide: pad the operand. */
obj->u_.arith.a[idx] = 0;
}
if (idx < net->width_b()) {
nex = net->pin_DataB(idx).nexus();
assert(nex);
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 {
obj->u_.arith.b[idx] = 0;
}
}
#else
cerr << "XXXX t-dll.cc: Forgot how to handle lpm_divide." << endl;
#endif
scope_add_lpm(obj->scope, obj); scope_add_lpm(obj->scope, obj);
} }
@ -2222,6 +2168,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/* /*
* $Log: t-dll.cc,v $ * $Log: t-dll.cc,v $
* Revision 1.142 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.141 2005/02/13 01:15:07 steve * Revision 1.141 2005/02/13 01:15:07 steve
* Replace supply nets with wires connected to pullup/down supply devices. * Replace supply nets with wires connected to pullup/down supply devices.
* *

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: t-dll.h,v 1.121 2005/02/12 06:25:40 steve Exp $" #ident "$Id: t-dll.h,v 1.122 2005/02/19 02:43:39 steve Exp $"
#endif #endif
# include "target.h" # include "target.h"
@ -325,9 +325,7 @@ struct ivl_lpm_s {
unsigned width; unsigned width;
unsigned select; unsigned select;
unsigned signed_flag :1; unsigned signed_flag :1;
ivl_nexus_t*q; ivl_nexus_t q, d, s;
ivl_nexus_t*d;
ivl_nexus_t*s;
} shift; } shift;
struct ivl_lpm_arith_s { struct ivl_lpm_arith_s {
@ -687,6 +685,9 @@ struct ivl_variable_s {
/* /*
* $Log: t-dll.h,v $ * $Log: t-dll.h,v $
* Revision 1.122 2005/02/19 02:43:39 steve
* Support shifts and divide.
*
* Revision 1.121 2005/02/12 06:25:40 steve * Revision 1.121 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors. * Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions, * Generate NetMux devices from ternary expressions,

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.110 2005/02/13 01:15:07 steve Exp $" #ident "$Id: stub.c,v 1.111 2005/02/19 02:43:39 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -270,6 +270,16 @@ static void show_lpm_add(ivl_lpm_t net)
show_lpm_arithmetic_pins(net); show_lpm_arithmetic_pins(net);
} }
static void show_lpm_divide(ivl_lpm_t net)
{
unsigned width = ivl_lpm_width(net);
fprintf(out, " LPM_DIVIDE %s: <width=%u>\n",
ivl_lpm_basename(net), width);
show_lpm_arithmetic_pins(net);
}
/* IVL_LPM_CMP_EEQ /* IVL_LPM_CMP_EEQ
* This LPM node supports two-input compare. The output width is * This LPM node supports two-input compare. The output width is
* actually always 1, the lpm_width is the expected width of the inputs. * actually always 1, the lpm_width is the expected width of the inputs.
@ -430,6 +440,36 @@ static void show_lpm_mux(ivl_lpm_t net)
} }
} }
static void show_lpm_part(ivl_lpm_t net)
{
unsigned width = ivl_lpm_width(net);
unsigned base = ivl_lpm_base(net);
const char*part_type_string = "";
switch (ivl_lpm_type(net)) {
case IVL_LPM_PART_VP:
part_type_string = "VP";
break;
case IVL_LPM_PART_PV:
part_type_string = "PV";
break;
default:
break;
}
fprintf(out, " LPM_PART_%s %s: <width=%u, base=%u, signed=%d>\n",
part_type_string, ivl_lpm_basename(net),
width, base, ivl_lpm_signed(net));
fprintf(out, " O: %s\n", ivl_nexus_name(ivl_lpm_q(net,0)));
fprintf(out, " I: %s\n", ivl_nexus_name(ivl_lpm_data(net,0)));
/* The compiler must assure that the base plus the part select
width fits within the input to the part select. */
if (width_of_nexus(ivl_lpm_data(net,0)) < (width+base)) {
fprintf(out, " ERROR: Part select is out of range.\n");
stub_errors += 1;
}
}
/* /*
* The reduction operators have similar characteristics and are * The reduction operators have similar characteristics and are
@ -524,25 +564,9 @@ static void show_lpm(ivl_lpm_t net)
show_lpm_add(net); show_lpm_add(net);
break; break;
case IVL_LPM_DIVIDE: { case IVL_LPM_DIVIDE:
fprintf(out, " LPM_DIVIDE %s: <width=%u %s>\n", show_lpm_divide(net);
ivl_lpm_basename(net), width,
ivl_lpm_signed(net)? "signed" : "unsigned");
for (idx = 0 ; idx < width ; idx += 1)
fprintf(out, " Q %u: %s\n", idx,
ivl_nexus_name(ivl_lpm_q(net, idx)));
for (idx = 0 ; idx < width ; idx += 1) {
ivl_nexus_t nex = ivl_lpm_data(net, idx);
fprintf(out, " Data A %u: %s\n", idx,
nex? ivl_nexus_name(nex) : "");
}
for (idx = 0 ; idx < width ; idx += 1) {
ivl_nexus_t nex = ivl_lpm_datab(net, idx);
fprintf(out, " Data B %u: %s\n", idx,
nex? ivl_nexus_name(nex) : "");
}
break; break;
}
case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EEQ:
show_lpm_cmp_eeq(net); show_lpm_cmp_eeq(net);
@ -643,23 +667,10 @@ static void show_lpm(ivl_lpm_t net)
show_lpm_mux(net); show_lpm_mux(net);
break; break;
case IVL_LPM_PART_VP: { case IVL_LPM_PART_VP:
fprintf(out, " LPM_PART_VP %s: <width=%u, base=%u, signed=%d>\n", case IVL_LPM_PART_PV:
ivl_lpm_basename(net), show_lpm_part(net);
width, ivl_lpm_base(net), ivl_lpm_signed(net));
fprintf(out, " O: %s\n", ivl_nexus_name(ivl_lpm_q(net,0)));
fprintf(out, " I: %s\n", ivl_nexus_name(ivl_lpm_data(net,0)));
break; break;
}
case IVL_LPM_PART_PV: {
fprintf(out, " LPM_PART_PV %s: <width=%u, base=%u, signed=%d>\n",
ivl_lpm_basename(net),
width, ivl_lpm_base(net), ivl_lpm_signed(net));
fprintf(out, " O: %s\n", ivl_nexus_name(ivl_lpm_q(net,0)));
fprintf(out, " I: %s\n", ivl_nexus_name(ivl_lpm_data(net,0)));
break;
}
case IVL_LPM_REPEAT: case IVL_LPM_REPEAT:
show_lpm_repeat(net); show_lpm_repeat(net);
@ -1111,6 +1122,9 @@ int target_design(ivl_design_t des)
/* /*
* $Log: stub.c,v $ * $Log: stub.c,v $
* Revision 1.111 2005/02/19 02:43:39 steve
* Support shifts and divide.
*
* Revision 1.110 2005/02/13 01:15:07 steve * Revision 1.110 2005/02/13 01:15:07 steve
* Replace supply nets with wires connected to pullup/down supply devices. * Replace supply nets with wires connected to pullup/down supply devices.
* *