Restructure NetMux devices to pass vectors.
Generate NetMux devices from ternary expressions, Reduce NetMux devices to bufif when appropriate.
This commit is contained in:
parent
eca4f4fa97
commit
d74177634c
98
cprop.cc
98
cprop.cc
|
|
@ -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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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
|
||||
connected to the select input. */
|
||||
bool flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
NetScope*scope = obj->scope();
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF1, 1);
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
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;
|
||||
|
|
@ -809,33 +832,29 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/* If instead the second input is all constant Vz, replace the
|
||||
NetMux with an array of BUFIF0 devices. */
|
||||
flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
NetScope*scope = obj->scope();
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF0, 1);
|
||||
|
||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
||||
connect(obj->pin_Data(idx,0), tmp->pin(1));
|
||||
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||
des->add_node(tmp);
|
||||
}
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF0, obj->width());
|
||||
|
||||
connect(obj->pin_Result(), tmp->pin(0));
|
||||
connect(obj->pin_Data(0), tmp->pin(1));
|
||||
connect(obj->pin_Sel(), tmp->pin(2));
|
||||
des->add_node(tmp);
|
||||
|
||||
count += 1;
|
||||
delete obj;
|
||||
|
|
@ -961,6 +980,11 @@ void cprop(Design*des)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Implement LPM_COMPARE nodes as two-input vector functors.
|
||||
*
|
||||
|
|
|
|||
86
elab_net.cc
86
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.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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1408,7 +1408,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|||
if (sig_width > max_width_by_sel)
|
||||
sig_width = max_width_by_sel;
|
||||
}
|
||||
|
||||
#if 0
|
||||
NetMux*mux = new NetMux(scope, scope->local_symbol(), 1,
|
||||
sig_width, sel->pin_count());
|
||||
|
||||
|
|
@ -1438,6 +1438,12 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|||
des->add_node(mux);
|
||||
out->local_flag(true);
|
||||
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,
|
||||
|
|
@ -2172,9 +2178,9 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
|
|||
largest condition. Normally they should be the same size,
|
||||
but if we do not get a size from the context, or the
|
||||
expressions resist, we need to cope. */
|
||||
unsigned iwidth = tru_sig->pin_count();
|
||||
unsigned iwidth = tru_sig->vector_width();
|
||||
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
|
||||
|
|
@ -2185,23 +2191,23 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
|
|||
/* If the expression has width, then generate a boolean result
|
||||
by connecting an OR gate to calculate the truth value of
|
||||
the result. In the end, the result needs to be a single bit. */
|
||||
if (expr_sig->pin_count() > 1) {
|
||||
NetLogic*log = new NetLogic(scope, scope->local_symbol(),
|
||||
expr_sig->pin_count()+1,
|
||||
NetLogic::OR, 1);
|
||||
for (unsigned idx = 0; idx < expr_sig->pin_count(); idx += 1)
|
||||
connect(log->pin(idx+1), expr_sig->pin(idx));
|
||||
if (expr_sig->vector_width() > 1) {
|
||||
NetUReduce*log = new NetUReduce(scope, scope->local_symbol(),
|
||||
NetUReduce::OR,
|
||||
expr_sig->vector_width());
|
||||
log->set_line(*this);
|
||||
des->add_node(log);
|
||||
connect(log->pin(1), expr_sig->pin(0));
|
||||
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
tmp->local_flag(true);
|
||||
connect(tmp->pin(0), log->pin(0));
|
||||
des->add_node(log);
|
||||
connect(log->pin(0), tmp->pin(0));
|
||||
|
||||
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
|
||||
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);
|
||||
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);
|
||||
|
||||
if (tru_sig->pin_count() < dwidth)
|
||||
if (tru_sig->vector_width() < 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. */
|
||||
|
||||
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. */
|
||||
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
|
||||
connect(mux->pin_Data(idx,0), fal_sig->pin(idx));
|
||||
connect(mux->pin_Data(idx,1), tru_sig->pin(idx));
|
||||
}
|
||||
connect(mux->pin_Data(0), fal_sig->pin(0));
|
||||
connect(mux->pin_Data(1), tru_sig->pin(0));
|
||||
|
||||
/* If there are non-zero output delays, then create bufz
|
||||
devices to carry the propagation delays. Otherwise, just
|
||||
|
|
@ -2246,38 +2250,27 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
|
|||
if (rise || fall || decay) {
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, dwidth);
|
||||
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
|
||||
|
||||
NetBUFZ*tmpz = new NetBUFZ(scope, scope->local_symbol(), 1);
|
||||
tmpz->rise_time(rise);
|
||||
tmpz->fall_time(fall);
|
||||
tmpz->decay_time(decay);
|
||||
tmpz->pin(0).drive0(drive0);
|
||||
tmpz->pin(0).drive1(drive1);
|
||||
NetBUFZ*tmpz = new NetBUFZ(scope, scope->local_symbol(), dwidth);
|
||||
tmpz->rise_time(rise);
|
||||
tmpz->fall_time(fall);
|
||||
tmpz->decay_time(decay);
|
||||
tmpz->pin(0).drive0(drive0);
|
||||
tmpz->pin(0).drive1(drive1);
|
||||
|
||||
connect(mux->pin_Result(idx), tmp->pin(idx));
|
||||
connect(tmp->pin(idx), tmpz->pin(1));
|
||||
connect(sig->pin(idx), tmpz->pin(0));
|
||||
connect(mux->pin_Result(), tmp->pin(0));
|
||||
connect(tmp->pin(0), tmpz->pin(1));
|
||||
connect(sig->pin(0), tmpz->pin(0));
|
||||
|
||||
des->add_node(tmpz);
|
||||
}
|
||||
des->add_node(tmpz);
|
||||
|
||||
} else {
|
||||
for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
|
||||
connect(mux->pin_Result(idx), sig->pin(idx));
|
||||
}
|
||||
connect(mux->pin_Result(), sig->pin(0));
|
||||
}
|
||||
|
||||
/* If the MUX device result is too narrow to fill out the
|
||||
desired result, pad with zeros by creating a NetConst device. */
|
||||
|
||||
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));
|
||||
}
|
||||
desired result, pad with zeros... */
|
||||
assert(dwidth == width);
|
||||
|
||||
des->add_node(mux);
|
||||
|
||||
|
|
@ -2469,6 +2462,11 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
|
||||
/*
|
||||
* $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
|
||||
* laborate reduction gates into LPM_RED_ nodes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -789,7 +789,7 @@ NetNet* NetETernary::synthesize(Design *des)
|
|||
|
||||
perm_string path = csig->scope()->local_symbol();
|
||||
|
||||
assert(csig->pin_count() == 1);
|
||||
assert(csig->vector_width() == 1);
|
||||
|
||||
unsigned width=expr_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);
|
||||
fsig = pad_to_width(des, fsig, width);
|
||||
|
||||
assert(width <= tsig->pin_count());
|
||||
assert(width <= fsig->pin_count());
|
||||
assert(width <= tsig->vector_width());
|
||||
assert(width <= fsig->vector_width());
|
||||
|
||||
perm_string oname = csig->scope()->local_symbol();
|
||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
|
||||
connect(fsig->pin(idx), mux->pin_Data(idx, 0));
|
||||
connect(osig->pin(idx), mux->pin_Result(idx));
|
||||
}
|
||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, width);
|
||||
connect(tsig->pin(0), mux->pin_Data(1));
|
||||
connect(fsig->pin(0), mux->pin_Data(0));
|
||||
connect(osig->pin(0), mux->pin_Result());
|
||||
connect(csig->pin(0), mux->pin_Sel());
|
||||
des->add_node(mux);
|
||||
connect(csig->pin(0), mux->pin_Sel(0));
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
|
@ -852,6 +850,11 @@ NetNet* NetESignal::synthesize(Design*des)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Simplified NetMult and IVL_LPM_MULT.
|
||||
*
|
||||
|
|
|
|||
22
ivl_target.h
22
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.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
|
||||
|
||||
#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
|
||||
* 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_*)
|
||||
* 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
|
||||
|
|
@ -843,11 +854,11 @@ 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_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);
|
||||
/* 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);
|
||||
/* IVL_LPM_UFUNC */
|
||||
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
|
||||
/* IVL_LPM_UFUNC */
|
||||
extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx);
|
||||
|
|
@ -1489,6 +1500,11 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
|
|
|
|||
80
netlist.cc
80
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.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
|
||||
|
||||
# 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
|
||||
* like so:
|
||||
* 0 -- Aclr (optional)
|
||||
* 1 -- Clock (optional)
|
||||
* 2 -- Result[0]
|
||||
* 2+N -- Result[N]
|
||||
* 0 -- Result
|
||||
* 1 -- Sel
|
||||
* 2+N -- Data[N] (N is the size of the mux)
|
||||
*/
|
||||
|
||||
NetMux::NetMux(NetScope*s, perm_string n,
|
||||
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)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name(perm_string::literal("Aclr"), 0);
|
||||
pin(1).set_dir(Link::INPUT); pin(1).set_name(perm_string::literal("Clock"), 0);
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
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) {
|
||||
pin_Result(idx).set_dir(Link::OUTPUT);
|
||||
pin_Result(idx).set_name(perm_string::literal("Result"), 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);
|
||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1) {
|
||||
pin_Data(idx).set_dir(Link::INPUT);
|
||||
pin_Data(idx).set_name(perm_string::literal("D"), idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1323,62 +1314,36 @@ unsigned NetMux::sel_width() const
|
|||
return swidth_;
|
||||
}
|
||||
|
||||
Link& NetMux::pin_Aclr()
|
||||
Link& NetMux::pin_Result()
|
||||
{
|
||||
return pin(0);
|
||||
}
|
||||
|
||||
const Link& NetMux::pin_Aclr() const
|
||||
const Link& NetMux::pin_Result() const
|
||||
{
|
||||
return pin(0);
|
||||
}
|
||||
|
||||
Link& NetMux::pin_Clock()
|
||||
Link& NetMux::pin_Sel()
|
||||
{
|
||||
return pin(1);
|
||||
}
|
||||
|
||||
const Link& NetMux::pin_Clock() const
|
||||
const Link& NetMux::pin_Sel() const
|
||||
{
|
||||
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_);
|
||||
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_);
|
||||
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 $
|
||||
* 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
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
|
|
|
|||
25
netlist.h
25
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.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
|
||||
|
||||
/*
|
||||
|
|
@ -864,19 +864,13 @@ class NetMux : public NetNode {
|
|||
unsigned size() const;
|
||||
unsigned sel_width() const;
|
||||
|
||||
Link& pin_Aclr();
|
||||
Link& pin_Clock();
|
||||
Link& pin_Result();
|
||||
Link& pin_Data(unsigned si);
|
||||
Link& pin_Sel();
|
||||
|
||||
Link& pin_Result(unsigned);
|
||||
Link& pin_Data(unsigned wi, unsigned si);
|
||||
Link& pin_Sel(unsigned);
|
||||
|
||||
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;
|
||||
const Link& pin_Result() const;
|
||||
const Link& pin_Data(unsigned) const;
|
||||
const Link& pin_Sel() const;
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
|
|
@ -3426,6 +3420,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
|
|
|
|||
31
synth2.cc
31
synth2.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -188,6 +188,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
const NetNet*nex_map, NetNet*nex_out)
|
||||
{
|
||||
DEBUG_SYNTH2_ENTRY("NetCase")
|
||||
#if 0
|
||||
unsigned cur;
|
||||
|
||||
NetNet*esig = expr_->synthesize(des);
|
||||
|
|
@ -216,7 +217,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
elided. */
|
||||
map<unsigned long,unsigned long>guard2sel;
|
||||
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) {
|
||||
guard2sel[idx] = cur;
|
||||
cur += 1;
|
||||
|
|
@ -312,6 +313,11 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
|
||||
DEBUG_SYNTH2_EXIT("NetCase", 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,
|
||||
|
|
@ -360,18 +366,12 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
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));
|
||||
|
||||
for (unsigned idx = 0 ; idx < asig->pin_count() ; idx += 1)
|
||||
connect(mux->pin_Data(idx, 1), asig->pin(idx));
|
||||
|
||||
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));
|
||||
connect(mux->pin_Sel(), ssig->pin(0));
|
||||
connect(mux->pin_Data(1), asig->pin(0));
|
||||
connect(mux->pin_Data(0), bsig->pin(0));
|
||||
connect(nex_out->pin(0), mux->pin_Result());
|
||||
|
||||
des->add_node(mux);
|
||||
|
||||
|
|
@ -985,6 +985,11 @@ void synth2(Design*des)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
|
|
|
|||
29
t-dll-api.cc
29
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.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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -755,6 +755,10 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
|||
else
|
||||
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_OR:
|
||||
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);
|
||||
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: {
|
||||
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];
|
||||
|
||||
case IVL_LPM_MUX:
|
||||
assert(idx < net->u_.mux.width);
|
||||
if (net->u_.mux.width == 1)
|
||||
return net->u_.mux.q.pin;
|
||||
else
|
||||
return net->u_.mux.q.pins[idx];
|
||||
assert(idx == 0);
|
||||
return net->u_.mux.q;
|
||||
|
||||
case IVL_LPM_RE_AND:
|
||||
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];
|
||||
|
||||
case IVL_LPM_MUX:
|
||||
assert(idx < net->u_.mux.swid);
|
||||
if (net->u_.mux.swid == 1)
|
||||
return net->u_.mux.s.pin;
|
||||
else
|
||||
return net->u_.mux.s.pins[idx];
|
||||
assert(idx == 0);
|
||||
return net->u_.mux.s;
|
||||
|
||||
case IVL_LPM_SHIFTL:
|
||||
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 $
|
||||
* 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
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
|
|
|
|||
69
t-dll.cc
69
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.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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1800,57 +1800,29 @@ void dll_target::lpm_mux(const NetMux*net)
|
|||
const Nexus*nex;
|
||||
|
||||
/* Connect the output bits. */
|
||||
if (obj->u_.mux.width == 1) {
|
||||
nex = net->pin_Result(0).nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.mux.q.pin = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.mux.q.pin, obj, 0,
|
||||
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);
|
||||
}
|
||||
}
|
||||
nex = net->pin_Result().nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.mux.q = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.mux.q, obj, 0,
|
||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
|
||||
/* Connect the select bits. */
|
||||
if (obj->u_.mux.swid == 1) {
|
||||
nex = net->pin_Sel(0).nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.mux.s.pin = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.mux.s.pin, obj, 0,
|
||||
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
nex = net->pin_Sel().nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.mux.s = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.mux.s, obj, 0,
|
||||
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;
|
||||
|
||||
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 ddx = 0 ; ddx < width ; ddx += 1) {
|
||||
nex = net->pin_Data(ddx, sdx).nexus();
|
||||
ivl_nexus_t tmp = (ivl_nexus_t) nex->t_cookie();
|
||||
obj->u_.mux.d[sdx*width + ddx] = tmp;
|
||||
nexus_lpm_add(tmp, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
}
|
||||
for (unsigned sdx = 0 ; sdx < selects ; sdx += 1) {
|
||||
nex = net->pin_Data(sdx).nexus();
|
||||
ivl_nexus_t tmp = (ivl_nexus_t) nex->t_cookie();
|
||||
obj->u_.mux.d[sdx] = tmp;
|
||||
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 $
|
||||
* 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
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
|
|
|
|||
16
t-dll.h
16
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.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
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -318,14 +318,7 @@ struct ivl_lpm_s {
|
|||
unsigned size;
|
||||
unsigned swid;
|
||||
ivl_nexus_t*d;
|
||||
union {
|
||||
ivl_nexus_t*pins;
|
||||
ivl_nexus_t pin;
|
||||
} q;
|
||||
union {
|
||||
ivl_nexus_t*pins;
|
||||
ivl_nexus_t pin;
|
||||
} s;
|
||||
ivl_nexus_t q, s;
|
||||
} mux;
|
||||
|
||||
struct ivl_lpm_shift_s {
|
||||
|
|
@ -694,6 +687,11 @@ struct ivl_variable_s {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue