From cb5fc54b5e9c474460c88c793dc545ba1733bd39 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 4 Nov 1999 03:53:26 +0000 Subject: [PATCH] Patch to synthesize unary ~ and the ternary operator. Thanks to Larry Doolittle . Add the LPM_MUX device, and integrate it with the ternary synthesis from Larry. Replace the lpm_mux generator in t-xnf.cc to use XNF EQU devices to put muxs into function units. Rewrite elaborate_net for the PETernary class to also use the LPM_MUX device. --- design_dump.cc | 25 +++++++-- elab_net.cc | 50 +++++++++++++++++- elaborate.cc | 97 ++++++++++++----------------------- emit.cc | 19 ++++++- expr_synth.cc | 72 +++++++++++++++++++++++++- netlist.cc | 135 ++++++++++++++++++++++++++++++++++++++++++++++++- netlist.h | 77 ++++++++++++++++++++++++++-- t-xnf.cc | 43 +++++++++++++++- target.cc | 20 +++++++- target.h | 15 +++++- 10 files changed, 472 insertions(+), 81 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index f38df968c..d5f445f78 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 */ #if !defined(WINNT) -#ident "$Id: design_dump.cc,v 1.54 1999/11/04 01:12:41 steve Exp $" +#ident "$Id: design_dump.cc,v 1.55 1999/11/04 03:53:26 steve Exp $" #endif /* @@ -130,6 +130,13 @@ void NetAddSub::dump_node(ostream&o, unsigned ind) const dump_obj_attr(o, ind+4); } +void NetMux::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "Multiplexer (NetMux): " << name() << endl; + dump_node_pins(o, ind+4); + dump_obj_attr(o, ind+4); +} + void NetAssign::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Procedural assign (NetAssign): " << name(); @@ -709,8 +716,8 @@ void NetESignal::dump_node(ostream&o, unsigned ind) const void NetETernary::dump(ostream&o) const { - o << "(" << *cond_ << ")? (" << *true_val_ << ") : (" << - false_val_ << ")"; + o << "(" << *cond_ << ") ? (" << *true_val_ << ") : (" << + *false_val_ << ")"; } void NetEUFunc::dump(ostream&o) const @@ -811,6 +818,18 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.55 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.54 1999/11/04 01:12:41 steve * Elaborate combinational UDP devices. * diff --git a/elab_net.cc b/elab_net.cc index db277f9d6..024ba85e8 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.1 1999/10/31 20:08:24 steve Exp $" +#ident "$Id: elab_net.cc,v 1.2 1999/11/04 03:53:26 steve Exp $" #endif # include "PExpr.h" @@ -332,8 +332,56 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, const string&path, return osig; } +/* + * Elaborate the ternary operator in a netlist by creating a LPM_MUX + * with width matching the result, size == 2 and 1 select input. + */ +NetNet* PETernary::elaborate_net(Design*des, const string&path, + unsigned width, + unsigned long rise, + unsigned long fall, + unsigned long decay) const +{ + NetNet* expr_sig = expr_->elaborate_net(des, path, 0, 0, 0, 0); + NetNet* tru_sig = tru_->elaborate_net(des, path, width, 0, 0, 0); + NetNet* fal_sig = fal_->elaborate_net(des, path, width, 0, 0, 0); + if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) { + des->errors += 1; + return 0; + } + + assert(tru_sig->pin_count() == fal_sig->pin_count()); + assert(width == tru_sig->pin_count()); + assert(expr_sig->pin_count() == 1); + + NetNet*sig = new NetNet(des->local_symbol(path), NetNet::WIRE, + tru_sig->pin_count()); + sig->local_flag(true); + + NetMux*mux = new NetMux(des->local_symbol(path), width, 2, 1); + connect(mux->pin_Sel(0), expr_sig->pin(0)); + + for (unsigned idx = 0 ; idx < width ; idx += 1) { + connect(mux->pin_Result(idx), sig->pin(idx)); + connect(mux->pin_Data(idx,0), fal_sig->pin(idx)); + connect(mux->pin_Data(idx,1), tru_sig->pin(idx)); + } +} + /* * $Log: elab_net.cc,v $ + * Revision 1.2 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.1 1999/10/31 20:08:24 steve * Include subtraction in LPM_ADD_SUB device. * diff --git a/elaborate.cc b/elaborate.cc index 37ad2add3..3204c496d 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.120 1999/10/31 20:08:24 steve Exp $" +#ident "$Id: elaborate.cc,v 1.121 1999/11/04 03:53:26 steve Exp $" #endif /* @@ -935,69 +935,6 @@ NetNet* PENumber::elaborate_net(Design*des, const string&path, return net; } -NetNet* PETernary::elaborate_net(Design*des, const string&path, - unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay) const -{ - NetNet* expr_sig = expr_->elaborate_net(des, path, 0, 0, 0, 0); - NetNet* tru_sig = tru_->elaborate_net(des, path, width, 0, 0, 0); - NetNet* fal_sig = fal_->elaborate_net(des, path, width, 0, 0, 0); - if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) { - des->errors += 1; - return 0; - } - - NetNet* sig; - NetLogic*exprinv; - NetLogic*and_tru; - NetLogic*and_fal; - NetLogic*gate; - - assert(tru_sig->pin_count() == fal_sig->pin_count()); - assert(expr_sig->pin_count() == 1); - - sig = new NetNet(des->local_symbol(path), NetNet::WIRE, - tru_sig->pin_count()); - sig->local_flag(true); - - for (unsigned idx = 0 ; idx < tru_sig->pin_count() ; idx += 1) { - exprinv = new NetLogic(des->local_symbol(path), 2, NetLogic::NOT); - and_tru = new NetLogic(des->local_symbol(path), 3, NetLogic::AND); - and_fal = new NetLogic(des->local_symbol(path), 3, NetLogic::AND); - gate = new NetLogic(des->local_symbol(path), 3, NetLogic::OR); - - connect(exprinv->pin(1), expr_sig->pin(0)); - connect(and_tru->pin(1), expr_sig->pin(0)); - connect(and_fal->pin(1), exprinv->pin(0)); - connect(and_tru->pin(2), tru_sig->pin(idx)); - connect(and_fal->pin(2), fal_sig->pin(idx)); - connect(gate->pin(1), and_tru->pin(0)); - connect(gate->pin(2), and_fal->pin(0)); - connect(gate->pin(0), sig->pin(idx)); - - des->add_node(exprinv); - des->add_node(and_tru); - des->add_node(and_fal); - des->add_node(gate); - - gate->rise_time(rise); - gate->fall_time(fall); - gate->decay_time(decay); - } - - des->add_signal(sig); - - if (NetTmp*tmp = dynamic_cast(expr_sig)) - delete tmp; - if (NetTmp*tmp = dynamic_cast(tru_sig)) - delete tmp; - if (NetTmp*tmp = dynamic_cast(fal_sig)) - delete tmp; - - return sig; -} NetNet* PEUnary::elaborate_net(Design*des, const string&path, unsigned width, @@ -1172,8 +1109,24 @@ NetExpr* PExpr::elaborate_expr(Design*des, const string&path) const NetExpr* PEUnary::elaborate_expr(Design*des, const string&path) const { - NetEUnary*tmp = new NetEUnary(op_, expr_->elaborate_expr(des, path)); - tmp->set_line(*this); + NetExpr*ip = expr_->elaborate_expr(des, path); + if (ip == 0) return 0; + + /* Should we evaluate expressions ahead of time, + * just like in PEBinary::elaborate_expr() ? + */ + + NetEUnary*tmp; + switch (op_) { + default: + tmp = new NetEUnary(op_, ip); + tmp->set_line(*this); + break; + case '~': + tmp = new NetEUBits(op_, ip); + tmp->set_line(*this); + break; + } return tmp; } @@ -2404,6 +2357,18 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.121 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.120 1999/10/31 20:08:24 steve * Include subtraction in LPM_ADD_SUB device. * diff --git a/emit.cc b/emit.cc index d55319d9c..814c37127 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: emit.cc,v 1.25 1999/11/01 02:07:40 steve Exp $" +#ident "$Id: emit.cc,v 1.26 1999/11/04 03:53:26 steve Exp $" #endif /* @@ -75,6 +75,11 @@ void NetFF::emit_node(ostream&o, struct target_t*tgt) const tgt->lpm_ff(o, this); } +void NetMux::emit_node(ostream&o, struct target_t*tgt) const +{ + tgt->lpm_mux(o, this); +} + void NetNEvent::emit_node(ostream&o, struct target_t*tgt) const { tgt->net_event(o, this); @@ -362,6 +367,18 @@ bool emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.26 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.25 1999/11/01 02:07:40 steve * Add the synth functor to do generic synthesis * and add the LPM_FF device to handle rows of diff --git a/expr_synth.cc b/expr_synth.cc index 385583f12..3ef4b83fb 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: expr_synth.cc,v 1.1 1999/11/02 04:55:34 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.2 1999/11/04 03:53:26 steve Exp $" #endif # include "netlist.h" @@ -81,6 +81,64 @@ NetNet* NetEBBits::synthesize(Design*des) return osig; } +/* + * The bitwise unary logic operator (there is only one) is turned + * into discrete gates just as easily as the binary ones above. + */ +NetNet* NetEUBits::synthesize(Design*des) +{ + string path = des->local_symbol("SYNTH"); + NetNet*isig = expr_->synthesize(des); + + NetNet*osig = new NetNet(path, NetNet::IMPLICIT, isig->pin_count()); + + for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) { + string oname = des->local_symbol(path); + NetLogic*gate; + + switch (op()) { + case '~': + gate = new NetLogic(oname, 2, NetLogic::NOT); + break; + default: + assert(0); + } + + connect(osig->pin(idx), gate->pin(0)); + connect(isig->pin(idx), gate->pin(1)); + + des->add_node(gate); + } + des->add_signal(osig); + return osig; +} + + +NetNet* NetETernary::synthesize(Design *des) +{ + string path = des->local_symbol("SYNTH"); + NetNet*csig = cond_->synthesize(des); + NetNet*tsig = true_val_->synthesize(des); + NetNet*fsig = false_val_->synthesize(des); + + assert(csig->pin_count() == 1); + assert(tsig->pin_count() == fsig->pin_count()); + unsigned width=tsig->pin_count(); + NetNet*osig = new NetNet(path, NetNet::IMPLICIT, width); + + string oname = des->local_symbol(path); + NetMux *mux = new NetMux(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)); + } + des->add_node(mux); + connect(csig->pin(0), mux->pin_Sel(0)); + des->add_signal(osig); + return osig; +} + NetNet* NetESignal::synthesize(Design*des) { NetNet*sig = new NetNet(name(), NetNet::WIRE, pin_count()); @@ -92,6 +150,18 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.2 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.1 1999/11/02 04:55:34 steve * Add the synthesize method to NetExpr to handle * synthesis of expressions, and use that method diff --git a/netlist.cc b/netlist.cc index aecdb4d4b..b809994bd 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.cc,v 1.81 1999/11/04 01:12:42 steve Exp $" +#ident "$Id: netlist.cc,v 1.82 1999/11/04 03:53:26 steve Exp $" #endif # include @@ -576,6 +576,118 @@ const NetObj::Link& NetAddSub::pin_Result(unsigned idx) const return pin(idx); } +/* + * 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] + */ + +NetMux::NetMux(const string&n, unsigned wi, unsigned si, unsigned sw) +: NetNode(n, 2+wi+sw+wi*si), width_(wi), size_(si), swidth_(sw) +{ + pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_name("Aclr", 0); + pin(1).set_dir(NetObj::Link::INPUT); pin(0).set_name("Clock", 0); + + for (unsigned idx = 0 ; idx < width_ ; idx += 1) { + pin_Result(idx).set_dir(NetObj::Link::OUTPUT); + pin_Result(idx).set_name("Result", idx); + + for (unsigned jdx = 0 ; jdx < size_ ; jdx += 1) { + pin_Data(idx,jdx).set_dir(Link::INPUT); + pin_Data(idx,jdx).set_name("Data", jdx*width_+idx); + } + } + + for (unsigned idx = 0 ; idx < swidth_ ; idx += 1) { + pin_Sel(idx).set_dir(Link::OUTPUT); + pin_Sel(idx).set_name("Sel", idx); + } +} + +NetMux::~NetMux() +{ +} + +unsigned NetMux::width()const +{ + return width_; +} + +unsigned NetMux::size() const +{ + return size_; +} + +unsigned NetMux::sel_width() const +{ + return swidth_; +} + +NetObj::Link& NetMux::pin_Aclr() +{ + return pin(0); +} + +const NetObj::Link& NetMux::pin_Aclr() const +{ + return pin(0); +} + +NetObj::Link& NetMux::pin_Clock() +{ + return pin(1); +} + +const NetObj::Link& NetMux::pin_Clock() const +{ + return pin(1); +} + +NetObj::Link& NetMux::pin_Result(unsigned w) +{ + assert(w < width_); + return pin(2+w); +} + +const NetObj::Link& NetMux::pin_Result(unsigned w) const +{ + assert(w < width_); + return pin(2+w); +} + +NetObj::Link& NetMux::pin_Sel(unsigned w) +{ + assert(w < swidth_); + return pin(2+width_+w); +} + +const NetObj::Link& NetMux::pin_Sel(unsigned w) const +{ + assert(w < swidth_); + return pin(2+width_+w); +} + +NetObj::Link& NetMux::pin_Data(unsigned w, unsigned s) +{ + assert(w < width_); + assert(s < size_); + return pin(2+width_+swidth_+s*width_+w); +} + +const NetObj::Link& NetMux::pin_Data(unsigned w, unsigned s) const +{ + assert(w < width_); + assert(s < size_); + return pin(2+width_+swidth_+s*width_+w); +} + +/* + * NetAssign + */ + NetAssign_::NetAssign_(const string&n, unsigned w) : NetNode(n, w), rval_(0), bmux_(0) { @@ -1340,6 +1452,15 @@ NetEUnary* NetEUnary::dup_expr() const assert(0); } +NetEUBits::NetEUBits(char op, NetExpr*ex) +: NetEUnary(op, ex) +{ +} + +NetEUBits::~NetEUBits() +{ +} + NetForever::NetForever(NetProc*p) : statement_(p) { @@ -1969,6 +2090,18 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.82 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.81 1999/11/04 01:12:42 steve * Elaborate combinational UDP devices. * diff --git a/netlist.h b/netlist.h index aebbc9c20..cd6a7cb7f 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.84 1999/11/04 01:12:42 steve Exp $" +#ident "$Id: netlist.h,v 1.85 1999/11/04 03:53:26 steve Exp $" #endif /* @@ -357,6 +357,7 @@ class NetFF : public NetNode { virtual void functor_node(Design*des, functor_t*fun); }; + /* * This class represents the declared memory object. The parser * creates one of these for each declared memory in the elaborated @@ -395,6 +396,49 @@ class NetMemory { map attributes_; }; +/* + * This class represents an LPM_MUX device. This device has some + * number of Result points (the width of the device) and some number + * of input choices. There is also a selector of some width. The + * parameters are: + * + * width -- Width of the result and each possible Data input + * size -- Number of Data input (each of width) + * selw -- Width in bits of the select input + */ +class NetMux : public NetNode { + + public: + NetMux(const string&n, unsigned width, unsigned size, unsigned selw); + ~NetMux(); + + unsigned width() const; + unsigned size() const; + unsigned sel_width() const; + + NetObj::Link& pin_Aclr(); + NetObj::Link& pin_Clock(); + + NetObj::Link& pin_Result(unsigned); + NetObj::Link& pin_Data(unsigned wi, unsigned si); + NetObj::Link& pin_Sel(unsigned); + + const NetObj::Link& pin_Aclr() const; + const NetObj::Link& pin_Clock() const; + + const NetObj::Link& pin_Result(unsigned) const; + const NetObj::Link& pin_Data(unsigned, unsigned) const; + const NetObj::Link& pin_Sel(unsigned) const; + + virtual void dump_node(ostream&, unsigned ind) const; + virtual void emit_node(ostream&, struct target_t*) const; + + private: + unsigned width_; + unsigned size_; + unsigned swidth_; +}; + /* ========= * There are cases where expressions need to be represented. The * NetExpr class is the root of a heirarchy that serves that purpose. @@ -1509,6 +1553,7 @@ class NetETernary : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; + virtual NetNet*synthesize(Design*); private: NetExpr*cond_; @@ -1527,9 +1572,9 @@ class NetETernary : public NetExpr { * ^ -- Reduction XOR * + -- * - -- - * A -- Reduciton NAND (~&) - * N -- Reduciton NOR (~|) - * X -- Reduciton NXOR (~^ or ^~) + * A -- Reduction NAND (~&) + * N -- Reduction NOR (~|) + * X -- Reduction NXOR (~^ or ^~) */ class NetEUnary : public NetExpr { @@ -1547,11 +1592,21 @@ class NetEUnary : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; - private: + protected: char op_; NetExpr* expr_; }; +class NetEUBits : public NetEUnary { + + public: + NetEUBits(char op, NetExpr*ex); + ~NetEUBits(); + + virtual NetNet* synthesize(Design*); + +}; + /* System identifiers are represented here. */ class NetEIdent : public NetExpr { @@ -1799,6 +1854,18 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.85 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.84 1999/11/04 01:12:42 steve * Elaborate combinational UDP devices. * diff --git a/t-xnf.cc b/t-xnf.cc index a9b2df860..33bf22f60 100644 --- a/t-xnf.cc +++ b/t-xnf.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-xnf.cc,v 1.10 1999/11/02 04:55:34 steve Exp $" +#ident "$Id: t-xnf.cc,v 1.11 1999/11/04 03:53:26 steve Exp $" #endif /* XNF BACKEND @@ -72,6 +72,7 @@ class target_xnf : public target_t { void signal(ostream&os, const NetNet*); void lpm_ff(ostream&os, const NetFF*); + void lpm_mux(ostream&os, const NetMux*); void logic(ostream&os, const NetLogic*); void bufz(ostream&os, const NetBUFZ*); @@ -287,6 +288,34 @@ void target_xnf::lpm_ff(ostream&os, const NetFF*net) } } +/* + * Generate an LPM_MUX. + * + * XXXX NOTE: For now, this only supports combinational LPM_MUX + * devices that have a single select input. These are typically + * generated from ?: expressions. + */ +void target_xnf::lpm_mux(ostream&os, const NetMux*net) +{ + assert(net->sel_width() == 1); + assert(net->size() == 2); + + for (unsigned idx = 0 ; idx < net->width() ; idx += 1) { + + os << "SYM, " << mangle(net->name()) << "<" << idx << ">" + << " EQN, EQN=(I0 * I2) + (~I0 * I1)" << endl; + + draw_pin(os, "I0", net->pin_Sel(0)); + draw_pin(os, "I1", net->pin_Data(idx,0)); + draw_pin(os, "I2", net->pin_Data(idx,1)); + draw_pin(os, "O", net->pin_Result(idx)); + + os << "END" << endl; + } + +} + + /* * The logic gates I know so far can be translated directly into XNF * standard symbol types. This is a fairly obvious transformation. @@ -382,6 +411,18 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj }; /* * $Log: t-xnf.cc,v $ + * Revision 1.11 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.10 1999/11/02 04:55:34 steve * Add the synthesize method to NetExpr to handle * synthesis of expressions, and use that method diff --git a/target.cc b/target.cc index 70b872bef..3a88ea948 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.cc,v 1.22 1999/11/01 02:07:41 steve Exp $" +#ident "$Id: target.cc,v 1.23 1999/11/04 03:53:26 steve Exp $" #endif # include "target.h" @@ -81,6 +81,12 @@ void target_t::lpm_ff(ostream&, const NetFF*) "Unhandled NetFF." << endl; } +void target_t::lpm_mux(ostream&, const NetMux*) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled NetMux." << endl; +} + void target_t::net_assign(ostream&os, const NetAssign*) { } @@ -281,6 +287,18 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.23 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.22 1999/11/01 02:07:41 steve * Add the synth functor to do generic synthesis * and add the LPM_FF device to handle rows of diff --git a/target.h b/target.h index e19398ca2..e35d91622 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.h,v 1.21 1999/11/01 02:07:41 steve Exp $" +#ident "$Id: target.h,v 1.22 1999/11/04 03:53:26 steve Exp $" #endif # include "netlist.h" @@ -68,6 +68,7 @@ struct target_t { /* LPM style components are handled here. */ virtual void lpm_add_sub(ostream&os, const NetAddSub*); virtual void lpm_ff(ostream&os, const NetFF*); + virtual void lpm_mux(ostream&os, const NetMux*); /* Output a gate (called for each gate) */ virtual void logic(ostream&os, const NetLogic*); @@ -138,6 +139,18 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.22 1999/11/04 03:53:26 steve + * Patch to synthesize unary ~ and the ternary operator. + * Thanks to Larry Doolittle . + * + * Add the LPM_MUX device, and integrate it with the + * ternary synthesis from Larry. Replace the lpm_mux + * generator in t-xnf.cc to use XNF EQU devices to + * put muxs into function units. + * + * Rewrite elaborate_net for the PETernary class to + * also use the LPM_MUX device. + * * Revision 1.21 1999/11/01 02:07:41 steve * Add the synth functor to do generic synthesis * and add the LPM_FF device to handle rows of