Restructure NetMux devices to pass vectors.

Generate NetMux devices from ternary expressions,
 Reduce NetMux devices to bufif when appropriate.
This commit is contained in:
steve 2005-02-12 06:25:40 +00:00
parent eca4f4fa97
commit d74177634c
10 changed files with 236 additions and 247 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-20035 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -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.49 2005/01/16 04:20:32 steve Exp $" #ident "$Id: cprop.cc,v 1.50 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -779,29 +779,52 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
NetMux with an array of BUFIF1 devices, with the enable NetMux with an array of BUFIF1 devices, with the enable
connected to the select input. */ connected to the select input. */
bool flag = true; bool flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) { if (! obj->pin_Data(0).nexus()->drivers_constant()) {
flag = false; flag = false;
break;
} }
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) { if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
flag = false; flag = false;
break;
}
} }
if (flag) { if (flag) {
NetScope*scope = obj->scope(); NetScope*scope = obj->scope();
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
NetLogic*tmp = new NetLogic(obj->scope(), NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(), scope->local_symbol(),
3, NetLogic::BUFIF1, 1); 3, NetLogic::BUFIF1, obj->width());
connect(obj->pin_Result(idx), tmp->pin(0));
connect(obj->pin_Data(idx,1), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp); des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
wide. Connect the select directly to the
enable. */
connect(obj->pin_Sel(), tmp->pin(2));
} else {
/* General case that the expression is arbitrarily
wide. Replicate the enable signal (which we
assume is 1 bit wide) to match the expression,
and connect the enable vector to the enable
input of the gate. */
NetReplicate*rtmp = new NetReplicate(scope,
scope->local_symbol(),
obj->width(),
obj->width());
des->add_node(rtmp);
connect(obj->pin_Sel(), rtmp->pin(1));
connect(tmp->pin(2), rtmp->pin(0));
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
rsig->local_flag(true);
connect(tmp->pin(2), rsig->pin(0));
} }
count += 1; count += 1;
@ -809,33 +832,29 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
return; return;
} }
/* If instead the second input is all constant Vz, replace the /* If instead the second input is all constant Vz, replace the
NetMux with an array of BUFIF0 devices. */ NetMux with an array of BUFIF0 devices. */
flag = true; flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) { if (! obj->pin_Data(1).nexus()->drivers_constant()) {
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
flag = false; flag = false;
break;
} }
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) { if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
flag = false; flag = false;
break;
}
} }
if (flag) { if (flag) {
NetScope*scope = obj->scope(); NetScope*scope = obj->scope();
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
NetLogic*tmp = new NetLogic(obj->scope(), NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(), scope->local_symbol(),
3, NetLogic::BUFIF0, 1); 3, NetLogic::BUFIF0, obj->width());
connect(obj->pin_Result(idx), tmp->pin(0)); connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(idx,0), tmp->pin(1)); connect(obj->pin_Data(0), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2)); connect(obj->pin_Sel(), tmp->pin(2));
des->add_node(tmp); des->add_node(tmp);
}
count += 1; count += 1;
delete obj; delete obj;
@ -961,6 +980,11 @@ void cprop(Design*des)
/* /*
* $Log: cprop.cc,v $ * $Log: cprop.cc,v $
* Revision 1.50 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.49 2005/01/16 04:20:32 steve * Revision 1.49 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors. * Implement LPM_COMPARE nodes as two-input vector functors.
* *

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.150 2005/02/03 04:56:20 steve Exp $" #ident "$Id: elab_net.cc,v 1.151 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1408,7 +1408,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
if (sig_width > max_width_by_sel) if (sig_width > max_width_by_sel)
sig_width = max_width_by_sel; sig_width = max_width_by_sel;
} }
#if 0
NetMux*mux = new NetMux(scope, scope->local_symbol(), 1, NetMux*mux = new NetMux(scope, scope->local_symbol(), 1,
sig_width, sel->pin_count()); sig_width, sel->pin_count());
@ -1438,6 +1438,12 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
des->add_node(mux); des->add_node(mux);
out->local_flag(true); out->local_flag(true);
return out; return out;
#else
cerr << get_line() << ": sorry: Forgot how to implement"
<< " NetMux in elaborate_net_bitmux_." << endl;
des->errors += 1;
return 0;
#endif
} }
NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
@ -2172,9 +2178,9 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
largest condition. Normally they should be the same size, largest condition. Normally they should be the same size,
but if we do not get a size from the context, or the but if we do not get a size from the context, or the
expressions resist, we need to cope. */ expressions resist, we need to cope. */
unsigned iwidth = tru_sig->pin_count(); unsigned iwidth = tru_sig->vector_width();
if (fal_sig->pin_count() > iwidth) if (fal_sig->pin_count() > iwidth)
iwidth = fal_sig->pin_count(); iwidth = fal_sig->vector_width();
/* If the width is not passed from the context, then take the /* If the width is not passed from the context, then take the
@ -2185,23 +2191,23 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
/* If the expression has width, then generate a boolean result /* If the expression has width, then generate a boolean result
by connecting an OR gate to calculate the truth value of by connecting an OR gate to calculate the truth value of
the result. In the end, the result needs to be a single bit. */ the result. In the end, the result needs to be a single bit. */
if (expr_sig->pin_count() > 1) { if (expr_sig->vector_width() > 1) {
NetLogic*log = new NetLogic(scope, scope->local_symbol(), NetUReduce*log = new NetUReduce(scope, scope->local_symbol(),
expr_sig->pin_count()+1, NetUReduce::OR,
NetLogic::OR, 1); expr_sig->vector_width());
for (unsigned idx = 0; idx < expr_sig->pin_count(); idx += 1) log->set_line(*this);
connect(log->pin(idx+1), expr_sig->pin(idx)); des->add_node(log);
connect(log->pin(1), expr_sig->pin(0));
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1); NetNet::IMPLICIT, 1);
tmp->local_flag(true); tmp->local_flag(true);
connect(tmp->pin(0), log->pin(0)); connect(log->pin(0), tmp->pin(0));
des->add_node(log);
expr_sig = tmp; expr_sig = tmp;
} }
assert(expr_sig->pin_count() == 1); assert(expr_sig->vector_width() == 1);
/* This is the width of the LPM_MUX device that I'm about to /* This is the width of the LPM_MUX device that I'm about to
create. It may be smaller then the desired output, but I'll create. It may be smaller then the desired output, but I'll
@ -2217,10 +2223,10 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
NetNet::WIRE, width); NetNet::WIRE, width);
sig->local_flag(true); sig->local_flag(true);
if (fal_sig->pin_count() < dwidth) if (fal_sig->vector_width() < dwidth)
fal_sig = pad_to_width(des, fal_sig, dwidth); fal_sig = pad_to_width(des, fal_sig, dwidth);
if (tru_sig->pin_count() < dwidth) if (tru_sig->vector_width() < dwidth)
tru_sig = pad_to_width(des, tru_sig, dwidth); tru_sig = pad_to_width(des, tru_sig, dwidth);
@ -2232,13 +2238,11 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
(true) connected to tru_sig. */ (true) connected to tru_sig. */
NetMux*mux = new NetMux(scope, scope->local_symbol(), dwidth, 2, 1); NetMux*mux = new NetMux(scope, scope->local_symbol(), dwidth, 2, 1);
connect(mux->pin_Sel(0), expr_sig->pin(0)); connect(mux->pin_Sel(), expr_sig->pin(0));
/* Connect the data inputs. */ /* Connect the data inputs. */
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) { connect(mux->pin_Data(0), fal_sig->pin(0));
connect(mux->pin_Data(idx,0), fal_sig->pin(idx)); connect(mux->pin_Data(1), tru_sig->pin(0));
connect(mux->pin_Data(idx,1), tru_sig->pin(idx));
}
/* If there are non-zero output delays, then create bufz /* If there are non-zero output delays, then create bufz
devices to carry the propagation delays. Otherwise, just devices to carry the propagation delays. Otherwise, just
@ -2246,38 +2250,27 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
if (rise || fall || decay) { if (rise || fall || decay) {
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, dwidth); NetNet::WIRE, dwidth);
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
NetBUFZ*tmpz = new NetBUFZ(scope, scope->local_symbol(), 1); NetBUFZ*tmpz = new NetBUFZ(scope, scope->local_symbol(), dwidth);
tmpz->rise_time(rise); tmpz->rise_time(rise);
tmpz->fall_time(fall); tmpz->fall_time(fall);
tmpz->decay_time(decay); tmpz->decay_time(decay);
tmpz->pin(0).drive0(drive0); tmpz->pin(0).drive0(drive0);
tmpz->pin(0).drive1(drive1); tmpz->pin(0).drive1(drive1);
connect(mux->pin_Result(idx), tmp->pin(idx)); connect(mux->pin_Result(), tmp->pin(0));
connect(tmp->pin(idx), tmpz->pin(1)); connect(tmp->pin(0), tmpz->pin(1));
connect(sig->pin(idx), tmpz->pin(0)); connect(sig->pin(0), tmpz->pin(0));
des->add_node(tmpz); des->add_node(tmpz);
}
} else { } else {
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) { connect(mux->pin_Result(), sig->pin(0));
connect(mux->pin_Result(idx), sig->pin(idx));
}
} }
/* If the MUX device result is too narrow to fill out the /* If the MUX device result is too narrow to fill out the
desired result, pad with zeros by creating a NetConst device. */ desired result, pad with zeros... */
assert(dwidth == width);
if (dwidth < width) {
verinum vpad (verinum::V0, width-dwidth);
NetConst*pad = new NetConst(scope, scope->local_symbol(), vpad);
des->add_node(pad);
for (unsigned idx = dwidth ; idx < width ; idx += 1)
connect(sig->pin(idx), pad->pin(idx-dwidth));
}
des->add_node(mux); des->add_node(mux);
@ -2469,6 +2462,11 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $Log: elab_net.cc,v $
* Revision 1.151 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.150 2005/02/03 04:56:20 steve * Revision 1.150 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes. * laborate reduction gates into LPM_RED_ nodes.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2004 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -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.62 2005/01/28 05:39:33 steve Exp $" #ident "$Id: expr_synth.cc,v 1.63 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -789,7 +789,7 @@ NetNet* NetETernary::synthesize(Design *des)
perm_string path = csig->scope()->local_symbol(); perm_string path = csig->scope()->local_symbol();
assert(csig->pin_count() == 1); assert(csig->vector_width() == 1);
unsigned width=expr_width(); unsigned width=expr_width();
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width); NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width);
@ -799,18 +799,16 @@ NetNet* NetETernary::synthesize(Design *des)
tsig = pad_to_width(des, tsig, width); tsig = pad_to_width(des, tsig, width);
fsig = pad_to_width(des, fsig, width); fsig = pad_to_width(des, fsig, width);
assert(width <= tsig->pin_count()); assert(width <= tsig->vector_width());
assert(width <= fsig->pin_count()); assert(width <= fsig->vector_width());
perm_string oname = csig->scope()->local_symbol(); perm_string oname = csig->scope()->local_symbol();
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1); NetMux *mux = new NetMux(csig->scope(), oname, width, 2, width);
for (unsigned idx = 0 ; idx < width; idx += 1) { connect(tsig->pin(0), mux->pin_Data(1));
connect(tsig->pin(idx), mux->pin_Data(idx, 1)); connect(fsig->pin(0), mux->pin_Data(0));
connect(fsig->pin(idx), mux->pin_Data(idx, 0)); connect(osig->pin(0), mux->pin_Result());
connect(osig->pin(idx), mux->pin_Result(idx)); connect(csig->pin(0), mux->pin_Sel());
}
des->add_node(mux); des->add_node(mux);
connect(csig->pin(0), mux->pin_Sel(0));
return osig; return osig;
} }
@ -852,6 +850,11 @@ NetNet* NetESignal::synthesize(Design*des)
/* /*
* $Log: expr_synth.cc,v $ * $Log: expr_synth.cc,v $
* Revision 1.63 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.62 2005/01/28 05:39:33 steve * Revision 1.62 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT. * Simplified NetMult and IVL_LPM_MULT.
* *

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.139 2005/02/08 00:12:36 steve Exp $" #ident "$Id: ivl_target.h,v 1.140 2005/02/12 06:25:40 steve Exp $"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -807,6 +807,17 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* magnitude compare, the signedness does matter. In any case, the * magnitude compare, the signedness does matter. In any case, the
* result of the compare is always unsigned. * result of the compare is always unsigned.
* *
* - Mux Device (IVL_LPM_MUX)
* The MUX device has a q output, a select input, and a number of data
* inputs. The ivl_lpm_q output and the ivl_lpm_data inputs all have
* the width from the ivl_lpm_width() method. The Select input, from
* ivl_lpm_select, has the width ivl_lpm_selects().
*
* The ivl_lpm_data() method returns the inputs of the MUX device. The
* ivl_lpm_size() method returns the number of data inputs there
* are. All the data inputs have the same width, the width of the
* ivl_lpm_q output.
*
* - Reduction operators (IVL_LPM_RE_*) * - Reduction operators (IVL_LPM_RE_*)
* These devices have one input, a vector, and generate a single bit * These devices have one input, a vector, and generate a single bit
* result. The width from the ivl_lpm_width is the width of the input * result. The width from the ivl_lpm_width is the width of the input
@ -843,11 +854,11 @@ 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_RAM IVL_LPM_SUB */ IVL_LPM_MUX IVL_LPM_RAM 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 */
/* IVL_LPM_MUX IVL_LPM_UFUNC */
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);
/* IVL_LPM_UFUNC */
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx); extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
/* IVL_LPM_UFUNC */ /* IVL_LPM_UFUNC */
extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx); extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx);
@ -1489,6 +1500,11 @@ _END_DECL
/* /*
* $Log: ivl_target.h,v $ * $Log: ivl_target.h,v $
* Revision 1.140 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.139 2005/02/08 00:12:36 steve * Revision 1.139 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support. * Add the NetRepeat node, and code generator support.
* *

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.236 2005/02/08 00:12:36 steve Exp $" #ident "$Id: netlist.cc,v 1.237 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1274,33 +1274,24 @@ const Link& NetMult::pin_DataB() const
/* /*
* The NetMux class represents an LPM_MUX device. The pinout is assigned * The NetMux class represents an LPM_MUX device. The pinout is assigned
* like so: * like so:
* 0 -- Aclr (optional) * 0 -- Result
* 1 -- Clock (optional) * 1 -- Sel
* 2 -- Result[0] * 2+N -- Data[N] (N is the size of the mux)
* 2+N -- Result[N]
*/ */
NetMux::NetMux(NetScope*s, perm_string n, NetMux::NetMux(NetScope*s, perm_string n,
unsigned wi, unsigned si, unsigned sw) unsigned wi, unsigned si, unsigned sw)
: NetNode(s, n, 2+wi+sw+wi*si), : NetNode(s, n, 2+si),
width_(wi), size_(si), swidth_(sw) width_(wi), size_(si), swidth_(sw)
{ {
pin(0).set_dir(Link::INPUT); pin(0).set_name(perm_string::literal("Aclr"), 0); pin(0).set_dir(Link::OUTPUT);
pin(1).set_dir(Link::INPUT); pin(1).set_name(perm_string::literal("Clock"), 0); pin(0).set_name(perm_string::literal("Q"), 0);
pin(1).set_dir(Link::INPUT);
pin(1).set_name(perm_string::literal("Sel"), 0);
for (unsigned idx = 0 ; idx < width_ ; idx += 1) { for (unsigned idx = 0 ; idx < size_ ; idx += 1) {
pin_Result(idx).set_dir(Link::OUTPUT); pin_Data(idx).set_dir(Link::INPUT);
pin_Result(idx).set_name(perm_string::literal("Result"), idx); pin_Data(idx).set_name(perm_string::literal("D"), idx);
for (unsigned jdx = 0 ; jdx < size_ ; jdx += 1) {
pin_Data(idx,jdx).set_dir(Link::INPUT);
pin_Data(idx,jdx).set_name(perm_string::literal("Data"), jdx*width_+idx);
}
}
for (unsigned idx = 0 ; idx < swidth_ ; idx += 1) {
pin_Sel(idx).set_dir(Link::INPUT);
pin_Sel(idx).set_name(perm_string::literal("Sel"), idx);
} }
} }
@ -1323,62 +1314,36 @@ unsigned NetMux::sel_width() const
return swidth_; return swidth_;
} }
Link& NetMux::pin_Aclr() Link& NetMux::pin_Result()
{ {
return pin(0); return pin(0);
} }
const Link& NetMux::pin_Aclr() const const Link& NetMux::pin_Result() const
{ {
return pin(0); return pin(0);
} }
Link& NetMux::pin_Clock() Link& NetMux::pin_Sel()
{ {
return pin(1); return pin(1);
} }
const Link& NetMux::pin_Clock() const const Link& NetMux::pin_Sel() const
{ {
return pin(1); return pin(1);
} }
Link& NetMux::pin_Result(unsigned w) Link& NetMux::pin_Data(unsigned s)
{ {
assert(w < width_);
return pin(2+w);
}
const Link& NetMux::pin_Result(unsigned w) const
{
assert(w < width_);
return pin(2+w);
}
Link& NetMux::pin_Sel(unsigned w)
{
assert(w < swidth_);
return pin(2+width_+w);
}
const Link& NetMux::pin_Sel(unsigned w) const
{
assert(w < swidth_);
return pin(2+width_+w);
}
Link& NetMux::pin_Data(unsigned w, unsigned s)
{
assert(w < width_);
assert(s < size_); assert(s < size_);
return pin(2+width_+swidth_+s*width_+w); return pin(2+s);
} }
const Link& NetMux::pin_Data(unsigned w, unsigned s) const const Link& NetMux::pin_Data(unsigned s) const
{ {
assert(w < width_);
assert(s < size_); assert(s < size_);
return pin(2+width_+swidth_+s*width_+w); return pin(2+s);
} }
@ -2293,6 +2258,11 @@ const NetProc*NetTaskDef::proc() const
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.237 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.236 2005/02/08 00:12:36 steve * Revision 1.236 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support. * Add the NetRepeat node, and code generator support.
* *

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.333 2005/02/08 00:12:36 steve Exp $" #ident "$Id: netlist.h,v 1.334 2005/02/12 06:25:40 steve Exp $"
#endif #endif
/* /*
@ -864,19 +864,13 @@ class NetMux : public NetNode {
unsigned size() const; unsigned size() const;
unsigned sel_width() const; unsigned sel_width() const;
Link& pin_Aclr(); Link& pin_Result();
Link& pin_Clock(); Link& pin_Data(unsigned si);
Link& pin_Sel();
Link& pin_Result(unsigned); const Link& pin_Result() const;
Link& pin_Data(unsigned wi, unsigned si); const Link& pin_Data(unsigned) const;
Link& pin_Sel(unsigned); const Link& pin_Sel() const;
const Link& pin_Aclr() const;
const Link& pin_Clock() const;
const Link& pin_Result(unsigned) const;
const Link& pin_Data(unsigned, unsigned) const;
const Link& pin_Sel(unsigned) 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;
@ -3426,6 +3420,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.334 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.333 2005/02/08 00:12:36 steve * Revision 1.333 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support. * Add the NetRepeat node, and code generator support.
* *

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: synth2.cc,v 1.40 2004/12/11 02:31:27 steve Exp $" #ident "$Id: synth2.cc,v 1.41 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -188,6 +188,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out) const NetNet*nex_map, NetNet*nex_out)
{ {
DEBUG_SYNTH2_ENTRY("NetCase") DEBUG_SYNTH2_ENTRY("NetCase")
#if 0
unsigned cur; unsigned cur;
NetNet*esig = expr_->synthesize(des); NetNet*esig = expr_->synthesize(des);
@ -216,7 +217,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
elided. */ elided. */
map<unsigned long,unsigned long>guard2sel; map<unsigned long,unsigned long>guard2sel;
cur = 0; cur = 0;
for (unsigned idx = 0 ; idx < (1U<<esig->pin_count()) ; idx += 1) { for (unsigned idx = 0 ; idx < (1U<<esig->vector_width()) ; idx += 1) {
if ((idx & ~sel_mask) == sel_ref) { if ((idx & ~sel_mask) == sel_ref) {
guard2sel[idx] = cur; guard2sel[idx] = cur;
cur += 1; cur += 1;
@ -312,6 +313,11 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
DEBUG_SYNTH2_EXIT("NetCase", true) DEBUG_SYNTH2_EXIT("NetCase", true)
return true; return true;
#else
cerr << get_line() << ": sorry: forgot how to implement "
<< "NetCase::synth_async" << endl;
return false;
#endif
} }
bool NetCondit::synth_async(Design*des, NetScope*scope, bool NetCondit::synth_async(Design*des, NetScope*scope,
@ -360,18 +366,12 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
} }
NetMux*mux = new NetMux(scope, scope->local_symbol(), NetMux*mux = new NetMux(scope, scope->local_symbol(),
nex_out->pin_count(), 2, 1); nex_out->vector_width(), 2, 1);
connect(mux->pin_Sel(0), ssig->pin(0)); connect(mux->pin_Sel(), ssig->pin(0));
connect(mux->pin_Data(1), asig->pin(0));
for (unsigned idx = 0 ; idx < asig->pin_count() ; idx += 1) connect(mux->pin_Data(0), bsig->pin(0));
connect(mux->pin_Data(idx, 1), asig->pin(idx)); connect(nex_out->pin(0), mux->pin_Result());
for (unsigned idx = 0 ; idx < bsig->pin_count() ; idx += 1)
connect(mux->pin_Data(idx, 0), bsig->pin(idx));
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1)
connect(nex_out->pin(idx), mux->pin_Result(idx));
des->add_node(mux); des->add_node(mux);
@ -985,6 +985,11 @@ void synth2(Design*des)
/* /*
* $Log: synth2.cc,v $ * $Log: synth2.cc,v $
* Revision 1.41 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.40 2004/12/11 02:31:27 steve * Revision 1.40 2004/12/11 02:31:27 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: t-dll-api.cc,v 1.117 2005/02/08 00:12:36 steve Exp $" #ident "$Id: t-dll-api.cc,v 1.118 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -755,6 +755,10 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
else else
return net->u_.arith.b; return net->u_.arith.b;
case IVL_LPM_MUX:
assert(idx < net->u_.mux.size);
return net->u_.mux.d[idx];
case IVL_LPM_RE_AND: case IVL_LPM_RE_AND:
case IVL_LPM_RE_OR: case IVL_LPM_RE_OR:
case IVL_LPM_RE_XOR: case IVL_LPM_RE_XOR:
@ -824,10 +828,6 @@ extern "C" ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx)
{ {
assert(net); assert(net);
switch (net->type) { switch (net->type) {
case IVL_LPM_MUX:
assert(sdx < net->u_.mux.size);
assert(idx < net->u_.mux.width);
return net->u_.mux.d[sdx*net->u_.mux.width + idx];
case IVL_LPM_UFUNC: { case IVL_LPM_UFUNC: {
sdx += 1; /* skip the output port. */ sdx += 1; /* skip the output port. */
@ -919,11 +919,8 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
return net->u_.ff.q.pins[idx]; return net->u_.ff.q.pins[idx];
case IVL_LPM_MUX: case IVL_LPM_MUX:
assert(idx < net->u_.mux.width); assert(idx == 0);
if (net->u_.mux.width == 1) return net->u_.mux.q;
return net->u_.mux.q.pin;
else
return net->u_.mux.q.pins[idx];
case IVL_LPM_RE_AND: case IVL_LPM_RE_AND:
case IVL_LPM_RE_OR: case IVL_LPM_RE_OR:
@ -978,11 +975,8 @@ extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx)
return net->u_.ff.s.pins[idx]; return net->u_.ff.s.pins[idx];
case IVL_LPM_MUX: case IVL_LPM_MUX:
assert(idx < net->u_.mux.swid); assert(idx == 0);
if (net->u_.mux.swid == 1) return net->u_.mux.s;
return net->u_.mux.s.pin;
else
return net->u_.mux.s.pins[idx];
case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR: case IVL_LPM_SHIFTR:
@ -1998,6 +1992,11 @@ 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.118 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.117 2005/02/08 00:12:36 steve * Revision 1.117 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support. * Add the NetRepeat node, and code generator support.
* *

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.139 2005/02/08 00:12:36 steve Exp $" #ident "$Id: t-dll.cc,v 1.140 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1800,55 +1800,27 @@ void dll_target::lpm_mux(const NetMux*net)
const Nexus*nex; const Nexus*nex;
/* Connect the output bits. */ /* Connect the output bits. */
if (obj->u_.mux.width == 1) { nex = net->pin_Result().nexus();
nex = net->pin_Result(0).nexus();
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.mux.q.pin = (ivl_nexus_t) nex->t_cookie(); obj->u_.mux.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.mux.q.pin, obj, 0, nexus_lpm_add(obj->u_.mux.q, obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG); IVL_DR_STRONG, IVL_DR_STRONG);
} else {
obj->u_.mux.q.pins = new ivl_nexus_t [obj->u_.mux.width];
for (unsigned idx = 0 ; idx < obj->u_.mux.width ; idx += 1) {
nex = net->pin_Result(idx).nexus();
assert(nex->t_cookie());
obj->u_.mux.q.pins[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.mux.q.pins[idx], obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG);
}
}
/* Connect the select bits. */ /* Connect the select bits. */
if (obj->u_.mux.swid == 1) { nex = net->pin_Sel().nexus();
nex = net->pin_Sel(0).nexus();
assert(nex->t_cookie()); assert(nex->t_cookie());
obj->u_.mux.s.pin = (ivl_nexus_t) nex->t_cookie(); obj->u_.mux.s = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.mux.s.pin, obj, 0, nexus_lpm_add(obj->u_.mux.s, obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ); IVL_DR_HiZ, IVL_DR_HiZ);
} else {
obj->u_.mux.s.pins = new ivl_nexus_t [obj->u_.mux.swid];
for (unsigned idx = 0 ; idx < obj->u_.mux.swid ; idx += 1) {
nex = net->pin_Sel(idx).nexus();
assert(nex->t_cookie());
obj->u_.mux.s.pins[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.mux.s.pins[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
}
}
unsigned width = obj->u_.mux.width;
unsigned selects = obj->u_.mux.size; unsigned selects = obj->u_.mux.size;
obj->u_.mux.d = new ivl_nexus_t [width * selects]; obj->u_.mux.d = new ivl_nexus_t [selects];
for (unsigned sdx = 0 ; sdx < selects ; sdx += 1) for (unsigned sdx = 0 ; sdx < selects ; sdx += 1) {
for (unsigned ddx = 0 ; ddx < width ; ddx += 1) { nex = net->pin_Data(sdx).nexus();
nex = net->pin_Data(ddx, sdx).nexus();
ivl_nexus_t tmp = (ivl_nexus_t) nex->t_cookie(); ivl_nexus_t tmp = (ivl_nexus_t) nex->t_cookie();
obj->u_.mux.d[sdx*width + ddx] = tmp; obj->u_.mux.d[sdx] = tmp;
nexus_lpm_add(tmp, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nexus_lpm_add(tmp, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
} }
@ -2257,6 +2229,11 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/* /*
* $Log: t-dll.cc,v $ * $Log: t-dll.cc,v $
* Revision 1.140 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.139 2005/02/08 00:12:36 steve * Revision 1.139 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support. * Add the NetRepeat node, and code generator support.
* *

16
t-dll.h
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.120 2005/02/08 00:12:36 steve Exp $" #ident "$Id: t-dll.h,v 1.121 2005/02/12 06:25:40 steve Exp $"
#endif #endif
# include "target.h" # include "target.h"
@ -318,14 +318,7 @@ struct ivl_lpm_s {
unsigned size; unsigned size;
unsigned swid; unsigned swid;
ivl_nexus_t*d; ivl_nexus_t*d;
union { ivl_nexus_t q, s;
ivl_nexus_t*pins;
ivl_nexus_t pin;
} q;
union {
ivl_nexus_t*pins;
ivl_nexus_t pin;
} s;
} mux; } mux;
struct ivl_lpm_shift_s { struct ivl_lpm_shift_s {
@ -694,6 +687,11 @@ struct ivl_variable_s {
/* /*
* $Log: t-dll.h,v $ * $Log: t-dll.h,v $
* Revision 1.121 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.120 2005/02/08 00:12:36 steve * Revision 1.120 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support. * Add the NetRepeat node, and code generator support.
* *