Support shifts and divide.
This commit is contained in:
parent
5fe5d9184d
commit
257e1f9516
217
elab_net.cc
217
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -723,23 +723,23 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
|
|||
unsigned rwidth = lwidth;
|
||||
|
||||
if (rwidth == 0) {
|
||||
rwidth = lsig->pin_count();
|
||||
if (rsig->pin_count() > rwidth)
|
||||
rwidth = rsig->pin_count();
|
||||
rwidth = lsig->vector_width();
|
||||
if (rsig->vector_width() > rwidth)
|
||||
rwidth = rsig->vector_width();
|
||||
|
||||
lwidth = rwidth;
|
||||
}
|
||||
|
||||
if ((rwidth > lsig->pin_count()) && (rwidth > rsig->pin_count())) {
|
||||
rwidth = lsig->pin_count();
|
||||
if (rsig->pin_count() > rwidth)
|
||||
rwidth = rsig->pin_count();
|
||||
if ((rwidth > lsig->vector_width()) && (rwidth > rsig->vector_width())) {
|
||||
rwidth = lsig->vector_width();
|
||||
if (rsig->vector_width() > rwidth)
|
||||
rwidth = rsig->vector_width();
|
||||
}
|
||||
|
||||
// Create a device with the calculated dimensions.
|
||||
NetDivide*div = new NetDivide(scope, scope->local_symbol(), rwidth,
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
lsig->vector_width(),
|
||||
rsig->vector_width());
|
||||
des->add_node(div);
|
||||
|
||||
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
|
||||
// nets that are the left and right expressions.
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataB(idx), rsig->pin(idx));
|
||||
connect(div->pin_DataA(), lsig->pin(0));
|
||||
connect(div->pin_DataB(), rsig->pin(0));
|
||||
|
||||
|
||||
// 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->set_signed(div->get_signed());
|
||||
|
||||
for (unsigned idx = 0 ; idx < rwidth ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
connect(div->pin_Result(), osig->pin(0));
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
@ -1004,8 +987,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
|||
NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
|
||||
if (lsig == 0) return 0;
|
||||
|
||||
if (lsig->pin_count() > lwidth)
|
||||
lwidth = lsig->pin_count();
|
||||
if (lsig->vector_width() > lwidth)
|
||||
lwidth = lsig->vector_width();
|
||||
|
||||
bool right_flag = op_ == 'r' || 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
|
||||
is no reason in this case to create a gate at all, just
|
||||
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)) {
|
||||
assert(rval->is_defined());
|
||||
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;
|
||||
|
||||
/* 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::WIRE, lwidth);
|
||||
osig->local_flag(true);
|
||||
|
||||
NetConst*zero = new NetConst(scope, scope->local_symbol(),
|
||||
verinum::V0);
|
||||
des->add_node(zero);
|
||||
|
||||
if (op_ == 'l') {
|
||||
/* Left shift means put some zeros on the bottom
|
||||
of the vector. */
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < dist ; idx += 1)
|
||||
connect(osig->pin(idx), zero->pin(0));
|
||||
for ( ; (idx<lwidth) && ((idx-dist) < lsig->pin_count())
|
||||
; idx += 1)
|
||||
connect(osig->pin(idx), lsig->pin(idx-dist));
|
||||
for ( ; idx < lwidth ; idx += 1)
|
||||
connect(osig->pin(idx), zero->pin(0));
|
||||
/* Make the constant zero's that I'm going to pad to the
|
||||
top or bottom of the left expression. Attach a signal
|
||||
to its output so that I don't have to worry about it
|
||||
later. If the left expression is less then the
|
||||
desired width (and we are doing right shifts) then we
|
||||
can combine the expression padding with the distance
|
||||
padding to reduce nodes. */
|
||||
unsigned pad_width = dist;
|
||||
unsigned part_width = lwidth - dist;
|
||||
if (op_ == 'r' || op_ == 'R') {
|
||||
if (lsig->vector_width() < lwidth) {
|
||||
pad_width += lwidth - lsig->vector_width();
|
||||
part_width -= lwidth - lsig->vector_width();
|
||||
}
|
||||
} else {
|
||||
|
||||
} else if (op_ == 'R') {
|
||||
/* Signed right shift. */
|
||||
unsigned idx;
|
||||
unsigned keep = lsig->pin_count()-dist;
|
||||
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));
|
||||
/* The left net must be the same width as the
|
||||
result. The part select that I'm about to make relies
|
||||
on that. */
|
||||
lsig = pad_to_width(des, lsig, lwidth);
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
/* Unsigned right shift. */
|
||||
assert(op_ == 'r');
|
||||
unsigned idx;
|
||||
unsigned keep = lsig->pin_count()-dist;
|
||||
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));
|
||||
NetConst*zero_c = new NetConst(scope, scope->local_symbol(),
|
||||
verinum(verinum::V0, pad_width));
|
||||
des->add_node(zero_c);
|
||||
connect(zero->pin(0), zero_c->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;
|
||||
}
|
||||
|
||||
|
|
@ -1078,39 +1128,31 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
|||
// Make the shift device itself, and the output
|
||||
// NetNet. Connect the Result output pins to the osig signal
|
||||
NetCLShift*gate = new NetCLShift(scope, scope->local_symbol(),
|
||||
lwidth, rsig->pin_count(),
|
||||
lwidth, rsig->vector_width(),
|
||||
right_flag, signed_flag);
|
||||
des->add_node(gate);
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, lwidth);
|
||||
osig->local_flag(true);
|
||||
osig->set_signed(signed_flag);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lwidth ; idx += 1)
|
||||
connect(osig->pin(idx), gate->pin_Result(idx));
|
||||
connect(osig->pin(0), gate->pin_Result());
|
||||
|
||||
// Connect the lsig (the left expression) to the Data input,
|
||||
// and pad it if necessary with constant zeros.
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(lsig->pin(idx), gate->pin_Data(idx));
|
||||
|
||||
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));
|
||||
}
|
||||
assert(lsig->vector_width() == lwidth);
|
||||
connect(lsig->pin(0), gate->pin_Data());
|
||||
|
||||
// Connect the rsig (the shift amount expression) to the
|
||||
// Distance input.
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(rsig->pin(idx), gate->pin_Distance(idx));
|
||||
connect(rsig->pin(0), gate->pin_Distance());
|
||||
|
||||
des->add_node(gate);
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Elaborate LPM_SHIFT: width="<<gate->width()
|
||||
<< ", swidth="<< gate->width_dist() << endl;
|
||||
}
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
|
@ -2462,6 +2504,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -94,7 +94,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
assert(lval->pin_count() == 1);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -2938,6 +2938,9 @@ Design* elaborate(list<perm_string>roots)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* distinguish between single port namy instances, and single instances many sub-ports.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -371,16 +371,13 @@ NetNet* NetEBDiv::synthesize(Design*des)
|
|||
case '/': {
|
||||
NetDivide*div = new NetDivide(scope, scope->local_symbol(),
|
||||
expr_width(),
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
lsig->vector_width(),
|
||||
rsig->vector_width());
|
||||
des->add_node(div);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
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));
|
||||
connect(div->pin_DataA(), lsig->pin(0));
|
||||
connect(div->pin_DataB(), rsig->pin(0));
|
||||
connect(div->pin_Result(),osig->pin(0));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -562,20 +559,18 @@ NetNet* NetEBShift::synthesize(Design*des)
|
|||
|
||||
assert(op() == 'l');
|
||||
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
||||
osig->pin_count(),
|
||||
rsig->pin_count(),
|
||||
osig->vector_width(),
|
||||
rsig->vector_width(),
|
||||
right_flag, signed_flag);
|
||||
dev->set_line(*this);
|
||||
des->add_node(dev);
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
|
||||
connect(dev->pin_Result(idx), osig->pin(idx));
|
||||
connect(dev->pin_Result(), osig->pin(0));
|
||||
|
||||
assert(lsig->pin_count() >= dev->width());
|
||||
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
|
||||
connect(dev->pin_Data(idx), lsig->pin(idx));
|
||||
assert(lsig->vector_width() == dev->width());
|
||||
connect(dev->pin_Data(), lsig->pin(0));
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->width_dist() ; idx += 1)
|
||||
connect(dev->pin_Distance(idx), rsig->pin(idx));
|
||||
connect(dev->pin_Distance(), rsig->pin(0));
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
|
@ -850,6 +845,9 @@ NetNet* NetESignal::synthesize(Design*des)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
|
|
|
|||
18
ivl_target.h
18
ivl_target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
#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
|
||||
* 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)
|
||||
* The multiply takes two inputs and generates an output. Unlike other
|
||||
* 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
|
||||
* repeated to get the desired width. The ivl core assures that the
|
||||
* 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) */
|
||||
|
|
@ -858,7 +869,7 @@ extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
|||
/* IVL_LPM_FF IVL_LPM_RAM */
|
||||
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_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);
|
||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
|
||||
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
||||
|
|
@ -1516,6 +1527,9 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle bit selects in l-values to assignments.
|
||||
*
|
||||
|
|
|
|||
158
netlist.cc
158
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -842,39 +842,23 @@ const Link& NetAddSub::pin_Result() const
|
|||
|
||||
/*
|
||||
* The pinout for the NetCLShift is:
|
||||
* 0 -- Direction
|
||||
* 1 -- Underflow
|
||||
* 2 -- Overflow
|
||||
* 3 -- Data(0)
|
||||
* 3+W -- Result(0)
|
||||
* 3+2W -- Distance(0)
|
||||
* 0 -- Result
|
||||
* 1 -- Data
|
||||
* 2 -- Distance
|
||||
*/
|
||||
NetCLShift::NetCLShift(NetScope*s, perm_string n,
|
||||
unsigned width, unsigned width_dist,
|
||||
bool right_flag, bool signed_flag)
|
||||
: NetNode(s, n, 3+2*width+width_dist),
|
||||
: NetNode(s, n, 3),
|
||||
width_(width), width_dist_(width_dist),
|
||||
right_flag_(right_flag), signed_flag_(signed_flag)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name(
|
||||
perm_string::literal("Direction"), 0);
|
||||
pin(1).set_dir(Link::OUTPUT); pin(1).set_name(
|
||||
perm_string::literal("Underflow"), 0);
|
||||
pin(2).set_dir(Link::OUTPUT); pin(2).set_name(
|
||||
perm_string::literal("Overflow"), 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);
|
||||
}
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name(perm_string::literal("Result"), 0);
|
||||
pin(1).set_dir(Link::INPUT);
|
||||
pin(1).set_name(perm_string::literal("Data"), 0);
|
||||
pin(2).set_dir(Link::INPUT);
|
||||
pin(2).set_name(perm_string::literal("Distance"), 0);
|
||||
}
|
||||
|
||||
NetCLShift::~NetCLShift()
|
||||
|
|
@ -901,74 +885,36 @@ bool NetCLShift::signed_flag() const
|
|||
return signed_flag_;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Link& NetCLShift::pin_Direction()
|
||||
{
|
||||
return pin(0);
|
||||
}
|
||||
|
||||
const Link& NetCLShift::pin_Direction() const
|
||||
{
|
||||
return pin(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
Link& NetCLShift::pin_Underflow()
|
||||
Link& NetCLShift::pin_Data()
|
||||
{
|
||||
return pin(1);
|
||||
}
|
||||
|
||||
const Link& NetCLShift::pin_Underflow() const
|
||||
const Link& NetCLShift::pin_Data() const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
const Link& NetCLShift::pin_Overflow() const
|
||||
const Link& NetCLShift::pin_Distance() const
|
||||
{
|
||||
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)
|
||||
: 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,
|
||||
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)
|
||||
{
|
||||
unsigned p = 0;
|
||||
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
|
||||
pin(p).set_dir(Link::OUTPUT);
|
||||
pin(p).set_name(perm_string::literal("Result"), idx);
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) {
|
||||
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);
|
||||
}
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name(perm_string::literal("Result"), 0);
|
||||
pin(1).set_dir(Link::INPUT);
|
||||
pin(1).set_name(perm_string::literal("DataA"), 0);
|
||||
pin(2).set_dir(Link::INPUT);
|
||||
pin(2).set_name(perm_string::literal("DataB"), 0);
|
||||
}
|
||||
|
||||
NetDivide::~NetDivide()
|
||||
|
|
@ -1163,40 +1102,34 @@ bool NetDivide::get_signed() const
|
|||
return signed_flag_;
|
||||
}
|
||||
|
||||
Link& NetDivide::pin_Result(unsigned idx)
|
||||
Link& NetDivide::pin_Result()
|
||||
{
|
||||
assert(idx < width_r_);
|
||||
return pin(idx);
|
||||
return pin(0);
|
||||
}
|
||||
|
||||
const Link& NetDivide::pin_Result(unsigned idx) const
|
||||
const Link& NetDivide::pin_Result() const
|
||||
{
|
||||
assert(idx < width_r_);
|
||||
return pin(idx);
|
||||
return pin(0);
|
||||
}
|
||||
|
||||
Link& NetDivide::pin_DataA(unsigned idx)
|
||||
Link& NetDivide::pin_DataA()
|
||||
{
|
||||
assert(idx < width_a_);
|
||||
return pin(idx+width_r_);
|
||||
return pin(1);
|
||||
}
|
||||
|
||||
const Link& NetDivide::pin_DataA(unsigned idx) const
|
||||
const Link& NetDivide::pin_DataA() const
|
||||
{
|
||||
assert(idx < width_a_);
|
||||
return pin(idx+width_r_);
|
||||
return pin(1);
|
||||
}
|
||||
|
||||
Link& NetDivide::pin_DataB(unsigned idx)
|
||||
Link& NetDivide::pin_DataB()
|
||||
{
|
||||
assert(idx < width_b_);
|
||||
return pin(idx+width_r_+width_a_);
|
||||
return pin(2);
|
||||
}
|
||||
|
||||
const Link& NetDivide::pin_DataB(unsigned idx) const
|
||||
const Link& NetDivide::pin_DataB() const
|
||||
{
|
||||
assert(idx < width_b_);
|
||||
return pin(idx+width_r_+width_a_);
|
||||
return pin(2);
|
||||
}
|
||||
|
||||
NetMult::NetMult(NetScope*sc, perm_string n, unsigned wr,
|
||||
|
|
@ -2258,6 +2191,9 @@ const NetProc*NetTaskDef::proc() const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
|
|
|
|||
35
netlist.h
35
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -506,19 +506,13 @@ class NetCLShift : public NetNode {
|
|||
bool right_flag() const;
|
||||
bool signed_flag() const;
|
||||
|
||||
Link& pin_Direction();
|
||||
Link& pin_Underflow();
|
||||
Link& pin_Overflow();
|
||||
Link& pin_Data(unsigned idx);
|
||||
Link& pin_Result(unsigned idx);
|
||||
Link& pin_Distance(unsigned idx);
|
||||
Link& pin_Data();
|
||||
Link& pin_Result();
|
||||
Link& pin_Distance();
|
||||
|
||||
const Link& pin_Direction() const;
|
||||
const Link& pin_Underflow() const;
|
||||
const Link& pin_Overflow() const;
|
||||
const Link& pin_Data(unsigned idx) const;
|
||||
const Link& pin_Result(unsigned idx) const;
|
||||
const Link& pin_Distance(unsigned idx) const;
|
||||
const Link& pin_Data() const;
|
||||
const Link& pin_Result() const;
|
||||
const Link& pin_Distance() const;
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
|
|
@ -639,13 +633,13 @@ class NetDivide : public NetNode {
|
|||
void set_signed(bool);
|
||||
bool get_signed() const;
|
||||
|
||||
Link& pin_DataA(unsigned idx);
|
||||
Link& pin_DataB(unsigned idx);
|
||||
Link& pin_Result(unsigned idx);
|
||||
Link& pin_DataA();
|
||||
Link& pin_DataB();
|
||||
Link& pin_Result();
|
||||
|
||||
const Link& pin_DataA(unsigned idx) const;
|
||||
const Link& pin_DataB(unsigned idx) const;
|
||||
const Link& pin_Result(unsigned idx) const;
|
||||
const Link& pin_DataA() const;
|
||||
const Link& pin_DataB() const;
|
||||
const Link& pin_Result() const;
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
|
|
@ -3420,6 +3414,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
|
|
|
|||
24
t-dll-api.cc
24
t-dll-api.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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_SHIFTR:
|
||||
assert(idx < net->u_.shift.width);
|
||||
return net->u_.shift.d[idx];
|
||||
assert(idx <= 1);
|
||||
if (idx == 0)
|
||||
return net->u_.shift.d;
|
||||
else
|
||||
return net->u_.shift.s;
|
||||
|
||||
case IVL_LPM_FF:
|
||||
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_SHIFTR:
|
||||
assert(idx < net->u_.shift.width);
|
||||
return net->u_.shift.q[idx];
|
||||
assert(idx == 0);
|
||||
return net->u_.shift.q;
|
||||
|
||||
case IVL_LPM_UFUNC:
|
||||
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);
|
||||
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:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -996,9 +994,6 @@ extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
|
|||
return net->u_.ff.swid;
|
||||
case IVL_LPM_MUX:
|
||||
return net->u_.mux.swid;
|
||||
case IVL_LPM_SHIFTL:
|
||||
case IVL_LPM_SHIFTR:
|
||||
return net->u_.shift.select;
|
||||
case IVL_LPM_CONCAT:
|
||||
return net->u_.concat.inputs;
|
||||
default:
|
||||
|
|
@ -1992,6 +1987,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
|
|
|
|||
111
t-dll.cc
111
t-dll.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1211,46 +1211,26 @@ void dll_target::lpm_clshift(const NetCLShift*net)
|
|||
|
||||
obj->u_.shift.width = net->width();
|
||||
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;
|
||||
const Nexus*nex;
|
||||
|
||||
for (unsigned idx = 0 ; idx < net->width() ; idx += 1) {
|
||||
const Nexus*nex;
|
||||
nex = net->pin_Result().nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
nex = net->pin_Result(idx).nexus();
|
||||
assert(nex && nex->t_cookie());
|
||||
obj->u_.shift.q = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.shift.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
|
||||
obj->u_.shift.q[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.shift.q[idx], obj, 0,
|
||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
}
|
||||
nex = net->pin_Data().nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
for (unsigned idx = 0 ; idx < net->width() ; idx += 1) {
|
||||
const Nexus*nex;
|
||||
obj->u_.shift.d = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.shift.d, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
|
||||
nex = net->pin_Data(idx).nexus();
|
||||
assert(nex && nex->t_cookie());
|
||||
nex = net->pin_Distance().nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.shift.d[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.shift.q[idx], obj, 0,
|
||||
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < net->width_dist() ; idx += 1) {
|
||||
const Nexus*nex;
|
||||
|
||||
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);
|
||||
}
|
||||
obj->u_.shift.s = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.shift.s, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
|
||||
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.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();
|
||||
assert(nex->t_cookie());
|
||||
nex = net->pin_Result().nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.arith.q[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.q[idx], obj, 0,
|
||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
|
||||
if (idx < net->width_a()) {
|
||||
nex = net->pin_DataA(idx).nexus();
|
||||
assert(nex);
|
||||
assert(nex->t_cookie());
|
||||
nex = net->pin_DataA().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);
|
||||
obj->u_.arith.a = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
|
||||
} else if (obj->u_.arith.signed_flag) {
|
||||
/* If this is signed divide, sign extend the perand. */
|
||||
nex = net->pin_DataA(net->width_a()-1).nexus();
|
||||
assert(nex);
|
||||
assert(nex->t_cookie());
|
||||
nex = net->pin_DataB().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);
|
||||
|
||||
} else {
|
||||
/* Unsigned divide: pad the operand. */
|
||||
obj->u_.arith.a[idx] = 0;
|
||||
}
|
||||
obj->u_.arith.b = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -2222,6 +2168,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Replace supply nets with wires connected to pullup/down supply devices.
|
||||
*
|
||||
|
|
|
|||
9
t-dll.h
9
t-dll.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -325,9 +325,7 @@ struct ivl_lpm_s {
|
|||
unsigned width;
|
||||
unsigned select;
|
||||
unsigned signed_flag :1;
|
||||
ivl_nexus_t*q;
|
||||
ivl_nexus_t*d;
|
||||
ivl_nexus_t*s;
|
||||
ivl_nexus_t q, d, s;
|
||||
} shift;
|
||||
|
||||
struct ivl_lpm_arith_s {
|
||||
|
|
@ -687,6 +685,9 @@ struct ivl_variable_s {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -270,6 +270,16 @@ static void show_lpm_add(ivl_lpm_t 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
|
||||
* This LPM node supports two-input compare. The output width is
|
||||
* 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
|
||||
|
|
@ -524,25 +564,9 @@ static void show_lpm(ivl_lpm_t net)
|
|||
show_lpm_add(net);
|
||||
break;
|
||||
|
||||
case IVL_LPM_DIVIDE: {
|
||||
fprintf(out, " LPM_DIVIDE %s: <width=%u %s>\n",
|
||||
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;
|
||||
}
|
||||
case IVL_LPM_DIVIDE:
|
||||
show_lpm_divide(net);
|
||||
break;
|
||||
|
||||
case IVL_LPM_CMP_EEQ:
|
||||
show_lpm_cmp_eeq(net);
|
||||
|
|
@ -643,23 +667,10 @@ static void show_lpm(ivl_lpm_t net)
|
|||
show_lpm_mux(net);
|
||||
break;
|
||||
|
||||
case IVL_LPM_PART_VP: {
|
||||
fprintf(out, " LPM_PART_VP %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_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_PART_VP:
|
||||
case IVL_LPM_PART_PV:
|
||||
show_lpm_part(net);
|
||||
break;
|
||||
|
||||
case IVL_LPM_REPEAT:
|
||||
show_lpm_repeat(net);
|
||||
|
|
@ -1111,6 +1122,9 @@ int target_design(ivl_design_t des)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Replace supply nets with wires connected to pullup/down supply devices.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue