From 20be0351aede8e4d9a23daa577f870c73baf3f69 Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 30 Jan 2005 05:20:38 +0000 Subject: [PATCH] Elaborate unary subtract and NOT in netlist contexts, and concatenation too. --- elab_net.cc | 126 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/elab_net.cc b/elab_net.cc index 61fe6b851..018a117f9 100644 --- a/elab_net.cc +++ b/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.148 2005/01/29 18:46:18 steve Exp $" +#ident "$Id: elab_net.cc,v 1.149 2005/01/30 05:20:38 steve Exp $" #endif # include "config.h" @@ -1258,10 +1258,13 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, Link::strength_t drive1) const { svectornets (parms_.count()); - unsigned pins = 0; + unsigned vector_width = 0; unsigned errors = 0; unsigned repeat = 1; + /* The repeat expression must evaluate to a compile-time + constant. This is used to generate the width of the + concatenation. */ if (repeat_) { NetExpr*etmp = elab_and_eval(des, scope, repeat_); assert(etmp); @@ -1286,6 +1289,11 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, } } + if (debug_elaborate) { + cerr << get_line() <<": debug: PEConcat concat repeat=" + << repeat << "." << endl; + } + /* The operands of the concatenation must contain all self-determined arguments. Set this flag to force an error message if this is not the case. */ @@ -1321,7 +1329,7 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, if (nets[idx] == 0) errors += 1; else - pins += nets[idx]->pin_count(); + vector_width += nets[idx]->vector_width(); } must_be_self_determined_flag = save_flag; @@ -1336,6 +1344,18 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, return 0; } + if (debug_elaborate) { + cerr << get_line() <<": debug: PEConcat concat collected " + << "width=" << vector_width << ", repeat=" << repeat + << " of " << nets.count() << " expressions." << endl; + } + + NetConcat*dev = new NetConcat(scope, scope->local_symbol(), + vector_width*repeat, + nets.count()*repeat); + dev->set_line(*this); + des->add_node(dev); + /* Make the temporary signal that connects to all the operands, and connect it up. Scan the operands of the concat operator from least significant to most significant, @@ -1345,17 +1365,18 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, connect loop as many times as necessary. */ NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, pins * repeat); + NetNet::IMPLICIT, vector_width * repeat); - pins = 0; - for (unsigned rpt = 0 ; rpt < repeat ; rpt += 1) - for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) { - NetNet*cur = nets[idx-1]; - for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) { - connect(osig->pin(pins), cur->pin(pin)); - pins += 1; - } + connect(dev->pin(0), osig->pin(0)); + + unsigned cur_pin = 1; + for (unsigned rpt = 0; rpt < repeat ; rpt += 1) { + for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) { + NetNet*cur = nets[nets.count()-idx-1]; + connect(dev->pin(cur_pin++), cur->pin(0)); } + } + osig->local_flag(true); return osig; @@ -2289,6 +2310,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, // value. This can be reduced to a no-op on a precalculated // result. if (op_ == '-') do { + // TODO: Should replace this with a call to + // elab_and_eval. Possibly blend this with the rest of + // the elaboration as well. verinum*val = expr_->eval_const(des, scope); if (val == 0) break; @@ -2303,15 +2327,23 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* Take the 2s complement by taking the 1s complement and adding 1. */ - verinum tmp (v_not(*val)); + verinum tmp (v_not(*val), width); verinum one (1UL, width); - tmp = tmp + one; - NetConst*con = new NetConst(scope, scope->local_symbol(), tmp); - for (unsigned idx = 0 ; idx < width ; idx += 1) - connect(sig->pin(idx), con->pin(idx)); + tmp = verinum(tmp + one, width); + tmp.has_sign(val->has_sign()); + NetConst*con = new NetConst(scope, scope->local_symbol(), tmp); + connect(sig->pin(0), con->pin(0)); + + if (debug_elaborate) { + cerr << get_line() << ": debug: Replace expression " + << *this << " with constant " << tmp << "."<add_node(con); return sig; + } while (0); NetNet* sub_sig = expr_->elaborate_net(des, scope, owidth, 0, 0, 0); @@ -2327,18 +2359,18 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, switch (op_) { case '~': // Bitwise NOT sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, - sub_sig->pin_count()); + sub_sig->vector_width()); sig->local_flag(true); - for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1) { - gate = new NetLogic(scope, scope->local_symbol(), - 2, NetLogic::NOT, 1); - connect(gate->pin(1), sub_sig->pin(idx)); - connect(gate->pin(0), sig->pin(idx)); - des->add_node(gate); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - } + gate = new NetLogic(scope, scope->local_symbol(), + 2, NetLogic::NOT, sub_sig->vector_width()); + gate->set_line(*this); + des->add_node(gate); + gate->rise_time(rise); + gate->fall_time(fall); + gate->decay_time(decay); + + connect(gate->pin(1), sub_sig->pin(0)); + connect(gate->pin(0), sig->pin(0)); break; case 'N': // Reduction NOR @@ -2360,10 +2392,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, NetNet::WIRE, owidth); sig->local_flag(true); - if (sub_sig->pin_count() < owidth) + if (sub_sig->vector_width() < owidth) sub_sig = pad_to_width(des, sub_sig, owidth); - switch (sub_sig->pin_count()) { + switch (sub_sig->vector_width()) { case 0: assert(0); break; @@ -2379,31 +2411,11 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, gate->decay_time(decay); break; - case 2: - gate = new NetLogic(scope, scope->local_symbol(), - 2, NetLogic::BUF, 1); - connect(gate->pin(0), sig->pin(0)); - connect(gate->pin(1), sub_sig->pin(0)); - des->add_node(gate); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - - gate = new NetLogic(scope, scope->local_symbol(), - 3, NetLogic::XOR, 1); - connect(gate->pin(0), sig->pin(1)); - connect(gate->pin(1), sub_sig->pin(0)); - connect(gate->pin(2), sub_sig->pin(1)); - des->add_node(gate); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - break; - default: NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(), - sig->pin_count()); - sub->attribute(perm_string::literal("LPM_Direction"), verinum("SUB")); + sig->vector_width()); + sub->attribute(perm_string::literal("LPM_Direction"), + verinum("SUB")); des->add_node(sub); @@ -2418,7 +2430,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, NetNet*tmp_sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, - sub_sig->pin_count()); + sub_sig->vector_width()); tmp_sig->local_flag(true); connect(tmp_sig->pin(0), sub->pin_DataA()); @@ -2432,6 +2444,8 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, sig = 0; } if (reduction) { + cerr << get_line() + << ": XXXX: PEUnary::elab_net reductions not complete." << endl; sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE); sig->local_flag(true); gate = new NetLogic(scope, scope->local_symbol(), @@ -2451,6 +2465,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.149 2005/01/30 05:20:38 steve + * Elaborate unary subtract and NOT in netlist + * contexts, and concatenation too. + * * Revision 1.148 2005/01/29 18:46:18 steve * Netlist boolean expressions generate gate vectors. *