diff --git a/t-vvm.cc b/t-vvm.cc index 429347e77..47248b5ea 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.125 2000/03/25 05:02:24 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.126 2000/03/26 16:28:31 steve Exp $" #endif # include @@ -133,6 +133,8 @@ class target_vvm : public target_t { mapesignal_printed_flag; mappevent_printed_flag; + unsigned signal_bit_counter; + mapnexus_wire_map; unsigned nexus_wire_counter; @@ -196,8 +198,11 @@ void vvm_proc_rval::expr_concat(const NetEConcat*expr) { assert(expr->repeat() > 0); string tname = make_temp(); - os_ << setw(indent_) << "" << "vvm_bitset_t<" << - expr->expr_width() << "> " << tname << ";" << endl; + + os_ << " vpip_bit_t " << tname << "_bits[" + << expr->expr_width() << "];" << endl; + os_ << " vvm_bitset_t " << tname << "(" << tname << "_bits, " + << expr->expr_width() << ");" << endl; unsigned pos = 0; for (unsigned rep = 0 ; rep < expr->repeat() ; rep += 1) @@ -229,10 +234,11 @@ void vvm_proc_rval::expr_concat(const NetEConcat*expr) void vvm_proc_rval::expr_const(const NetEConst*expr) { string tname = make_temp(); - os_ << setw(indent_) << "" << "vvm_bitset_t<" << - expr->expr_width() << "> " << tname << ";" << endl; + + os_ << " vpip_bit_t " << tname<<"_bits[" + << expr->expr_width() << "];" << endl; for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) { - os_ << setw(indent_) << "" << tname << "[" << idx << "] = "; + os_ << " " << tname << "_bits["<value().get(idx)) { case verinum::V0: os_ << "St0"; @@ -250,6 +256,9 @@ void vvm_proc_rval::expr_const(const NetEConst*expr) os_ << ";" << endl; } + os_ << " vvm_bitset_t " << tname << "(" << tname + << "_bits, " << expr->expr_width() << ");" << endl; + result = tname; } @@ -263,21 +272,43 @@ void vvm_proc_rval::expr_ident(const NetEIdent*expr) */ void vvm_proc_rval::expr_memory(const NetEMemory*mem) { + /* Make a temporary to hold the word from the memory. */ const string tname = make_temp(); - os_ << setw(indent_) << "" << "vvm_bitset_t<" - << mem->expr_width() << "> " << tname << ";" << endl; + os_ << " vpip_bit_t " << tname << "_bits[" + << mem->expr_width() << "];" << endl; + os_ << " vvm_bitset_t " << tname << "(" << tname << "_bits, " + << mem->expr_width() << ");" << endl; const string mname = mangle(mem->name()); + + /* Evaluate the memory index */ assert(mem->index()); mem->index()->expr_scan(this); - os_ << setw(indent_) << "" << mname << ".get_word(" << - result<<".as_unsigned(), " << tname << ");"; + + + /* Write code to use the calculated index to get the word from + the memory into the temporary we created earlier. */ + + os_ << " " << mname << ".get_word(" << + result << ".as_unsigned(), " << tname << ");" << endl; + result = tname; } +/* + * A bitset reference to a signal can be done simply by referring to + * the same bits as the signal. We onlt need to copy the bits pointer + * from the vvm_signal_t object to get our reference. + */ void vvm_proc_rval::expr_signal(const NetESignal*expr) { - result = mangle(expr->name()) + "_bits"; + const string tname = make_temp(); + + os_ << " vvm_bitset_t " << tname << "(" + << mangle(expr->name()) << ".bits, " + << expr->expr_width() << ");" << endl; + + result = tname; } void vvm_proc_rval::expr_subsignal(const NetESubSignal*sig) @@ -285,19 +316,23 @@ void vvm_proc_rval::expr_subsignal(const NetESubSignal*sig) string idx = make_temp(); string val = make_temp(); if (const NetEConst*cp = dynamic_cast(sig->index())) { - os_ << setw(indent_) << "" << "const unsigned " << idx << + os_ << " const unsigned " << idx << " = " << cp->value().as_ulong() << ";" << endl; } else { sig->index()->expr_scan(this); - os_ << setw(indent_) << "" << "const unsigned " << + os_ << " const unsigned " << idx << " = " << result << ".as_unsigned();" << endl; } - os_ << setw(indent_) << "" << "vvm_bitset_t<1>" << val << ";" << endl; - os_ << setw(indent_) << "" << val << "[0] = " << - mangle(sig->name()) << "_bits[" << idx << "];" << endl; + /* Get the bit select of a signal by making a vvm_bitset_t + object that refers to the single bit within the signal that + is of interest. */ + + os_ << " vvm_bitset_t " << val << "(" + << mangle(sig->name()) << ".bits+" << idx << ", 1);" << endl; + result = val; } @@ -312,11 +347,13 @@ void vvm_proc_rval::expr_ternary(const NetETernary*expr) result = make_temp(); - os_ << setw(indent_) << "" << "vvm_bitset_t<" << - expr->expr_width() << ">" << result << ";" << endl; - os_ << setw(indent_) << "" << "vvm_ternary(" << result << ", " - << cond_val << "[0], " << true_val << ", " << false_val << ");" - << endl; + os_ << " vpip_bit_t " << result << "_bits[" + << expr->expr_width() << "];" << endl; + os_ << " vvm_bitset_t " << result << "(" << result<<"_bits, " + << expr->expr_width() << ");" << endl; + + os_ << " vvm_ternary(" << result << ", " << cond_val<<"[0], " + << true_val << ", " << false_val << ");" << endl; } /* @@ -342,7 +379,7 @@ void vvm_proc_rval::expr_ufunc(const NetEUFunc*expr) for (unsigned bit = 0 ; bit < expr->parm(idx)->expr_width() ; bit += 1) { - os_ << " " << bname << "_bits["<name()) << "();" << endl; - /* Save the return value in a temporary. */ + /* rbits is the bits of the signal that hold the result. */ + string rbits = mangle(expr->result()->name()) + ".bits"; + + /* Make a temporary to hold the result... */ result = make_temp(); - string rbits = mangle(expr->result()->name()) + "_bits"; + os_ << " vpip_bit_t " << result << "_bits[" + << expr->expr_width() << "];" << endl; + os_ << " vvm_bitset_t " << result << "(" + << result<<"_bits, " << expr->expr_width() << ");" << endl; - os_ << " vvm_bitset_t<" << expr->expr_width() << "> " << - result << ";" << endl; + /* Copy the result into the new temporary. */ + for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) + os_ << " " << result << "_bits[" << idx << "] = " + << rbits << "[" << idx << "];" << endl; - for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) { - os_ << " " << result<<"["<expr()->expr_scan(this); string tname = make_temp(); - os_ << " vvm_bitset_t<" << expr->expr_width() << "> " - << tname << ";" << endl; + os_ << " vpip_bit_t " << tname << "_bits[" + << expr->expr_width() << "];" << endl; + os_ << " vvm_bitset_t " << tname << "(" << tname<<"_bits, " + << expr->expr_width() << ");" << endl; switch (expr->op()) { case '~': @@ -424,10 +467,12 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) string rres = result; result = make_temp(); - os_ << setw(indent_) << "" << "// " << expr->get_line() << - ": expression node." << endl; - os_ << setw(indent_) << "" << "vvm_bitset_t<" << - expr->expr_width() << ">" << result << ";" << endl; + os_ << " // " << expr->get_line() << ": expression node." << endl; + os_ << " vpip_bit_t " << result<<"_bits[" << expr->expr_width() + << "];" << endl; + os_ << " vvm_bitset_t " << result << "(" << result << "_bits, " + << expr->expr_width() << ");" << endl; + switch (expr->op()) { case 'a': // logical and (&&) os_ << setw(indent_) << "" << result << "[0] = vvm_binop_land(" @@ -690,6 +735,7 @@ void target_vvm::start_design(ostream&os, const Design*mod) os << "# include \"vpi_user.h\"" << endl; os << "# include \"vpi_priv.h\"" << endl; + signal_bit_counter = 0; process_counter = 0; string_counter = 1; number_counter = 1; @@ -740,6 +786,9 @@ void target_vvm::end_design(ostream&os, const Design*mod) number_counter+1 << "];" << endl; os << "static vvm_nexus_wire nexus_wire_table[" << nexus_wire_counter << "];" << endl; + os << "static vpip_bit_t signal_bit_table[" << + signal_bit_counter << "];" << endl; + defn.close(); os << "// **** Definition code" << endl; @@ -830,14 +879,15 @@ void target_vvm::signal(ostream&os, const NetNet*sig) "].connect(&" << net_name << ", " << idx << ");" << endl; } - os << "static vvm_bitset_t<" << sig->pin_count() << "> " << - net_name<< "_bits; /* " << sig->name() << - " */" << endl; os << "static vvm_signal_t " << net_name << ";" << endl; init_code << " vpip_make_reg(&" << net_name - << ", \"" << sig->name() << "\"," << net_name<<"_bits.bits, " - << sig->pin_count() << ");" << endl; + << ", \"" << sig->name() << "\", signal_bit_table+" + << signal_bit_counter << ", " << sig->pin_count() + << ");" << endl; + + + signal_bit_counter += sig->pin_count(); if (const NetScope*scope = sig->scope()) { string sname = mangle(scope->name()) + "_scope"; @@ -849,8 +899,6 @@ void target_vvm::signal(ostream&os, const NetNet*sig) /* Scan the signals of the vector, passing the initial value to the inputs of all the connected devices. */ for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1) { - if (sig->get_ival(idx) == verinum::Vz) - continue; init_code << " " << mangle(sig->name()) << ".init_P(" << idx << ", "; @@ -973,7 +1021,12 @@ void target_vvm::emit_init_value_(const NetObj::Link&lnk, verinum::V val) if (! dynamic_cast(cur->get_obj())) continue; - if (dynamic_cast(cur->get_obj())) + /* If the caller lnk is a signal, then we are declaring + signals so we skip signal initializations as they + take care of themselves. */ + + if (dynamic_cast(cur->get_obj()) + && dynamic_cast(lnk.get_obj())) continue; // Build an init statement for the link, that writes the @@ -1754,28 +1807,31 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net) */ void target_vvm::proc_assign_mem(ostream&os, const NetAssignMem*amem) { - string index = mangle(amem->index()->name()) + "_bits"; + /* make a temporary to reference the index signal. */ + string index = make_temp(); + + defn << " vvm_bitset_t " << index << "(" + << mangle(amem->index()->name()) << ".bits, " + << mangle(amem->index()->name()) << ".nbits);" << endl; + + /* Evaluate the rval that gets written into the memory word. */ string rval = emit_proc_rval(defn, 8, amem->rval()); + + const NetMemory*mem = amem->memory(); + assert(mem->width() <= amem->rval()->expr_width()); defn << " /* " << amem->get_line() << " */" << endl; - if (mem->width() == amem->rval()->expr_width()) { - defn << " " << mangle(mem->name()) << - ".set_word(" << index << ".as_unsigned(), " << - rval << ");" << endl; - } else { - assert(mem->width() <= amem->rval()->expr_width()); - string tmp = make_temp(); - defn << " vvm_bitset_t<" << mem->width() << ">" << - tmp << ";" << endl; - for (unsigned idx = 0 ; idx < mem->width() ; idx += 1) - defn << " " << tmp << "[" << idx << "] = " << - rval << "[" << idx << "];" << endl; + /* Set the indexed word from the rval. Note that this + assignment will work even if the rval is too wide, because + the set_word method takes only the low bits of the width of + the memory. */ + + defn << " " << mangle(mem->name()) << + ".set_word(" << index << ".as_unsigned(), " << + rval << ");" << endl; - defn << " " << mangle(mem->name()) << ".set_word(" - << index << ".as_unsigned(), " << tmp << ");" << endl; - } } void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net) @@ -1821,33 +1877,27 @@ void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net) void target_vvm::proc_assign_mem_nb(ostream&os, const NetAssignMemNB*amem) { + /* make a temporary to reference the index signal. */ + string index = make_temp(); - string index = mangle(amem->index()->name()) + "_bits"; + defn << " vvm_bitset_t " << index << "(" + << mangle(amem->index()->name()) << ".bits, " + << mangle(amem->index()->name()) << ".nbits);" << endl; + + + /* Evaluate the rval that gets written into the memory word. */ string rval = emit_proc_rval(defn, 8, amem->rval()); + const NetMemory*mem = amem->memory(); defn << " /* " << amem->get_line() << " */" << endl; - if (mem->width() == amem->rval()->expr_width()) { - defn << " (new vvm_memory_t<" << mem->width() << "," - << mem->count() << ">::assign_nb(" << mangle(mem->name()) - << ", " << index << ".as_unsigned(), " << rval << - ")) -> schedule();" << endl; - } else { + assert(mem->width() <= amem->rval()->expr_width()); - assert(mem->width() <= amem->rval()->expr_width()); - string tmp = make_temp(); - defn << " vvm_bitset_t<" << mem->width() << ">" << - tmp << ";" << endl; - for (unsigned idx = 0 ; idx < mem->width() ; idx += 1) - defn << " " << tmp << "[" << idx << "] = " << - rval << "[" << idx << "];" << endl; - - defn << " (new vvm_memory_t<" << mem->width() << "," - << mem->count() << ">::assign_nb(" << mangle(mem->name()) - << ", " << index << ".as_unsigned(), " << tmp << - ")) -> schedule();" << endl; - } + defn << " (new vvm_memory_t<" << mem->width() << "," + << mem->count() << ">::assign_nb(" << mangle(mem->name()) + << ", " << index << ".as_unsigned(), " << rval << + ")) -> schedule();" << endl; } bool target_vvm::proc_block(ostream&os, const NetBlock*net) @@ -2390,6 +2440,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.126 2000/03/26 16:28:31 steve + * vvm_bitset_t is no longer a template. + * * Revision 1.125 2000/03/25 05:02:24 steve * signal bits are referenced at run time by the vpiSignal struct. * diff --git a/vvm/vvm_func.cc b/vvm/vvm_func.cc index f596828ea..83d36f2d2 100644 --- a/vvm/vvm_func.cc +++ b/vvm/vvm_func.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_func.cc,v 1.4 2000/03/25 02:43:56 steve Exp $" +#ident "$Id: vvm_func.cc,v 1.5 2000/03/26 16:28:31 steve Exp $" #endif # include "vvm_func.h" @@ -44,6 +44,13 @@ vpip_bit_t vvm_unop_lnot(const vvm_bits_t&r) return B_NOT(v); } +void vvm_unop_not(vvm_bitset_t&v, const vvm_bitset_t&p) +{ + assert(v.nbits == p.nbits); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = B_NOT(p[idx]); +} + vpip_bit_t vvm_unop_or(const vvm_bits_t&r) { for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) { @@ -60,6 +67,15 @@ vpip_bit_t vvm_unop_nor(const vvm_bits_t&r) return B_NOT(v); } +void vvm_unop_uminus(vvm_bitset_t&v, const vvm_bitset_t&l) +{ + vvm_unop_not(v, l); + vpip_bit_t carry = St1; + for (unsigned i = 0 ; i < v.nbits ; i += 1) + v[i] = add_with_carry(v[i], St0, carry); + +} + vpip_bit_t vvm_unop_xor(const vvm_bits_t&r) { vpip_bit_t v = St0; @@ -77,6 +93,84 @@ vpip_bit_t vvm_unop_xnor(const vvm_bits_t&r) return B_NOT(v); } +void vvm_binop_and(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) +{ + assert(v.nbits == l.nbits); + assert(v.nbits == r.nbits); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = B_AND(l[idx], r[idx]); +} + +void vvm_binop_minus(vvm_bitset_t&v, const vvm_bitset_t&l, + const vvm_bitset_t&r) +{ + vvm_unop_not(v, r); + vpip_bit_t carry = St1; + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = add_with_carry(l[idx], v[idx], carry); +} + +void vvm_binop_nor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) +{ + assert(v.nbits == l.nbits); + assert(v.nbits == r.nbits); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = B_NOT(B_OR(l[idx], r[idx])); +} + +void vvm_binop_or(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) +{ + assert(v.nbits == l.nbits); + assert(v.nbits == r.nbits); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = B_OR(l[idx], r[idx]); +} + +void vvm_binop_plus(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) +{ + assert(v.nbits == l.nbits); + assert(v.nbits == r.nbits); + vpip_bit_t carry = St0; + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = add_with_carry(l[idx], r[idx], carry); +} + +void vvm_binop_shiftl(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bits_t&r) +{ + assert(v.nbits == l.nbits); + vvm_u32 s = r.as_unsigned(); + for (unsigned idx = 0 ; idx < v.nbits; idx += 1) + v[idx] = (idx < s) ? St0 : l[idx-s]; +} + +void vvm_binop_shiftr(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bits_t&r) +{ + assert(v.nbits == l.nbits); + vvm_u32 s = r.as_unsigned(); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = (idx < (v.nbits-s)) ? l[idx+s] : St0; +} + +void vvm_binop_xnor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) +{ + assert(v.nbits == l.nbits); + assert(v.nbits == r.nbits); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = B_NOT(B_XOR(l[idx], r[idx])); +} + +void vvm_binop_xor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) +{ + assert(v.nbits == l.nbits); + assert(v.nbits == r.nbits); + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = B_XOR(l[idx], r[idx]); +} + vpip_bit_t vvm_binop_eq(const vvm_bits_t&l, const vvm_bits_t&r) { const unsigned lwid = l.get_width(); @@ -363,9 +457,38 @@ vpip_bit_t vvm_binop_lor(const vvm_bits_t&l, const vvm_bits_t&r) return B_OR(res1, res2); } +void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c, + const vvm_bitset_t&t, + const vvm_bitset_t&f) +{ + assert(v.nbits == t.nbits); + assert(v.nbits == f.nbits); + + if (B_IS0(c)) { + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = f[idx]; + return; + } + if (B_IS1(c)) { + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) + v[idx] = t[idx]; + return; + } + + for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) { + if (B_EQ(t[idx], f[idx])) + v[idx] = t[idx]; + else + v[idx] = StX; + } +} + /* * $Log: vvm_func.cc,v $ + * Revision 1.5 2000/03/26 16:28:31 steve + * vvm_bitset_t is no longer a template. + * * Revision 1.4 2000/03/25 02:43:56 steve * Remove all remain vvm_bitset_t return values, * and disallow vvm_bitset_t copying. diff --git a/vvm/vvm_func.h b/vvm/vvm_func.h index b448e5436..76312b1b4 100644 --- a/vvm/vvm_func.h +++ b/vvm/vvm_func.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_func.h,v 1.25 2000/03/25 02:43:57 steve Exp $" +#ident "$Id: vvm_func.h,v 1.26 2000/03/26 16:28:31 steve Exp $" #endif # include "vvm.h" @@ -29,12 +29,7 @@ * Implement the unary NOT operator in the verilog way. This takes a * vector of a certain width and returns a result of the same width. */ -template -void vvm_unop_not(vvm_bitset_t&v, const vvm_bitset_t&p) -{ - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = B_NOT(p[idx]); -} +extern void vvm_unop_not(vvm_bitset_t&v, const vvm_bitset_t&p); /* * The unary AND is the reduction AND. It returns a single bit. @@ -57,84 +52,48 @@ extern vpip_bit_t vvm_unop_nor(const vvm_bits_t&r); extern vpip_bit_t vvm_unop_xor(const vvm_bits_t&r); extern vpip_bit_t vvm_unop_xnor(const vvm_bits_t&r); -// -// simple-minded unary minus operator (two's complement) -// -template -void vvm_unop_uminus(vvm_bitset_t&v, const vvm_bitset_t&l) -{ - vvm_unop_not(v, l); - vpip_bit_t carry = St1; - for (int i = 0; i < WIDTH; i++) - v[i] = add_with_carry(v[i], St0, carry); - -} +/* + * simple-minded unary minus operator (two's complement) + */ +extern void vvm_unop_uminus(vvm_bitset_t&v, const vvm_bitset_t&l); /* * Implement the binary AND operator. This is a bitwise and with all * the parameters and the result having the same width. */ -template -void vvm_binop_and(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = B_AND(l[idx], r[idx]); -} +extern void vvm_binop_and(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); /* * Implement the binary OR operator. This is a bitwise and with all * the parameters and the result having the same width. */ -template -void vvm_binop_or(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = B_OR(l[idx], r[idx]); -} +extern void vvm_binop_or(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); -template -void vvm_binop_nor(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = B_NOT(B_OR(l[idx], r[idx])); -} +extern void vvm_binop_nor(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); /* * Implement the binary + operator in the verilog way. This takes * vectors of identical width and returns another vector of same width * that contains the arithmetic sum. Z values are converted to X. */ -template -void vvm_binop_plus(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - vpip_bit_t carry = St0; - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = add_with_carry(l[idx], r[idx], carry); -} +extern void vvm_binop_plus(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); /* * The binary - operator is turned into + by doing 2's complement * arithmetic. l-r == l+~r+1. The "+1" is accomplished by adding in a * carry of 1 to the 0 bit position. */ -template -void vvm_binop_minus(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - vvm_unop_not(v, r); - vpip_bit_t carry = St1; - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = add_with_carry(l[idx], v[idx], carry); -} +extern void vvm_binop_minus(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); /* * The multiply binary operator takes an A and B parameter and returns @@ -145,12 +104,13 @@ extern void vvm_binop_mult(vpip_bit_t*res, unsigned nres, const vpip_bit_t*a, unsigned na, const vpip_bit_t*b, unsigned nb); -template -void vvm_binop_mult(vvm_bitset_t&r, - const vvm_bitset_t&a, - const vvm_bitset_t&b) +inline void vvm_binop_mult(vvm_bitset_t&r, + const vvm_bitset_t&a, + const vvm_bitset_t&b) { - vvm_binop_mult(r.bits, WR, a.bits, WA, b.bits, WB); + vvm_binop_mult(r.bits, r.nbits, + a.bits, a.nbits, + b.bits, b.nbits); } @@ -158,53 +118,31 @@ void vvm_binop_mult(vvm_bitset_t&r, * The binary ^ (xor) operator is a bitwise XOR of equal width inputs * to generate the corresponsing output. */ -template -void vvm_binop_xor(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = B_XOR(l[idx], r[idx]); -} +extern void vvm_binop_xor(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); -template -void vvm_binop_xnor(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bitset_t&r) -{ - for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - v[idx] = B_NOT(B_XOR(l[idx], r[idx])); -} +extern void vvm_binop_xnor(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bitset_t&r); /* * the binary 'l' operator is a logic left-shift by the number of positions * indicated by argument r. r is an unsigned integer, which is represented * internally as a 32-bit bitvector. */ -template -void vvm_binop_shiftl(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bits_t&r) -{ - vvm_u32 s = r.as_unsigned(); - for (unsigned idx = 0; idx < WIDTH; idx++) - v[idx] = (idx < s) ? St0 : l[idx-s]; -} +extern void vvm_binop_shiftl(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bits_t&r); /* * The binary 'r' operator is a logic right-shift by the number of positions * indicated by argument r. r is an unsigned integer, which is represented * internally by a 32-bit bitvector. */ -template -void vvm_binop_shiftr(vvm_bitset_t&v, - const vvm_bitset_t&l, - const vvm_bits_t&r) -{ - vvm_u32 s = r.as_unsigned(); - for (unsigned idx = 0; idx < WIDTH; idx++) - v[idx] = (idx < (WIDTH-s)) ? l[idx+s] : St0; -} +extern void vvm_binop_shiftr(vvm_bitset_t&v, + const vvm_bitset_t&l, + const vvm_bits_t&r); /* * Tests for equality are a bit tricky, as they allow for the left and @@ -252,32 +190,15 @@ extern vpip_bit_t vvm_binop_land(const vvm_bits_t&l, const vvm_bits_t&r); extern vpip_bit_t vvm_binop_lor(const vvm_bits_t&l, const vvm_bits_t&r); -template -void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c, - const vvm_bitset_t&t, - const vvm_bitset_t&f) -{ - if (B_IS0(c)) { - for (unsigned idx = 0 ; idx < W ; idx += 1) - v[idx] = f[idx]; - return; - } - if (B_IS1(c)) { - for (unsigned idx = 0 ; idx < W ; idx += 1) - v[idx] = t[idx]; - return; - } - - for (unsigned idx = 0 ; idx < W ; idx += 1) { - if (B_EQ(t[idx], f[idx])) - v[idx] = t[idx]; - else - v[idx] = StX; - } -} +extern void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c, + const vvm_bitset_t&t, + const vvm_bitset_t&f); /* * $Log: vvm_func.h,v $ + * Revision 1.26 2000/03/26 16:28:31 steve + * vvm_bitset_t is no longer a template. + * * Revision 1.25 2000/03/25 02:43:57 steve * Remove all remain vvm_bitset_t return values, * and disallow vvm_bitset_t copying. diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index e675b6be7..ec387a10b 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.51 2000/03/25 02:43:57 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.52 2000/03/26 16:28:31 steve Exp $" #endif # include "vvm.h" @@ -488,7 +488,8 @@ class vvm_ram_dq : protected vvm_ram_callback, public vvm_nexus::recvr_t { } void send_out_() - { vvm_bitset_tov; + { vpip_bit_t*ov_bits[WIDTH]; + vvm_bitset_t ov(bits, WIDTH); mem_->get_word(addr_val_, ov); for (unsigned bit = 0 ; bit < WIDTH ; bit += 1) { vvm_out_event*ev = new vvm_out_event(ov[bit], out_+bit); @@ -785,7 +786,7 @@ template class vvm_pevent : public vvm_nexus::recvr_t { private: vvm_sync*target_; - vvm_bitset_t value_; + vpip_bit_t value_[WIDTH]; EDGE edge_; private: // not implemented @@ -795,6 +796,9 @@ template class vvm_pevent : public vvm_nexus::recvr_t { /* * $Log: vvm_gates.h,v $ + * Revision 1.52 2000/03/26 16:28:31 steve + * vvm_bitset_t is no longer a template. + * * Revision 1.51 2000/03/25 02:43:57 steve * Remove all remain vvm_bitset_t return values, * and disallow vvm_bitset_t copying. diff --git a/vvm/vvm_signal.h b/vvm/vvm_signal.h index 9d17afe2b..e96af6d05 100644 --- a/vvm/vvm_signal.h +++ b/vvm/vvm_signal.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_signal.h,v 1.6 2000/03/25 05:02:25 steve Exp $" +#ident "$Id: vvm_signal.h,v 1.7 2000/03/26 16:28:31 steve Exp $" #endif # include "vvm.h" @@ -31,26 +31,25 @@ * single bits. The fixed array is used when possible because of the * more thorough type checking and (hopefully) better optimization. */ -template class vvm_bitset_t : public vvm_bits_t { +class vvm_bitset_t : public vvm_bits_t { public: - vvm_bitset_t() - { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - bits[idx] = HiZ; - } + explicit vvm_bitset_t(vpip_bit_t*b, unsigned nb) + : bits(b), nbits(nb) { } vpip_bit_t operator[] (unsigned idx) const { return bits[idx]; } vpip_bit_t&operator[] (unsigned idx) { return bits[idx]; } - unsigned get_width() const { return WIDTH; } + unsigned get_width() const { return nbits; } vpip_bit_t get_bit(unsigned idx) const { return bits[idx]; } public: - vpip_bit_t bits[WIDTH]; + vpip_bit_t*bits; + unsigned nbits; private: // not implemented - vvm_bitset_t(const vvm_bitset_t&); - vvm_bitset_t& operator= (const vvm_bitset_t&); + vvm_bitset_t(const vvm_bitset_t&); + vvm_bitset_t& operator= (const vvm_bitset_t&); }; /* @@ -88,8 +87,7 @@ class vvm_memory_t : public __vpiMemory { { cb_list_ = 0; } - void set_word(unsigned addr, - const vvm_bitset_t&val) + void set_word(unsigned addr, const vvm_bitset_t&val) { unsigned base = WIDTH * addr; assert(addr < size); for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) @@ -106,7 +104,7 @@ class vvm_memory_t : public __vpiMemory { call_list_(addr); } - void get_word(unsigned addr, vvm_bitset_t&val) const + void get_word(unsigned addr, vvm_bitset_t&val) const { unsigned base = WIDTH * addr; assert(addr < size); for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) @@ -121,8 +119,8 @@ class vvm_memory_t : public __vpiMemory { class assign_nb : public vvm_event { public: assign_nb(vvm_memory_t&m, unsigned i, - const vvm_bitset_t&v) - : mem_(m), index_(i) + const vvm_bitset_t&v) + : mem_(m), index_(i), val_(bits_, WIDTH) { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) val_[idx] = v[idx]; } @@ -132,7 +130,8 @@ class vvm_memory_t : public __vpiMemory { private: vvm_memory_t&mem_; unsigned index_; - vvm_bitset_t val_; + vpip_bit_t bits_[WIDTH]; + vvm_bitset_t val_; }; private: @@ -146,6 +145,9 @@ class vvm_memory_t : public __vpiMemory { /* * $Log: vvm_signal.h,v $ + * Revision 1.7 2000/03/26 16:28:31 steve + * vvm_bitset_t is no longer a template. + * * Revision 1.6 2000/03/25 05:02:25 steve * signal bits are referenced at run time by the vpiSignal struct. *