diff --git a/t-vvm.cc b/t-vvm.cc index e264249dc..35b34513e 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) && !defined(macintosh) -#ident "$Id: t-vvm.cc,v 1.115 2000/03/17 20:21:14 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.116 2000/03/18 01:26:59 steve Exp $" #endif # include @@ -135,7 +135,9 @@ class target_vvm : public target_t { // of things that may be scanned multiple times. mapesignal_printed_flag; mappevent_printed_flag; - mapnexus_printed_flag; + + mapnexus_wire_map; + unsigned nexus_wire_counter; // String constants that are made into vpiHandles have th // handle name mapped by this. @@ -670,6 +672,7 @@ void target_vvm::start_design(ostream&os, const Design*mod) process_counter = 0; string_counter = 1; number_counter = 1; + nexus_wire_counter = 1; init_code << "static void design_init()" << endl; init_code << "{" << endl; @@ -714,8 +717,10 @@ void target_vvm::end_design(ostream&os, const Design*mod) string_counter+1 << "];" << endl; os << "static struct __vpiNumberConst number_table[" << number_counter+1 << "];" << endl; - + os << "static vvm_nexus_wire nexus_wire_table[" << + nexus_wire_counter << "];" << endl; defn.close(); + os << "// **** Definition code" << endl; { ifstream rdefn (defn_name); os << rdefn.rdbuf(); @@ -803,15 +808,15 @@ void target_vvm::signal(ostream&os, const NetNet*sig) string net_name = mangle(sig->name()); for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&sig->pin(idx))); - - if (! nexus_printed_flag[nexus]) { - nexus_printed_flag[nexus] = true; - os << "vvm_nexus_wire " << nexus << "_nex;" << endl; + string nexus = nexus_from_link(&sig->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + if (ncode == 0) { + nexus_wire_map[nexus] = ncode = nexus_wire_counter; + nexus_wire_counter += 1; } - init_code << " " << nexus << "_nex.connect(&" << - net_name << ", " << idx << ");" << endl; + init_code << " nexus_wire_table[" << ncode << + "].connect(&" << net_name << ", " << idx << ");" << endl; } os << "static vvm_bitset_t<" << sig->pin_count() << "> " << @@ -1020,9 +1025,9 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) /* Connect the DataA inputs. */ for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) { - unsigned pin = gate->pin_DataA(idx).get_pin(); - string nexus = mangle(nexus_from_link(&gate->pin(pin))); - init_code << " " << nexus << "_nex.connect(&" << + string nexus = nexus_from_link(&gate->pin_DataA(idx)); + unsigned ncode = nexus_wire_map[nexus]; + init_code << " nexus_wire_table["<name()) << ", " << mangle(gate->name()) << ".key_DataA(" << idx << "));" << endl; @@ -1031,9 +1036,10 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) /* Connect the DataB inputs. */ for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) { - unsigned pin = gate->pin_DataB(idx).get_pin(); - string nexus = mangle(nexus_from_link(&gate->pin(pin))); - init_code << " " << nexus << "_nex.connect(&" << + string nexus = nexus_from_link(&gate->pin_DataB(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()) << ", " << mangle(gate->name()) << ".key_DataB(" << idx << "));" << endl; @@ -1042,18 +1048,20 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) /* Connect the outputs of the adder. */ for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) { - unsigned pin = gate->pin_Result(idx).get_pin(); - string nexus = mangle(nexus_from_link(&gate->pin(pin))); - init_code << " " << nexus << "_nex.connect(" << + string nexus = nexus_from_link(&gate->pin_Result(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()) << ".config_rout(" << idx << "));" << endl; } // Connect the carry output if necessary. if (gate->pin_Cout().is_linked()) { - unsigned pin = gate->pin_Cout().get_pin(); - string nexus = mangle(nexus_from_link(&gate->pin(pin))); - init_code << " " << nexus << "_nex.connect(" << + string nexus = nexus_from_link(&gate->pin_Cout()); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()) << ".config_cout());" << endl; } @@ -1072,32 +1080,39 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) void target_vvm::lpm_clshift(ostream&os, const NetCLShift*gate) { - os << "static vvm_clshift " << mangle(gate->name()) << "(" << + string mname = mangle(gate->name()); + + os << "static vvm_clshift " << mname << "(" << gate->width() << "," << gate->width_dist() << ");" << endl; /* Connect the Data input pins... */ for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin_Data(idx))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ", " << mangle(gate->name()) + string nexus = nexus_from_link(&gate->pin_Data(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width_dist() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin_Distance(idx))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ", " << mangle(gate->name()) + string nexus = nexus_from_link(&gate->pin_Distance(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin_Result(idx))); - init_code << " " << nexus << "_nex.connect(" << - mangle(gate->name()) << ".config_rout(" << idx << - "));" << endl; + string nexus = nexus_from_link(&gate->pin_Result(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin_DataA(idx))); - init_code << " " << nexus << "_nex.connect(&" << mname - << ", " << mname << ".key_DataA(" << idx + string nexus = nexus_from_link(&gate->pin_DataA(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin_DataB(idx))); - init_code << " " << nexus << "_nex.connect(&" << mname - << ", " << mname << ".key_DataB(" << idx + string nexus = nexus_from_link(&gate->pin_DataB(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<pin_ALB().is_linked()) { - string nexus = mangle(nexus_from_link(&gate->pin_ALB())); - init_code << " " << nexus << "_nex.connect(" << mname - << ".config_ALB_out());" << endl; + string nexus = nexus_from_link(&gate->pin_ALB()); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<pin_AGB().is_linked()) { - string nexus = mangle(nexus_from_link(&gate->pin_AGB())); - init_code << " " << nexus << "_nex.connect(" << mname - << ".config_AGB_out());" << endl; + string nexus = nexus_from_link(&gate->pin_AGB()); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<pin_ALEB().is_linked()) { - string nexus = mangle(nexus_from_link(&gate->pin_ALEB())); - init_code << " " << nexus << "_nex.connect(" << mname - << ".config_ALEB_out());" << endl; + string nexus = nexus_from_link(&gate->pin_ALEB()); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<pin_AGEB().is_linked()) { - string nexus = mangle(nexus_from_link(&gate->pin_AGEB())); - init_code << " " << nexus << "_nex.connect(" << mname - << ".config_AGEB_out());" << endl; + string nexus = nexus_from_link(&gate->pin_AGEB()); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()); + os << "static vvm_mult " << mname << "(" << mul->width_r() << "," << mul->width_a() << "," << mul->width_b() << "," << mul->width_s() << ");" << endl; @@ -1176,7 +1204,9 @@ void target_vvm::lpm_mult(ostream&os, const NetMult*mul) /* Connect the DataA inputs... */ for (unsigned idx = 0 ; idx < mul->width_a() ; idx += 1) { string nexus = nexus_from_link(&mul->pin_DataA(idx)); - init_code << " " << mangle(nexus) << "_nex.connect(&" + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width_b() ; idx += 1) { string nexus = nexus_from_link(&mul->pin_DataB(idx)); - init_code << " " << mangle(nexus) << "_nex.connect(&" + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width_r() ; idx += 1) { string nexus = nexus_from_link(&mul->pin_Result(idx)); - init_code << " " << mangle(nexus) << "_nex.connect(" + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()); - os << "static vvm_mux<" << mux->width() << "," << mux->size() << - "," << mux->sel_width() << "> " << mname << ";" << endl; + + os << "static vvm_mux " << mname << "(" << mux->width() << "," + << mux->size() << "," << mux->sel_width() << ");" << endl; /* Connect the select inputs... */ for (unsigned idx = 0 ; idx < mux->sel_width() ; idx += 1) { - string nexus = mangle(nexus_from_link(&mux->pin_Sel(idx))); - init_code << " " << nexus << "_nex.connect(&" - << mangle(mux->name()) << ", " << mangle(mux->name()) + string nexus = nexus_from_link(&mux->pin_Sel(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<size() ; idx += 1) { for (unsigned wid = 0 ; wid < mux->width() ; wid += 1) { - string nexus = mangle(nexus_from_link(&mux->pin_Data(wid, idx))); - init_code << " " << nexus << "_nex.connect(&" - << mangle(mux->name()) << ", " - << mangle(mux->name()) << ".key_Data(" + string nexus = nexus_from_link(&mux->pin_Data(wid, idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<width() ; idx += 1) { - string nexus = mangle(nexus_from_link(&mux->pin_Result(idx))); - init_code << " " << nexus << "_nex.connect(" << - mangle(mux->name()) << ".config_rout(" << idx << - "));" << endl; + string nexus = nexus_from_link(&mux->pin_Result(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name() << "." << endl; - { string nexus = mangle(nexus_from_link(&gate->pin(0))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ");" << endl; + { string nexus = nexus_from_link(&gate->pin(0)); + unsigned ncode = nexus_wire_map[nexus]; + init_code << " nexus_wire_table[" << ncode << + "].connect(&" << mangle(gate->name()) << ");" << endl; } for (unsigned idx = 1 ; idx < gate->pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin(idx))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ", " << (idx-1) << ");" << endl; + string nexus = nexus_from_link(&gate->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + init_code << " nexus_wire_table[" << ncode + << "].connect(&" << mangle(gate->name()) << ", " + << (idx-1) << ");" << endl; } } @@ -1408,29 +1451,34 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net) void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate) { + string mname = mangle(gate->name()); string nexus; + unsigned ncode; assert(gate->pin_count() == 3); - os << "static vvm_eeq " << mangle(gate->name()) << "(" << + os << "static vvm_eeq " << mname << "(" << gate->rise_time() << ");" << endl; /* Connect the output pin */ - nexus = mangle(nexus_from_link(&gate->pin(0))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ");" << endl; + nexus = nexus_from_link(&gate->pin(0)); + ncode = nexus_wire_map[nexus]; + init_code << " nexus_wire_table["<pin(1))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ", 0);" << endl; + nexus = nexus_from_link(&gate->pin(1)); + ncode = nexus_wire_map[nexus]; + init_code << " nexus_wire_table["<pin(2))); - init_code << " " << nexus << "_nex.connect(&" << - mangle(gate->name()) << ", 1);" << endl; + nexus = nexus_from_link(&gate->pin(2)); + ncode = nexus_wire_map[nexus]; + init_code << " nexus_wire_table["<name()) << ".start();" << endl; + start_code << " " << mname << ".start();" << endl; } /* @@ -1487,8 +1535,10 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate) source. Write the connect calls into the init code. */ for (unsigned idx = 0 ; idx < gate->pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&gate->pin(idx))); - init_code << " " << nexus << "_nex.connect(&" << + string nexus = nexus_from_link(&gate->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()) << ", " << idx << ");" << endl; } } @@ -1538,8 +1588,9 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net) const verinum value = rc->value(); for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&net->pin(idx))); - defn << " " << nexus << "_nex.reg_assign("; + string nexus = nexus_from_link(&net->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + defn << " nexus_wire_table[" <bmux()) { - //XXXX Not updated to nexus style?? - // This is a bit select. Assign the low bit of the rval // to the selected bit of the lval. string bval = emit_proc_rval(defn, 8, net->bmux()); @@ -1574,43 +1623,26 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net) defn << " switch (" << bval << ".as_unsigned()) {" << endl; for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { - const NetObj*cur; - unsigned pin; - map written; + + string nexus = nexus_from_link(&net->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; defn << " case " << idx << ":" << endl; - for (net->pin(idx).next_link(cur, pin) - ; net->pin(idx) != cur->pin(pin) - ; cur->pin(pin).next_link(cur, pin)) { - - // Skip output only pins. - if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT) - continue; - - // It is possible for a named device to show up - // several times in a link. This is the classic - // case with NetESignal objects, which are - // repeated for each expression that uses it. - if (written[cur->name()]) - continue; - - written[cur->name()] = true; - defn << " " << mangle(cur->name()) << - ".set_" << cur->pin(pin).get_name() << - "(" << cur->pin(pin).get_inst() << - ", " << rval << "[0]);" << endl; - } - + defn << " nexus_wire_table["<pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&net->pin(idx))); - defn << " " << nexus << "_nex.reg_assign(" << - rval << "[" << idx << "]);" << endl; + string nexus = nexus_from_link(&net->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + defn << " nexus_wire_table["<pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&net->pin(idx))); + string nexus = nexus_from_link(&net->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; defn << " case " << idx << ":" << endl; - defn << " vvm_delyed_assign(" << nexus << - "_nex, " << rval << ", " << delay << ");" << endl; + defn << " vvm_delayed_assign(nexus_wire_table[" + << ncode << "], " << rval << ", " << delay << ");" + << endl; defn << " break;" << endl; } @@ -1676,10 +1710,11 @@ void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net) } else { for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { - string nexus = mangle(nexus_from_link(&net->pin(idx))); - defn << " vvm_delayed_assign(" << nexus << - "_nex, " << rval << "[" << idx << "], " << - delay << ");" << endl; + string nexus = nexus_from_link(&net->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + defn << " vvm_delayed_assign(nexus_wire_table[" + << ncode << "], " << rval << "[" << idx << "], " + << delay << ");" << endl; } } } @@ -2245,6 +2280,17 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.116 2000/03/18 01:26:59 steve + * Generate references into a table of nexus objects instead of + * generating lots of isolated nexus objects. Easier on linkers + * and compilers, + * + * Add missing nexus support for l-value bit selects, + * + * Detemplatize the vvm_mux type. + * + * Fix up the vvm_nexus destructor to disconnect from drivers. + * * Revision 1.115 2000/03/17 20:21:14 steve * Detemplatize the vvm_signal_t class. * diff --git a/vvm/Makefile.in b/vvm/Makefile.in index dad5cdf0c..917338b84 100644 --- a/vvm/Makefile.in +++ b/vvm/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.23 2000/03/17 17:25:53 steve Exp $" +#ident "$Id: Makefile.in,v 1.24 2000/03/18 01:26:59 steve Exp $" # # SHELL = /bin/sh @@ -60,7 +60,7 @@ all: libvvm.a O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \ vvm_event.o \ -vvm_func.o vvm_gates.o vvm_mult.o \ +vvm_func.o vvm_gates.o vvm_mult.o vvm_mux.o \ vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vpip.o P = vpi_callback.o \ diff --git a/vvm/vvm_gates.cc b/vvm/vvm_gates.cc index 6f5da7e31..db348aaa9 100644 --- a/vvm/vvm_gates.cc +++ b/vvm/vvm_gates.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_gates.cc,v 1.9 2000/03/17 19:24:00 steve Exp $" +#ident "$Id: vvm_gates.cc,v 1.10 2000/03/18 01:27:00 steve Exp $" #endif # include "vvm_gates.h" @@ -94,46 +94,6 @@ vpip_bit_t compute_xnor(const vpip_bit_t*inp, unsigned count) return v_not(compute_xor(inp,count)); } -void compute_mux(vpip_bit_t*out, unsigned wid, - const vpip_bit_t*sel, unsigned swid, - const vpip_bit_t*dat, unsigned size) -{ - unsigned tmp = 0; - for (unsigned idx = 0 ; idx < swid ; idx += 1) - switch (sel[idx]) { - case V0: - break; - case V1: - tmp |= (1<= size) { - - if (swid > 1) { - for (unsigned idx = 0; idx < wid ; idx += 1) - out[idx] = Vx; - } else { - const unsigned b0 = 0; - const unsigned b1 = wid; - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - if (dat[idx+b0] == dat[idx+b1]) - out[idx] = dat[idx+b0]; - else - out[idx] = Vx; - } - } - - } else { - unsigned b = tmp * wid; - for (unsigned idx = 0; idx < wid ; idx += 1) - out[idx] = dat[idx+b]; - } -} - vvm_and2::vvm_and2(unsigned long d) : vvm_1bit_out(d) { @@ -298,6 +258,17 @@ void vvm_not::take_value(unsigned, vpip_bit_t val) /* * $Log: vvm_gates.cc,v $ + * Revision 1.10 2000/03/18 01:27:00 steve + * Generate references into a table of nexus objects instead of + * generating lots of isolated nexus objects. Easier on linkers + * and compilers, + * + * Add missing nexus support for l-value bit selects, + * + * Detemplatize the vvm_mux type. + * + * Fix up the vvm_nexus destructor to disconnect from drivers. + * * Revision 1.9 2000/03/17 19:24:00 steve * nor2 and and2 optimized gates. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index a46194ea2..9c7167418 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) && !defined(macintosh) -#ident "$Id: vvm_gates.h,v 1.45 2000/03/17 19:24:00 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.46 2000/03/18 01:27:00 steve Exp $" #endif # include "vvm.h" @@ -328,70 +328,36 @@ class vvm_mult : public vvm_nexus::recvr_t { /* * This class supports mux devices. The width is the width of the data * (or bus) path, SIZE is the number of alternative inputs and SELWID - * is the size (in bits) of the selector input. + * is the size (in bits) of the selector input. The device passes to + * the output the bits of the input selected by the selector. */ -template class vvm_mux : public vvm_nexus::recvr_t { public: - explicit vvm_mux() - { unsigned idx; - for (idx = 0 ; idx < WIDTH ; idx += 1) output_[idx] = Vx; - for (idx = 0 ; idx < SELWID; idx += 1) sel_[idx] = Vx; - for (idx = 0 ; idx < WIDTH*SIZE; idx += 1) input_[idx] = Vx; - } + explicit vvm_mux(unsigned width, unsigned size, unsigned selwid); + ~vvm_mux(); - void init_Sel(unsigned idx, vpip_bit_t val) - { sel_[idx] = val; } + void init_Sel(unsigned idx, vpip_bit_t val); + void init_Data(unsigned idx, vpip_bit_t val); - void init_Data(unsigned idx, vpip_bit_t val) - { input_[idx] = val; } + vvm_nexus::drive_t* config_rout(unsigned idx); - vvm_nexus::drive_t* config_rout(unsigned idx) - { return out_+idx; } - - unsigned key_Sel(unsigned idx) const { return idx; } - unsigned key_Data(unsigned wi, unsigned si) const - { return 0x10000 + si*WIDTH + wi; } + unsigned key_Sel(unsigned idx) const; + unsigned key_Data(unsigned wi, unsigned si) const; private: - void take_value(unsigned key, vpip_bit_t val) - { unsigned code = key >> 16; - unsigned idx = key & 0xffff; - if (code == 1) - set_Data(idx, val); - else - set_Sel(idx, val); - } + void take_value(unsigned key, vpip_bit_t val); - void set_Sel(unsigned idx, vpip_bit_t val) - { if (sel_[idx] == val) return; - sel_[idx] = val; - evaluate_(); - } + unsigned width_, size_, selwid_; + vpip_bit_t*bits_; - void set_Data(unsigned idx, vpip_bit_t val) - { if (input_[idx] == val) return; - input_[idx] = val; - evaluate_(); - } + vvm_nexus::drive_t*out_; - private: - vpip_bit_t sel_[SELWID]; - vpip_bit_t input_[WIDTH * SIZE]; - vpip_bit_t output_[WIDTH]; + void evaluate_(); - vvm_nexus::drive_t out_[WIDTH]; - - void evaluate_() - { vpip_bit_t tmp[WIDTH]; - compute_mux(tmp, WIDTH, sel_, SELWID, input_, SIZE); - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - if (tmp[idx] != output_[idx]) { - output_[idx] = tmp[idx]; - out_[idx].set_value(output_[idx]); - } - } + private: // not implemented + vvm_mux(const vvm_mux&); + vvm_mux& operator= (vvm_mux&); }; template @@ -848,6 +814,17 @@ template class vvm_pevent : public vvm_nexus::recvr_t { /* * $Log: vvm_gates.h,v $ + * Revision 1.46 2000/03/18 01:27:00 steve + * Generate references into a table of nexus objects instead of + * generating lots of isolated nexus objects. Easier on linkers + * and compilers, + * + * Add missing nexus support for l-value bit selects, + * + * Detemplatize the vvm_mux type. + * + * Fix up the vvm_nexus destructor to disconnect from drivers. + * * Revision 1.45 2000/03/17 19:24:00 steve * nor2 and and2 optimized gates. * diff --git a/vvm/vvm_mux.cc b/vvm/vvm_mux.cc new file mode 100644 index 000000000..e20544e61 --- /dev/null +++ b/vvm/vvm_mux.cc @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2000 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: vvm_mux.cc,v 1.1 2000/03/18 01:27:00 steve Exp $" +#endif + +# include "vvm_gates.h" +# include + +/* + * The array of bits is arranged as: + * + * oooo ss 0000 1111 2222 3333 ... + * + */ +vvm_mux::vvm_mux(unsigned w, unsigned s, unsigned sw) +: width_(w), size_(s), selwid_(sw) +{ + bits_ = new vpip_bit_t[width_*size_+selwid_+width_]; + out_ = new vvm_nexus::drive_t[width_]; + + for (unsigned idx = 0 ; idx < width_*size_+selwid_+width_ ; idx += 1) + bits_[idx] = Vx; +} + +vvm_mux::~vvm_mux() +{ + delete[]out_; + delete[]bits_; +} + +vvm_nexus::drive_t* vvm_mux::config_rout(unsigned idx) +{ + assert(idx < width_); + return out_+idx; +} + +unsigned vvm_mux::key_Sel(unsigned idx) const +{ + assert(idx < selwid_); + return idx + width_; +} + +unsigned vvm_mux::key_Data(unsigned wi, unsigned si) const +{ + assert(si < size_); + assert(wi < width_); + return width_ + selwid_ + si*width_ + wi; +} + +void vvm_mux::init_Sel(unsigned idx, vpip_bit_t val) +{ + assert(idx < selwid_); + bits_[width_+idx] = val; +} + +void vvm_mux::init_Data(unsigned idx, vpip_bit_t val) +{ + assert(idx < width_*size_); + bits_[width_+selwid_+idx] = val; +} + +void vvm_mux::take_value(unsigned key, vpip_bit_t val) +{ + if (bits_[key] == val) + return; + + bits_[key] = val; + evaluate_(); +} + +void vvm_mux::evaluate_() +{ + vpip_bit_t*tmp = new vpip_bit_t[width_]; + + vpip_bit_t*sel = bits_+width_; + vpip_bit_t*inp = bits_+width_+selwid_; + + compute_mux(tmp, width_, sel, selwid_, inp, size_); + for (unsigned idx = 0 ; idx < width_ ; idx += 1) + if (tmp[idx] != bits_[idx]) { + bits_[idx] = tmp[idx]; + out_[idx].set_value(bits_[idx]); + } + + delete[]tmp; +} + +void compute_mux(vpip_bit_t*out, unsigned wid, + const vpip_bit_t*sel, unsigned swid, + const vpip_bit_t*dat, unsigned size) +{ + unsigned tmp = 0; + for (unsigned idx = 0 ; idx < swid ; idx += 1) + switch (sel[idx]) { + case V0: + break; + case V1: + tmp |= (1<= size) { + + if (swid > 1) { + for (unsigned idx = 0; idx < wid ; idx += 1) + out[idx] = Vx; + } else { + const unsigned b0 = 0; + const unsigned b1 = wid; + for (unsigned idx = 0 ; idx < wid ; idx += 1) { + if (dat[idx+b0] == dat[idx+b1]) + out[idx] = dat[idx+b0]; + else + out[idx] = Vx; + } + } + + } else { + unsigned b = tmp * wid; + for (unsigned idx = 0; idx < wid ; idx += 1) + out[idx] = dat[idx+b]; + } +} + +/* + * $Log: vvm_mux.cc,v $ + * Revision 1.1 2000/03/18 01:27:00 steve + * Generate references into a table of nexus objects instead of + * generating lots of isolated nexus objects. Easier on linkers + * and compilers, + * + * Add missing nexus support for l-value bit selects, + * + * Detemplatize the vvm_mux type. + * + * Fix up the vvm_nexus destructor to disconnect from drivers. + * + */ + diff --git a/vvm/vvm_nexus.cc b/vvm/vvm_nexus.cc index b5dcb7f49..0a7bc0994 100644 --- a/vvm/vvm_nexus.cc +++ b/vvm/vvm_nexus.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_nexus.cc,v 1.2 2000/03/16 21:45:07 steve Exp $" +#ident "$Id: vvm_nexus.cc,v 1.3 2000/03/18 01:27:00 steve Exp $" #endif # include "vvm_nexus.h" @@ -34,7 +34,13 @@ vvm_nexus::vvm_nexus() vvm_nexus::~vvm_nexus() { - assert(drivers_ == 0); + while (drivers_) { + drive_t*cur = drivers_; + drivers_ = cur->next_; + assert(cur->nexus_ == this); + cur->nexus_ = 0; + cur->next_ = 0; + } /* assert(recvrs_ == 0); XXXX I really should make a point to guarantee that all the receivers that I refer to are gone, @@ -227,6 +233,17 @@ void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, /* * $Log: vvm_nexus.cc,v $ + * Revision 1.3 2000/03/18 01:27:00 steve + * Generate references into a table of nexus objects instead of + * generating lots of isolated nexus objects. Easier on linkers + * and compilers, + * + * Add missing nexus support for l-value bit selects, + * + * Detemplatize the vvm_mux type. + * + * Fix up the vvm_nexus destructor to disconnect from drivers. + * * Revision 1.2 2000/03/16 21:45:07 steve * Properly initialize driver and nexus values. *