From d54cc14ca26089c31abdd998270a1d060d7ddcfb Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 16 Dec 1999 02:42:14 +0000 Subject: [PATCH] Simulate carry output on adders. --- elab_net.cc | 17 ++++++++++++++--- netlist.cc | 15 ++++++++++++++- netlist.h | 6 +++++- t-vvm.cc | 19 ++++++++++++++++--- t-xnf.cc | 7 +++++-- vvm/vvm_gates.h | 19 +++++++++++++++++-- 6 files changed, 71 insertions(+), 12 deletions(-) diff --git a/elab_net.cc b/elab_net.cc index 437a07ee7..7ab6efb92 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.11 1999/12/02 04:08:10 steve Exp $" +#ident "$Id: elab_net.cc,v 1.12 1999/12/16 02:42:14 steve Exp $" #endif # include "PExpr.h" @@ -236,8 +236,14 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, const string&path, if (rsig->pin_count() > lsig->pin_count()) width = rsig->pin_count(); + // If the desired output size if creater then the largest + // operand, then include the carry of the adder as an output. + unsigned owidth = width; + if (lwidth > owidth) + owidth = width + 1; + // Make the adder as wide as the widest operand - osig = new NetNet(0, des->local_symbol(path), NetNet::WIRE, width); + osig = new NetNet(0, des->local_symbol(path), NetNet::WIRE, owidth); NetAddSub*adder = new NetAddSub(name, width); // Connect the adder to the various parts. @@ -245,8 +251,10 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, const string&path, connect(lsig->pin(idx), adder->pin_DataA(idx)); for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1) connect(rsig->pin(idx), adder->pin_DataB(idx)); - for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) + for (unsigned idx = 0 ; idx < width ; idx += 1) connect(osig->pin(idx), adder->pin_Result(idx)); + if (owidth > width) + connect(osig->pin(width), adder->pin_Cout()); gate = adder; des->add_signal(osig); @@ -898,6 +906,9 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path, /* * $Log: elab_net.cc,v $ + * Revision 1.12 1999/12/16 02:42:14 steve + * Simulate carry output on adders. + * * Revision 1.11 1999/12/02 04:08:10 steve * Elaborate net repeat concatenations. * diff --git a/netlist.cc b/netlist.cc index 6d5d4b1b3..9aef91940 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.99 1999/12/05 19:30:43 steve Exp $" +#ident "$Id: netlist.cc,v 1.100 1999/12/16 02:42:15 steve Exp $" #endif # include @@ -642,6 +642,16 @@ unsigned NetAddSub::width()const return (pin_count() - 6) / 3; } +NetObj::Link& NetAddSub::pin_Cout() +{ + return pin(4); +} + +const NetObj::Link& NetAddSub::pin_Cout() const +{ + return pin(4); +} + NetObj::Link& NetAddSub::pin_DataA(unsigned idx) { idx = 6 + idx*3; @@ -2734,6 +2744,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.100 1999/12/16 02:42:15 steve + * Simulate carry output on adders. + * * Revision 1.99 1999/12/05 19:30:43 steve * Generate XNF RAMS from synthesized memories. * diff --git a/netlist.h b/netlist.h index ffb417bee..690236ed4 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.101 1999/12/12 06:03:14 steve Exp $" +#ident "$Id: netlist.h,v 1.102 1999/12/16 02:42:15 steve Exp $" #endif /* @@ -321,6 +321,7 @@ class NetAddSub : public NetNode { NetObj::Link& pin_DataB(unsigned idx); NetObj::Link& pin_Result(unsigned idx); + const NetObj::Link& pin_Cout() const; const NetObj::Link& pin_DataA(unsigned idx) const; const NetObj::Link& pin_DataB(unsigned idx) const; const NetObj::Link& pin_Result(unsigned idx) const; @@ -2069,6 +2070,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.102 1999/12/16 02:42:15 steve + * Simulate carry output on adders. + * * Revision 1.101 1999/12/12 06:03:14 steve * Allow memories without indices in expressions. * diff --git a/t-vvm.cc b/t-vvm.cc index a82d993f3..2140a38f1 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.90 1999/12/12 19:47:54 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.91 1999/12/16 02:42:15 steve Exp $" #endif # include @@ -911,6 +911,15 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) emit_gate_outputfun_(gate, pin); } + // Connect the carry output if necessary. + if (gate->pin_Cout().is_linked()) { + unsigned pin = gate->pin_Cout().get_pin(); + string outfun = defn_gate_outputfun_(os, gate, pin); + init_code << " " << mangle(gate->name()) << + ".config_cout(&" << outfun << ");" << endl; + emit_gate_outputfun_(gate, pin); + } + if (gate->attribute("LPM_Direction") == "ADD") { init_code << " " << mangle(gate->name()) << ".init_Add_Sub(0, V1);" << endl; @@ -920,6 +929,8 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) ".init_Add_Sub(0, V0);" << endl; } + + start_code << " " << mangle(gate->name()) << ".start();" << endl; } void target_vvm::lpm_clshift(ostream&os, const NetCLShift*gate) @@ -1071,8 +1082,7 @@ void target_vvm::logic(ostream&os, const NetLogic*gate) emit_gate_outputfun_(gate, 0); - start_code << " " << mangle(gate->name()) << - ".start();" << endl; + start_code << " " << mangle(gate->name()) << ".start();" << endl; } void target_vvm::bufz(ostream&os, const NetBUFZ*gate) @@ -1955,6 +1965,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.91 1999/12/16 02:42:15 steve + * Simulate carry output on adders. + * * Revision 1.90 1999/12/12 19:47:54 steve * Remove the useless vvm_simulation class. * diff --git a/t-xnf.cc b/t-xnf.cc index 112341587..e84422925 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.19 1999/12/05 19:30:43 steve Exp $" +#ident "$Id: t-xnf.cc,v 1.20 1999/12/16 02:42:15 steve Exp $" #endif /* XNF BACKEND @@ -465,7 +465,7 @@ void target_xnf::lpm_add_sub(ostream&os, const NetAddSub*gate) unsigned width = gate->width(); // Don't handle carry output yet - // assert (count_outputs(gate->pin_Cout())==0); + assert (! gate->pin_Cout().is_linked()); unsigned carry_width = width-1; /* Make the force-0 cary mode object to initialize the bottom @@ -687,6 +687,9 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj }; /* * $Log: t-xnf.cc,v $ + * Revision 1.20 1999/12/16 02:42:15 steve + * Simulate carry output on adders. + * * Revision 1.19 1999/12/05 19:30:43 steve * Generate XNF RAMS from synthesized memories. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index 8ccab4036..db444cb30 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_gates.h,v 1.32 1999/12/12 19:47:54 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.33 1999/12/16 02:42:15 steve Exp $" #endif # include "vvm.h" @@ -81,10 +81,16 @@ class vvm_1bit_out { template class vvm_add_sub { public: - vvm_add_sub() : ndir_(V0) { } + vvm_add_sub() : ndir_(V0), co_(0) { } void config_rout(unsigned idx, vvm_out_event::action_t a) { o_[idx] = a; + r_[idx] = Vx; + } + + void config_cout(vvm_out_event::action_t a) + { co_ = a; + c_ = Vx; } void init_DataA(unsigned idx, vpip_bit_t val) @@ -99,6 +105,8 @@ template class vvm_add_sub { { ndir_ = not(val); } + void start() { compute_(); } + void set_DataA(unsigned idx, vpip_bit_t val) { a_[idx] = val; compute_(); @@ -112,12 +120,14 @@ template class vvm_add_sub { vpip_bit_t a_[WIDTH]; vpip_bit_t b_[WIDTH]; vpip_bit_t r_[WIDTH]; + vpip_bit_t c_; // this is the inverse of the Add_Sub port. It is 0 for add, // and 1 for subtract. vpip_bit_t ndir_; vvm_out_event::action_t o_[WIDTH]; + vvm_out_event::action_t co_; void compute_() { vpip_bit_t carry = ndir_; @@ -130,6 +140,8 @@ template class vvm_add_sub { vvm_event*ev = new vvm_out_event(val, o_[idx]); ev->schedule(); } + if (co_ && (carry != c_)) + (new vvm_out_event(carry, co_)) -> schedule(); } }; @@ -921,6 +933,9 @@ template class vvm_pevent { /* * $Log: vvm_gates.h,v $ + * Revision 1.33 1999/12/16 02:42:15 steve + * Simulate carry output on adders. + * * Revision 1.32 1999/12/12 19:47:54 steve * Remove the useless vvm_simulation class. *