diff --git a/PExpr.h b/PExpr.h index c8bfb6513..06b863621 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PExpr.h,v 1.22 1999/10/31 20:08:24 steve Exp $" +#ident "$Id: PExpr.h,v 1.23 1999/11/05 21:45:19 steve Exp $" #endif # include @@ -248,6 +248,11 @@ class PEBinary : public PExpr { unsigned long rise, unsigned long fall, unsigned long decay) const; + NetNet* elaborate_net_cmp_(Design*des, const string&path, + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay) const; }; /* @@ -297,6 +302,10 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.23 1999/11/05 21:45:19 steve + * Fix NetConst being set to zero width, and clean + * up elaborate_set_cmp_ for NetEBinary. + * * Revision 1.22 1999/10/31 20:08:24 steve * Include subtraction in LPM_ADD_SUB device. * diff --git a/elab_net.cc b/elab_net.cc index 024ba85e8..673d71e4e 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 */ #if !defined(WINNT) -#ident "$Id: elab_net.cc,v 1.2 1999/11/04 03:53:26 steve Exp $" +#ident "$Id: elab_net.cc,v 1.3 1999/11/05 21:45:19 steve Exp $" #endif # include "PExpr.h" @@ -38,6 +38,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path, case '+': case '-': return elaborate_net_add_(des, path, width, rise, fall, decay); + case 'E': + case 'e': + case 'n': + return elaborate_net_cmp_(des, path, width, rise, fall, decay); } NetNet*lsig = left_->elaborate_net(des, path, width, 0, 0, 0), @@ -156,81 +160,9 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path, break; case 'E': // === (Case equals) - - // The comparison generates gates to bitwise compare - // each pair, and AND all the comparison results. - assert(lsig->pin_count() == rsig->pin_count()); - osig = new NetNet(des->local_symbol(path), NetNet::WIRE); - osig->local_flag(true); - gate = new NetLogic(des->local_symbol(path), - 1+lsig->pin_count(), - NetLogic::AND); - connect(gate->pin(0), osig->pin(0)); - for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { - gate_t = new NetCaseCmp(des->local_symbol(path)); - connect(gate_t->pin(1), lsig->pin(idx)); - connect(gate_t->pin(2), rsig->pin(idx)); - connect(gate_t->pin(0), gate->pin(idx+1)); - des->add_node(gate_t); - - // Attach a label to this intermediate wire - NetNet*tmp = new NetNet(des->local_symbol(path), - NetNet::WIRE); - tmp->local_flag(true); - connect(gate_t->pin(0), tmp->pin(0)); - des->add_signal(tmp); - } - des->add_signal(osig); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - des->add_node(gate); - break; - case 'e': // == - assert(lsig->pin_count() == rsig->pin_count()); - osig = new NetNet(des->local_symbol(path), NetNet::WIRE); - osig->local_flag(true); - gate = new NetLogic(des->local_symbol(path), - 1+lsig->pin_count(), - NetLogic::AND); - connect(gate->pin(0), osig->pin(0)); - for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { - gate_t = new NetLogic(des->local_symbol(path), 3, - NetLogic::XNOR); - connect(gate_t->pin(1), lsig->pin(idx)); - connect(gate_t->pin(2), rsig->pin(idx)); - connect(gate_t->pin(0), gate->pin(idx+1)); - des->add_node(gate_t); - } - des->add_signal(osig); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - des->add_node(gate); - break; - case 'n': // != - assert(lsig->pin_count() == rsig->pin_count()); - osig = new NetNet(des->local_symbol(path), NetNet::WIRE); - osig->local_flag(true); - gate = new NetLogic(des->local_symbol(path), - 1+lsig->pin_count(), - NetLogic::OR); - connect(gate->pin(0), osig->pin(0)); - for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { - gate_t = new NetLogic(des->local_symbol(path), 3, - NetLogic::XOR); - connect(gate_t->pin(1), lsig->pin(idx)); - connect(gate_t->pin(2), rsig->pin(idx)); - connect(gate_t->pin(0), gate->pin(idx+1)); - des->add_node(gate_t); - } - des->add_signal(osig); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - des->add_node(gate); + assert(0); break; case '+': @@ -332,6 +264,142 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, const string&path, return osig; } +/* + * Elaborate the various binary comparison operators. + */ +NetNet* PEBinary::elaborate_net_cmp_(Design*des, const string&path, + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay) const +{ + NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0), + *rsig = right_->elaborate_net(des, path, 0, 0, 0, 0); + if (lsig == 0) { + cerr << get_line() << ": error: Cannot elaborate "; + left_->dump(cerr); + cerr << endl; + return 0; + } + if (rsig == 0) { + cerr << get_line() << ": error: Cannot elaborate "; + right_->dump(cerr); + cerr << endl; + return 0; + } + + if (lsig->pin_count() != rsig->pin_count()) { + cerr << get_line() << ": internal error: Cannot match " + "structural net widths " << lsig->pin_count() << + " and " << rsig->pin_count() << "." << endl; + delete lsig; + delete rsig; + des->errors += 1; + return 0; + } + + NetNet*osig = new NetNet(des->local_symbol(path), NetNet::WIRE); + osig->local_flag(true); + + NetNode*gate; + NetNode*gate_t; + + switch (op_) { + case 'E': // Case equals (===) + // The comparison generates gates to bitwise compare + // each pair, and AND all the comparison results. + gate = new NetLogic(des->local_symbol(path), + 1+lsig->pin_count(), + NetLogic::AND); + connect(gate->pin(0), osig->pin(0)); + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { + gate_t = new NetCaseCmp(des->local_symbol(path)); + connect(gate_t->pin(1), lsig->pin(idx)); + connect(gate_t->pin(2), rsig->pin(idx)); + connect(gate_t->pin(0), gate->pin(idx+1)); + des->add_node(gate_t); + + // Attach a label to this intermediate wire + NetNet*tmp = new NetNet(des->local_symbol(path), + NetNet::WIRE); + tmp->local_flag(true); + connect(gate_t->pin(0), tmp->pin(0)); + des->add_signal(tmp); + } + break; + + + case 'e': // == + gate = new NetLogic(des->local_symbol(path), + 1+lsig->pin_count(), + NetLogic::AND); + connect(gate->pin(0), osig->pin(0)); + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { + gate_t = new NetLogic(des->local_symbol(path), 3, + NetLogic::XNOR); + connect(gate_t->pin(1), lsig->pin(idx)); + connect(gate_t->pin(2), rsig->pin(idx)); + connect(gate_t->pin(0), gate->pin(idx+1)); + des->add_node(gate_t); + } + break; + + case 'n': // != + gate = new NetLogic(des->local_symbol(path), + 1+lsig->pin_count(), + NetLogic::OR); + connect(gate->pin(0), osig->pin(0)); + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { + gate_t = new NetLogic(des->local_symbol(path), 3, + NetLogic::XOR); + connect(gate_t->pin(1), lsig->pin(idx)); + connect(gate_t->pin(2), rsig->pin(idx)); + connect(gate_t->pin(0), gate->pin(idx+1)); + des->add_node(gate_t); + } + break; + + default: + assert(0); + } + + des->add_signal(osig); + gate->rise_time(rise); + gate->fall_time(fall); + gate->decay_time(decay); + des->add_node(gate); + + return osig; +} + +/* + * Elaborate a number as a NetConst object. + */ +NetNet* PENumber::elaborate_net(Design*des, const string&path, + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay) const +{ + unsigned width = value_->len(); + if ((lwidth > 0) && (lwidth < width)) + width = lwidth; + + NetNet*net = new NetNet(des->local_symbol(path), + NetNet::IMPLICIT, width); + net->local_flag(true); + for (unsigned idx = 0 ; idx < width ; idx += 1) { + NetConst*tmp = new NetConst(des->local_symbol(path), + value_->get(idx)); + des->add_node(tmp); + connect(net->pin(idx), tmp->pin(0)); + } + + des->add_signal(net); + return net; +} + + /* * Elaborate the ternary operator in a netlist by creating a LPM_MUX * with width matching the result, size == 2 and 1 select input. @@ -370,6 +438,10 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path, /* * $Log: elab_net.cc,v $ + * Revision 1.3 1999/11/05 21:45:19 steve + * Fix NetConst being set to zero width, and clean + * up elaborate_set_cmp_ for NetEBinary. + * * Revision 1.2 1999/11/04 03:53:26 steve * Patch to synthesize unary ~ and the ternary operator. * Thanks to Larry Doolittle . diff --git a/elaborate.cc b/elaborate.cc index 3204c496d..4db57895e 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.121 1999/11/04 03:53:26 steve Exp $" +#ident "$Id: elaborate.cc,v 1.122 1999/11/05 21:45:19 steve Exp $" #endif /* @@ -908,34 +908,6 @@ NetNet* PEIdent::elaborate_lnet(Design*des, const string&path) const return sig; } -/* - * Elaborate a number as a NetConst object. - */ -NetNet* PENumber::elaborate_net(Design*des, const string&path, - unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const -{ - unsigned width = value_->len(); - if (lwidth < width) - width = lwidth; - - NetNet*net = new NetNet(des->local_symbol(path), - NetNet::IMPLICIT, width); - net->local_flag(true); - for (unsigned idx = 0 ; idx < width ; idx += 1) { - NetConst*tmp = new NetConst(des->local_symbol(path), - value_->get(idx)); - des->add_node(tmp); - connect(net->pin(idx), tmp->pin(0)); - } - - des->add_signal(net); - return net; -} - - NetNet* PEUnary::elaborate_net(Design*des, const string&path, unsigned width, unsigned long rise, @@ -2357,6 +2329,10 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.122 1999/11/05 21:45:19 steve + * Fix NetConst being set to zero width, and clean + * up elaborate_set_cmp_ for NetEBinary. + * * Revision 1.121 1999/11/04 03:53:26 steve * Patch to synthesize unary ~ and the ternary operator. * Thanks to Larry Doolittle .