diff --git a/design_dump.cc b/design_dump.cc index 9130b850b..e4675e329 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: design_dump.cc,v 1.154 2005/01/24 05:28:30 steve Exp $" +#ident "$Id: design_dump.cc,v 1.155 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -374,6 +374,41 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const dump_obj_attr(o, ind+4); } +void NetUReduce::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "reduction logic: "; + switch (type_) { + case NONE: + o << "NONE"; + break; + case AND: + o << "and"; + break; + case OR: + o << "or"; + break; + case XOR: + o << "xor"; + break; + case NAND: + o << "nand"; + break; + case NOR: + o << "nor"; + break; + case XNOR: + o << "xnor"; + break; + } + o << " #(" << rise_time() + << "," << fall_time() << "," << decay_time() << ") " << name() + << " scope=" << (scope()? scope()->name() : "") + << endl; + + dump_node_pins(o, ind+4); + dump_obj_attr(o, ind+4); +} + void NetUserFunc::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << def_->name() << "("; @@ -1094,6 +1129,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.155 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.154 2005/01/24 05:28:30 steve * Remove the NetEBitSel and combine all bit/part select * behavior into the NetESelect node and IVL_EX_SELECT diff --git a/elab_net.cc b/elab_net.cc index 018a117f9..ef23661aa 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.149 2005/01/30 05:20:38 steve Exp $" +#ident "$Id: elab_net.cc,v 1.150 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -2306,6 +2306,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, NetNet* sig = 0; NetLogic*gate; + // Handle the special case of a 2's complement of a constant // value. This can be reduced to a no-op on a precalculated // result. @@ -2354,7 +2355,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, assert(sub_sig); bool reduction=false; - NetLogic::TYPE gtype = NetLogic::AND; + NetUReduce::TYPE rtype = NetUReduce::NONE; switch (op_) { case '~': // Bitwise NOT @@ -2375,17 +2376,17 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, case 'N': // Reduction NOR case '!': // Reduction NOT - reduction=true; gtype = NetLogic::NOR; break; + reduction=true; rtype = NetUReduce::NOR; break; case '&': // Reduction AND - reduction=true; gtype = NetLogic::AND; break; + reduction=true; rtype = NetUReduce::AND; break; case '|': // Reduction OR - reduction=true; gtype = NetLogic::OR; break; + reduction=true; rtype = NetUReduce::OR; break; case '^': // Reduction XOR - reduction=true; gtype = NetLogic::XOR; break; + reduction=true; rtype = NetUReduce::XOR; break; case 'A': // Reduction NAND (~&) - reduction=true; gtype = NetLogic::NAND; break; + reduction=true; rtype = NetUReduce::NAND; break; case 'X': // Reduction XNOR (~^) - reduction=true; gtype = NetLogic::XNOR; break; + reduction=true; rtype = NetUReduce::XNOR; break; case '-': // Unary 2's complement. sig = new NetNet(scope, scope->local_symbol(), @@ -2443,21 +2444,24 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, cerr << "internal error: Unhandled UNARY '" << op_ << "'" << endl; 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(), - 1+sub_sig->pin_count(), gtype, 1); - connect(gate->pin(0), sig->pin(0)); - for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1) - connect(gate->pin(idx+1), sub_sig->pin(idx)); - des->add_node(gate); - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); + if (reduction) { + NetUReduce*rgate; + + // The output of a reduction operator is 1 bit + sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1); + sig->local_flag(true); + + rgate = new NetUReduce(scope, scope->local_symbol(), + rtype, sub_sig->vector_width()); + rgate->set_line(*this); + connect(rgate->pin(0), sig->pin(0)); + connect(rgate->pin(1), sub_sig->pin(0)); + + des->add_node(rgate); + rgate->rise_time(rise); + rgate->fall_time(fall); + rgate->decay_time(decay); } return sig; @@ -2465,6 +2469,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.150 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.149 2005/01/30 05:20:38 steve * Elaborate unary subtract and NOT in netlist * contexts, and concatenation too. @@ -2509,171 +2516,5 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, * * Revision 1.136 2004/10/04 00:25:46 steve * Error message to match assertion. - * - * Revision 1.135 2004/09/24 04:25:19 steve - * Detect and prevent implicit declaration of hierarchical names. - * - * Revision 1.134 2004/08/28 15:42:12 steve - * Add support for $unsigned. - * - * Revision 1.133 2004/06/30 02:16:26 steve - * Implement signed divide and signed right shift in nets. - * - * Revision 1.132 2004/06/24 15:22:23 steve - * Code cleanup from Larry. - * - * Revision 1.131 2004/06/22 18:41:48 steve - * Fix broken calcuation of NE for constant. - * - * Revision 1.130 2004/06/18 16:38:22 steve - * compare-to-constant uses sig len, not val len. - * - * Revision 1.129 2004/06/16 23:32:58 steve - * Handle equality compare to constants specially. - * - * Revision 1.128 2004/06/13 04:56:53 steve - * Add support for the default_nettype directive. - * - * Revision 1.127 2004/06/01 01:04:57 steve - * Fix synthesis method for logical and/or - * - * Revision 1.126 2004/05/31 23:34:36 steve - * Rewire/generalize parsing an elaboration of - * function return values to allow for better - * speed and more type support. - * - * Revision 1.125 2004/02/20 18:53:34 steve - * Addtrbute keys are perm_strings. - * - * Revision 1.124 2004/02/18 17:11:54 steve - * Use perm_strings for named langiage items. - * - * Revision 1.123 2004/02/15 04:23:48 steve - * Fix evaluation of compare to constant expression. - * - * Revision 1.122 2003/10/30 04:31:34 steve - * Catch real variables in net expressions. - * - * Revision 1.121 2003/10/20 01:44:28 steve - * memory index need not be self determined width. - * - * Revision 1.120 2003/09/23 03:31:28 steve - * Catch unsized expressions in continuous assigns. - * - * Revision 1.119 2003/09/19 03:50:12 steve - * Remove find_memory method from Design class. - * - * Revision 1.118 2003/09/13 01:30:07 steve - * Missing case warnings. - * - * Revision 1.117 2003/09/03 04:29:18 steve - * Only build a mux as wide as can be selected. - * - * Revision 1.116 2003/08/28 04:11:17 steve - * Spelling patch. - * - * Revision 1.115 2003/08/05 03:01:58 steve - * Primitive outputs have same limitations as continuous assignment. - * - * Revision 1.114 2003/06/21 01:21:43 steve - * Harmless fixup of warnings. - * - * Revision 1.113 2003/05/01 01:13:57 steve - * More complete bit range internal error message, - * Better test of part select ranges on non-zero - * signal ranges. - * - * Revision 1.112 2003/04/11 05:18:08 steve - * Handle signed magnitude compare all the - * way through to the vvp code generator. - * - * Revision 1.111 2003/03/29 05:51:25 steve - * Sign extend NetMult inputs if result is signed. - * - * Revision 1.110 2003/03/26 06:16:38 steve - * Some better internal error messages. - * - * Revision 1.109 2003/03/10 23:40:53 steve - * Keep parameter constants for the ivl_target API. - * - * Revision 1.108 2003/03/06 00:28:41 steve - * All NetObj objects have lex_string base names. - * - * Revision 1.107 2003/02/26 01:29:24 steve - * LPM objects store only their base names. - * - * Revision 1.106 2003/01/27 05:09:17 steve - * Spelling fixes. - * - * Revision 1.105 2003/01/19 00:35:39 steve - * Detect null arguments to concatenation operator. - * - * Revision 1.104 2003/01/17 05:48:35 steve - * Remove useless variable. - * - * Revision 1.103 2002/12/06 03:08:19 steve - * Reword some error messages for clarity. - * - * Revision 1.102 2002/11/09 19:20:48 steve - * Port expressions for output ports are lnets, not nets. - * - * Revision 1.101 2002/09/18 04:29:55 steve - * Add support for binary NOR operator. - * - * Revision 1.100 2002/09/12 15:49:43 steve - * Add support for binary nand operator. - * - * Revision 1.99 2002/09/08 01:37:13 steve - * Fix padding of operand of unary minus. - * - * Revision 1.98 2002/08/31 03:48:50 steve - * Fix reverse bit ordered bit select in continuous assignment. - * - * Revision 1.97 2002/08/21 02:28:03 steve - * Carry mux output delays. - * - * Revision 1.96 2002/08/14 03:57:27 steve - * Constants can self-size themselves in unsized contexts. - * - * Revision 1.95 2002/08/12 01:34:59 steve - * conditional ident string using autoconfig. - * - * Revision 1.94 2002/08/05 04:18:45 steve - * Store only the base name of memories. - * - * Revision 1.93 2002/07/05 21:26:17 steve - * Avoid emitting to vvp local net symbols. - * - * Revision 1.92 2002/06/22 04:22:40 steve - * Wide unary minus in continuous assignments. - * - * Revision 1.91 2002/06/19 04:20:03 steve - * Remove NetTmp and add NetSubnet class. - * - * Revision 1.90 2002/05/23 03:08:51 steve - * Add language support for Verilog-2001 attribute - * syntax. Hook this support into existing $attribute - * handling, and add number and void value types. - * - * Add to the ivl_target API new functions for access - * of complex attributes attached to gates. - * - * Revision 1.89 2002/04/23 03:53:59 steve - * Add support for non-constant bit select. - * - * Revision 1.88 2002/04/22 00:53:39 steve - * Do not allow implicit wires in sensitivity lists. - * - * Revision 1.87 2002/03/09 02:10:22 steve - * Add the NetUserFunc netlist node. - * - * Revision 1.86 2002/01/23 05:23:17 steve - * No implicit declaration in assign l-values. - * - * Revision 1.85 2002/01/03 04:19:01 steve - * Add structural modulus support down to vvp. - * - * Revision 1.84 2001/12/31 04:23:59 steve - * Elaborate multiply nets with constant operands ad NetConst. */ diff --git a/emit.cc b/emit.cc index 16fbe28cc..159367573 100644 --- a/emit.cc +++ b/emit.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-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: emit.cc,v 1.81 2005/01/24 05:28:30 steve Exp $" +#ident "$Id: emit.cc,v 1.82 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -126,6 +126,12 @@ bool NetRamDq::emit_node(struct target_t*tgt) const return true; } +bool NetUReduce::emit_node(struct target_t*tgt) const +{ + return tgt->ureduce(this); +} + + bool NetUserFunc::emit_node(struct target_t*tgt) const { return tgt->net_function(this); @@ -512,6 +518,9 @@ int emit(const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.82 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.81 2005/01/24 05:28:30 steve * Remove the NetEBitSel and combine all bit/part select * behavior into the NetESelect node and IVL_EX_SELECT diff --git a/functor.cc b/functor.cc index cb2d3692b..a37d6f270 100644 --- a/functor.cc +++ b/functor.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 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: functor.cc,v 1.32 2004/10/04 01:10:53 steve Exp $" +#ident "$Id: functor.cc,v 1.33 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -79,6 +79,10 @@ void functor_t::lpm_mux(class Design*, class NetMux*) { } +void functor_t::lpm_ureduce(class Design*, class NetUReduce*) +{ +} + void NetScope::run_functor(Design*des, functor_t*fun) { @@ -206,6 +210,11 @@ void NetMux::functor_node(Design*des, functor_t*fun) fun->lpm_mux(des, this); } +void NetUReduce::functor_node(Design*des, functor_t*fun) +{ + fun->lpm_ureduce(des, this); +} + proc_match_t::~proc_match_t() { } @@ -267,6 +276,9 @@ int proc_match_t::event_wait(NetEvWait*) /* * $Log: functor.cc,v $ + * Revision 1.33 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.32 2004/10/04 01:10:53 steve * Clean up spurious trailing white space. * diff --git a/functor.h b/functor.h index 2f143fd00..fcf66e1c7 100644 --- a/functor.h +++ b/functor.h @@ -1,7 +1,7 @@ #ifndef __functor_H #define __functor_H /* - * Copyright (c) 1999-2000 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 @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $" +#ident "$Id: functor.h,v 1.21 2005/02/03 04:56:20 steve Exp $" #endif /* @@ -77,6 +77,9 @@ struct functor_t { /* This method is called for each MUX. */ virtual void lpm_mux(class Design*des, class NetMux*); + + /* This method is called for each unary reduction gate. */ + virtual void lpm_ureduce(class Design*des, class NetUReduce*); }; struct proc_match_t { @@ -92,6 +95,9 @@ struct proc_match_t { /* * $Log: functor.h,v $ + * Revision 1.21 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.20 2002/08/12 01:34:59 steve * conditional ident string using autoconfig. * diff --git a/ivl_target.h b/ivl_target.h index dd7bb533d..9532dd5ab 100644 --- a/ivl_target.h +++ b/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.137 2005/01/29 18:46:18 steve Exp $" +#ident "$Id: ivl_target.h,v 1.138 2005/02/03 04:56:20 steve Exp $" #endif #ifdef __cplusplus @@ -238,6 +238,12 @@ typedef enum ivl_lpm_type_e { IVL_LPM_MUX = 5, IVL_LPM_PART_VP= 15, /* part select: vector to part */ IVL_LPM_PART_PV= 17, /* part select: part written to vector */ + IVL_LPM_RE_AND = 20, + IVL_LPM_RE_NAND= 21, + IVL_LPM_RE_NOR = 22, + IVL_LPM_RE_OR = 23, + IVL_LPM_RE_XNOR= 24, + IVL_LPM_RE_XOR = 25, IVL_LPM_SHIFTL = 6, IVL_LPM_SHIFTR = 7, IVL_LPM_SUB = 8, @@ -799,6 +805,11 @@ extern const char* ivl_udp_name(ivl_udp_t net); * (so the target need not worry about sign extension) but when doing * magnitude compare, the signedness does matter. In any case, the * result of the compare is always unsigned. + * + * - 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 + * vector. */ extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */ @@ -1470,6 +1481,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.138 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.137 2005/01/29 18:46:18 steve * Netlist boolean expressions generate gate vectors. * diff --git a/netlist.cc b/netlist.cc index 98f6ae91c..a7a7f6fb5 100644 --- a/netlist.cc +++ b/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.234 2005/01/28 05:39:33 steve Exp $" +#ident "$Id: netlist.cc,v 1.235 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -2210,6 +2210,26 @@ unsigned NetLogic::width() const return width_; } +NetUReduce::NetUReduce(NetScope*scope, perm_string n, + NetUReduce::TYPE t, unsigned wid) +: NetNode(scope, n, 2), type_(t), width_(wid) +{ + pin(0).set_dir(Link::OUTPUT); + pin(0).set_name(perm_string::literal("O")); + pin(1).set_dir(Link::INPUT); + pin(1).set_name(perm_string::literal("I")); +} + +NetUReduce::TYPE NetUReduce::type() const +{ + return type_; +} + +unsigned NetUReduce::width() const +{ + return width_; +} + NetTaskDef::NetTaskDef(const string&n, const svector&po) : name_(n), proc_(0), ports_(po) { @@ -2249,6 +2269,9 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.235 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.234 2005/01/28 05:39:33 steve * Simplified NetMult and IVL_LPM_MULT. * diff --git a/netlist.h b/netlist.h index e9156ad00..f0781b443 100644 --- a/netlist.h +++ b/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.331 2005/01/30 01:43:48 steve Exp $" +#ident "$Id: netlist.h,v 1.332 2005/02/03 04:56:20 steve Exp $" #endif /* @@ -1316,6 +1316,32 @@ class NetLogic : public NetNode { unsigned width_; }; +/* + * This class represents *reduction* logic operators. Certain boolean + * logic operators have reduction forms which take in a vector and + * return a single bit that is calculated by applying the logic + * operation through the width of the input vector. These correspond + * to reduction unary operators in Verilog. + */ +class NetUReduce : public NetNode { + + public: + enum TYPE {NONE, AND, OR, XOR, NAND, NOR, XNOR}; + + NetUReduce(NetScope*s, perm_string n, TYPE t, unsigned wid); + + TYPE type() const; + unsigned width() const; + + virtual void dump_node(ostream&, unsigned ind) const; + virtual bool emit_node(struct target_t*) const; + virtual void functor_node(Design*, functor_t*); + + private: + TYPE type_; + unsigned width_; +}; + /* * The UDP is a User Defined Primitive from the Verilog source. Do not * expand it out any further then this in the netlist, as this can be @@ -3370,6 +3396,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.332 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.331 2005/01/30 01:43:48 steve * Clarify width argument to NetNet constructor. * diff --git a/t-dll-api.cc b/t-dll-api.cc index 0da651a91..e0badacaf 100644 --- a/t-dll-api.cc +++ b/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.115 2005/01/24 05:28:31 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.116 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -755,6 +755,15 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx) else return net->u_.arith.b; + case IVL_LPM_RE_AND: + case IVL_LPM_RE_OR: + case IVL_LPM_RE_XOR: + case IVL_LPM_RE_NAND: + case IVL_LPM_RE_NOR: + case IVL_LPM_RE_XNOR: + assert(idx == 0); + return net->u_.reduce.a; + case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: assert(idx < net->u_.shift.width); @@ -912,6 +921,15 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx) else return net->u_.mux.q.pins[idx]; + case IVL_LPM_RE_AND: + case IVL_LPM_RE_OR: + case IVL_LPM_RE_XOR: + case IVL_LPM_RE_NAND: + case IVL_LPM_RE_NOR: + case IVL_LPM_RE_XNOR: + assert(idx == 0); + return net->u_.reduce.q; + case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: assert(idx < net->u_.shift.width); @@ -1006,10 +1024,16 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net) case IVL_LPM_MULT: case IVL_LPM_SUB: return net->u_.arith.signed_flag; + case IVL_LPM_RE_AND: + case IVL_LPM_RE_OR: + case IVL_LPM_RE_XOR: + case IVL_LPM_RE_NAND: + case IVL_LPM_RE_NOR: + case IVL_LPM_RE_XNOR: + return 0; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: return net->u_.shift.signed_flag; - return 0; case IVL_LPM_UFUNC: return 0; case IVL_LPM_CONCAT: // Concatenations are always unsigned @@ -1061,6 +1085,13 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net) case IVL_LPM_MULT: case IVL_LPM_SUB: return net->u_.arith.width; + case IVL_LPM_RE_AND: + case IVL_LPM_RE_OR: + case IVL_LPM_RE_XOR: + case IVL_LPM_RE_NAND: + case IVL_LPM_RE_NOR: + case IVL_LPM_RE_XNOR: + return net->u_.reduce.width; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: return net->u_.shift.width; @@ -1953,6 +1984,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.116 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.115 2005/01/24 05:28:31 steve * Remove the NetEBitSel and combine all bit/part select * behavior into the NetESelect node and IVL_EX_SELECT diff --git a/t-dll.cc b/t-dll.cc index 7c7ffdb0a..bce3666d9 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-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: t-dll.cc,v 1.137 2005/01/28 05:39:33 steve Exp $" +#ident "$Id: t-dll.cc,v 1.138 2005/02/03 04:56:20 steve Exp $" #endif # include "config.h" @@ -912,6 +912,58 @@ void dll_target::logic(const NetLogic*net) scope_add_logic(scope, obj); } +bool dll_target::ureduce(const NetUReduce*net) +{ + struct ivl_lpm_s*obj = new struct ivl_lpm_s; + switch (net->type()) { + case NetUReduce::NONE: + assert(0); + return false; + case NetUReduce::AND: + obj->type = IVL_LPM_RE_AND; + break; + case NetUReduce::OR: + obj->type = IVL_LPM_RE_OR; + break; + case NetUReduce::XOR: + obj->type = IVL_LPM_RE_XOR; + break; + case NetUReduce::NAND: + obj->type = IVL_LPM_RE_NAND; + break; + case NetUReduce::NOR: + obj->type = IVL_LPM_RE_NOR; + break; + case NetUReduce::XNOR: + obj->type = IVL_LPM_RE_XNOR; + break; + } + + obj->name = net->name(); + obj->scope = find_scope(des_, net->scope()); + assert(obj->scope); + + obj->u_.reduce.width = net->width(); + + const Nexus*nex; + + nex = net->pin(0).nexus(); + assert(nex->t_cookie()); + + obj->u_.reduce.q = (ivl_nexus_t) nex->t_cookie(); + nexus_lpm_add(obj->u_.reduce.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); + + nex = net->pin(1).nexus(); + assert(nex->t_cookie()); + + obj->u_.reduce.a = (ivl_nexus_t) nex->t_cookie(); + nexus_lpm_add(obj->u_.reduce.a, obj, 1, IVL_DR_HiZ, IVL_DR_HiZ); + + scope_add_lpm(obj->scope, obj); + + return true; +} + void dll_target::net_case_cmp(const NetCaseCmp*net) { struct ivl_lpm_s*obj = new struct ivl_lpm_s; @@ -2174,6 +2226,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.138 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.137 2005/01/28 05:39:33 steve * Simplified NetMult and IVL_LPM_MULT. * diff --git a/t-dll.h b/t-dll.h index 9b22a9da8..634d27e3e 100644 --- a/t-dll.h +++ b/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.118 2005/01/24 05:28:31 steve Exp $" +#ident "$Id: t-dll.h,v 1.119 2005/02/03 04:56:20 steve Exp $" #endif # include "target.h" @@ -71,6 +71,7 @@ struct dll_target : public target_t, public expr_scan_t { void event(const NetEvent*); void variable(const NetVariable*); void logic(const NetLogic*); + bool ureduce(const NetUReduce*); void net_case_cmp(const NetCaseCmp*); void udp(const NetUDP*); void lpm_add_sub(const NetAddSub*); @@ -354,6 +355,11 @@ struct ivl_lpm_s { ivl_nexus_t q, a; } part; + struct ivl_lpm_reduce_s { + unsigned width; + ivl_nexus_t q, a; + } reduce; + struct ivl_lpm_ufunc_s { ivl_scope_t def; unsigned ports; @@ -680,6 +686,9 @@ struct ivl_variable_s { /* * $Log: t-dll.h,v $ + * Revision 1.119 2005/02/03 04:56:20 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.118 2005/01/24 05:28:31 steve * Remove the NetEBitSel and combine all bit/part select * behavior into the NetESelect node and IVL_EX_SELECT diff --git a/target.cc b/target.cc index 8aaa13c98..22e47a683 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: target.cc,v 1.72 2005/01/24 05:28:31 steve Exp $" +#ident "$Id: target.cc,v 1.73 2005/02/03 04:56:21 steve Exp $" #endif # include "config.h" @@ -68,6 +68,8 @@ void target_t::task_def(const NetScope*) void target_t::logic(const NetLogic*) { + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled logic gate" << endl; } bool target_t::bufz(const NetBUFZ*) @@ -83,6 +85,13 @@ void target_t::udp(const NetUDP*) "Unhandled UDP." << endl; } +bool target_t::ureduce(const NetUReduce*) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled unary reduction logic gate." << endl; + return false; +} + void target_t::lpm_add_sub(const NetAddSub*) { cerr << "target (" << typeid(*this).name() << "): " @@ -413,6 +422,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.73 2005/02/03 04:56:21 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.72 2005/01/24 05:28:31 steve * Remove the NetEBitSel and combine all bit/part select * behavior into the NetESelect node and IVL_EX_SELECT diff --git a/target.h b/target.h index 29023058d..3d96fa52c 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: target.h,v 1.69 2005/01/24 05:28:31 steve Exp $" +#ident "$Id: target.h,v 1.70 2005/02/03 04:56:21 steve Exp $" #endif # include "netlist.h" @@ -91,6 +91,7 @@ struct target_t { /* Output a gate (called for each gate) */ virtual void logic(const NetLogic*); + virtual bool ureduce(const NetUReduce*); /* unary reduction operator */ virtual bool bufz(const NetBUFZ*); virtual void udp(const NetUDP*); virtual void net_case_cmp(const NetCaseCmp*); @@ -170,6 +171,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.70 2005/02/03 04:56:21 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.69 2005/01/24 05:28:31 steve * Remove the NetEBitSel and combine all bit/part select * behavior into the NetESelect node and IVL_EX_SELECT diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index cab2cc59a..98a1175fd 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.105 2005/01/30 05:09:04 steve Exp $" +#ident "$Id: stub.c,v 1.106 2005/02/03 04:56:21 steve Exp $" #endif # include "config.h" @@ -380,6 +380,48 @@ static void show_lpm_mult(ivl_lpm_t net) } } +/* + * The reduction operators have similar characteristics and are + * displayed here. + */ +static void show_lpm_re(ivl_lpm_t net) +{ + ivl_nexus_t nex; + const char*type = "?"; + unsigned width = ivl_lpm_width(net); + + switch (ivl_lpm_type(net)) { + case IVL_LPM_RE_AND: + type = "AND"; + break; + default: + break; + } + + fprintf(out, " LPM_RE_%s: \n", type, width); + + nex = ivl_lpm_q(net, 0); + fprintf(out, " Q: %s\n", ivl_nexus_name(nex)); + + nex = ivl_lpm_data(net, 0); + fprintf(out, " D: %s\n", ivl_nexus_name(nex)); + + nex = ivl_lpm_q(net, 0); + + if (1 != width_of_nexus(nex)) { + fprintf(out, " ERROR: Width of Q is %u, expecting 1\n", + width_of_nexus(nex)); + stub_errors += 1; + } + + nex = ivl_lpm_data(net, 0); + if (width != width_of_nexus(nex)) { + fprintf(out, " ERROR: Width of input is %u, expecting %u\n", + width_of_nexus(nex), width); + stub_errors += 1; + } +} + static void show_lpm_sub(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); @@ -437,6 +479,10 @@ static void show_lpm(ivl_lpm_t net) show_lpm_concat(net); break; + case IVL_LPM_RE_AND: + show_lpm_re(net); + break; + case IVL_LPM_SHIFTL: { fprintf(out, " LPM_SHIFTL %s: \n", ivl_lpm_basename(net), width, ivl_lpm_selects(net), @@ -1012,6 +1058,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.106 2005/02/03 04:56:21 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.105 2005/01/30 05:09:04 steve * Support LPM_SUB * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index aadee16bb..f915a515b 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_scope.c,v 1.112 2005/01/22 16:22:13 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.113 2005/02/03 04:56:21 steve Exp $" #endif # include "vvp_priv.h" @@ -438,6 +438,12 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: + case IVL_LPM_RE_AND: + case IVL_LPM_RE_OR: + case IVL_LPM_RE_XOR: + case IVL_LPM_RE_NAND: + case IVL_LPM_RE_NOR: + case IVL_LPM_RE_XNOR: case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: case IVL_LPM_SUB: @@ -1618,6 +1624,16 @@ static void draw_lpm_part_pv(ivl_lpm_t net) fprintf(vvp_out, ", %u, %u, %u;\n", base, width, signal_width); } +/* + * Draw unary reduction devices. + */ +static void draw_lpm_re(ivl_lpm_t net, const char*type) +{ + fprintf(vvp_out, "L_%p .reduce/%s ", net, type); + draw_input_from_net(ivl_lpm_data(net,0)); + fprintf(vvp_out, ";\n"); +} + static void draw_lpm_in_scope(ivl_lpm_t net) { switch (ivl_lpm_type(net)) { @@ -1662,6 +1678,25 @@ static void draw_lpm_in_scope(ivl_lpm_t net) draw_lpm_mux(net); return; + case IVL_LPM_RE_AND: + draw_lpm_re(net, "and"); + return; + case IVL_LPM_RE_OR: + draw_lpm_re(net, "or"); + return; + case IVL_LPM_RE_XOR: + draw_lpm_re(net, "xor"); + return; + case IVL_LPM_RE_NAND: + draw_lpm_re(net, "nand"); + return; + case IVL_LPM_RE_NOR: + draw_lpm_re(net, "nor"); + return; + case IVL_LPM_RE_XNOR: + draw_lpm_re(net, "xnor"); + return; + case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: draw_lpm_shiftl(net); @@ -1794,6 +1829,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.113 2005/02/03 04:56:21 steve + * laborate reduction gates into LPM_RED_ nodes. + * * Revision 1.112 2005/01/22 16:22:13 steve * LPM_CMP_NE/EQ are vectored devices. *