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
* 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.
*

View File

@ -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.
*

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
* 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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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

View File

@ -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.
*

View File

@ -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
View File

@ -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.
*