vvm_bitset_t is no longer a template.

This commit is contained in:
steve 2000-03-26 16:28:31 +00:00
parent 9f84deeb56
commit 8a10511105
5 changed files with 327 additions and 224 deletions

213
t-vvm.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <iostream> # include <iostream>
@ -133,6 +133,8 @@ class target_vvm : public target_t {
map<string,bool>esignal_printed_flag; map<string,bool>esignal_printed_flag;
map<string,bool>pevent_printed_flag; map<string,bool>pevent_printed_flag;
unsigned signal_bit_counter;
map<string,unsigned>nexus_wire_map; map<string,unsigned>nexus_wire_map;
unsigned nexus_wire_counter; unsigned nexus_wire_counter;
@ -196,8 +198,11 @@ void vvm_proc_rval::expr_concat(const NetEConcat*expr)
{ {
assert(expr->repeat() > 0); assert(expr->repeat() > 0);
string tname = make_temp(); 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; unsigned pos = 0;
for (unsigned rep = 0 ; rep < expr->repeat() ; rep += 1) 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) void vvm_proc_rval::expr_const(const NetEConst*expr)
{ {
string tname = make_temp(); 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) { for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) {
os_ << setw(indent_) << "" << tname << "[" << idx << "] = "; os_ << " " << tname << "_bits["<<idx<<"] = ";
switch (expr->value().get(idx)) { switch (expr->value().get(idx)) {
case verinum::V0: case verinum::V0:
os_ << "St0"; os_ << "St0";
@ -250,6 +256,9 @@ void vvm_proc_rval::expr_const(const NetEConst*expr)
os_ << ";" << endl; os_ << ";" << endl;
} }
os_ << " vvm_bitset_t " << tname << "(" << tname
<< "_bits, " << expr->expr_width() << ");" << endl;
result = tname; result = tname;
} }
@ -263,21 +272,43 @@ void vvm_proc_rval::expr_ident(const NetEIdent*expr)
*/ */
void vvm_proc_rval::expr_memory(const NetEMemory*mem) void vvm_proc_rval::expr_memory(const NetEMemory*mem)
{ {
/* Make a temporary to hold the word from the memory. */
const string tname = make_temp(); const string tname = make_temp();
os_ << setw(indent_) << "" << "vvm_bitset_t<" os_ << " vpip_bit_t " << tname << "_bits["
<< mem->expr_width() << "> " << tname << ";" << endl; << mem->expr_width() << "];" << endl;
os_ << " vvm_bitset_t " << tname << "(" << tname << "_bits, "
<< mem->expr_width() << ");" << endl;
const string mname = mangle(mem->name()); const string mname = mangle(mem->name());
/* Evaluate the memory index */
assert(mem->index()); assert(mem->index());
mem->index()->expr_scan(this); 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; 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) 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) 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 idx = make_temp();
string val = make_temp(); string val = make_temp();
if (const NetEConst*cp = dynamic_cast<const NetEConst*>(sig->index())) { if (const NetEConst*cp = dynamic_cast<const NetEConst*>(sig->index())) {
os_ << setw(indent_) << "" << "const unsigned " << idx << os_ << " const unsigned " << idx <<
" = " << cp->value().as_ulong() << ";" << endl; " = " << cp->value().as_ulong() << ";" << endl;
} else { } else {
sig->index()->expr_scan(this); sig->index()->expr_scan(this);
os_ << setw(indent_) << "" << "const unsigned " << os_ << " const unsigned " <<
idx << " = " << result << ".as_unsigned();" << idx << " = " << result << ".as_unsigned();" <<
endl; endl;
} }
os_ << setw(indent_) << "" << "vvm_bitset_t<1>" << val << ";" << endl; /* Get the bit select of a signal by making a vvm_bitset_t
os_ << setw(indent_) << "" << val << "[0] = " << object that refers to the single bit within the signal that
mangle(sig->name()) << "_bits[" << idx << "];" << endl; is of interest. */
os_ << " vvm_bitset_t " << val << "("
<< mangle(sig->name()) << ".bits+" << idx << ", 1);" << endl;
result = val; result = val;
} }
@ -312,11 +347,13 @@ void vvm_proc_rval::expr_ternary(const NetETernary*expr)
result = make_temp(); result = make_temp();
os_ << setw(indent_) << "" << "vvm_bitset_t<" << os_ << " vpip_bit_t " << result << "_bits["
expr->expr_width() << ">" << result << ";" << endl; << expr->expr_width() << "];" << endl;
os_ << setw(indent_) << "" << "vvm_ternary(" << result << ", " os_ << " vvm_bitset_t " << result << "(" << result<<"_bits, "
<< cond_val << "[0], " << true_val << ", " << false_val << ");" << expr->expr_width() << ");" << endl;
<< 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 ; for (unsigned bit = 0 ;
bit < expr->parm(idx)->expr_width() ; bit += 1) { bit < expr->parm(idx)->expr_width() ; bit += 1) {
os_ << " " << bname << "_bits["<<bit<<"] = " << os_ << " " << bname << ".bits["<<bit<<"] = " <<
result << "["<<bit<<"];" << endl; result << "["<<bit<<"];" << endl;
} }
} }
@ -350,17 +387,21 @@ void vvm_proc_rval::expr_ufunc(const NetEUFunc*expr)
/* Make the function call. */ /* Make the function call. */
os_ << " " << mangle(expr->name()) << "();" << endl; os_ << " " << mangle(expr->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(); 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() << "> " << /* Copy the result into the new temporary. */
result << ";" << endl; 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<<"["<<idx<<"] = " <<
rbits<<"["<<idx<<"];" << endl;
}
} }
void vvm_proc_rval::expr_unary(const NetEUnary*expr) void vvm_proc_rval::expr_unary(const NetEUnary*expr)
@ -368,8 +409,10 @@ void vvm_proc_rval::expr_unary(const NetEUnary*expr)
expr->expr()->expr_scan(this); expr->expr()->expr_scan(this);
string tname = make_temp(); string tname = make_temp();
os_ << " vvm_bitset_t<" << expr->expr_width() << "> " os_ << " vpip_bit_t " << tname << "_bits["
<< tname << ";" << endl; << expr->expr_width() << "];" << endl;
os_ << " vvm_bitset_t " << tname << "(" << tname<<"_bits, "
<< expr->expr_width() << ");" << endl;
switch (expr->op()) { switch (expr->op()) {
case '~': case '~':
@ -424,10 +467,12 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
string rres = result; string rres = result;
result = make_temp(); result = make_temp();
os_ << setw(indent_) << "" << "// " << expr->get_line() << os_ << " // " << expr->get_line() << ": expression node." << endl;
": expression node." << endl; os_ << " vpip_bit_t " << result<<"_bits[" << expr->expr_width()
os_ << setw(indent_) << "" << "vvm_bitset_t<" << << "];" << endl;
expr->expr_width() << ">" << result << ";" << endl; os_ << " vvm_bitset_t " << result << "(" << result << "_bits, "
<< expr->expr_width() << ");" << endl;
switch (expr->op()) { switch (expr->op()) {
case 'a': // logical and (&&) case 'a': // logical and (&&)
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_land(" 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_user.h\"" << endl;
os << "# include \"vpi_priv.h\"" << endl; os << "# include \"vpi_priv.h\"" << endl;
signal_bit_counter = 0;
process_counter = 0; process_counter = 0;
string_counter = 1; string_counter = 1;
number_counter = 1; number_counter = 1;
@ -740,6 +786,9 @@ void target_vvm::end_design(ostream&os, const Design*mod)
number_counter+1 << "];" << endl; number_counter+1 << "];" << endl;
os << "static vvm_nexus_wire nexus_wire_table[" << os << "static vvm_nexus_wire nexus_wire_table[" <<
nexus_wire_counter << "];" << endl; nexus_wire_counter << "];" << endl;
os << "static vpip_bit_t signal_bit_table[" <<
signal_bit_counter << "];" << endl;
defn.close(); defn.close();
os << "// **** Definition code" << endl; os << "// **** Definition code" << endl;
@ -830,14 +879,15 @@ void target_vvm::signal(ostream&os, const NetNet*sig)
"].connect(&" << net_name << ", " << idx << ");" << endl; "].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; os << "static vvm_signal_t " << net_name << ";" << endl;
init_code << " vpip_make_reg(&" << net_name init_code << " vpip_make_reg(&" << net_name
<< ", \"" << sig->name() << "\"," << net_name<<"_bits.bits, " << ", \"" << sig->name() << "\", signal_bit_table+"
<< sig->pin_count() << ");" << endl; << signal_bit_counter << ", " << sig->pin_count()
<< ");" << endl;
signal_bit_counter += sig->pin_count();
if (const NetScope*scope = sig->scope()) { if (const NetScope*scope = sig->scope()) {
string sname = mangle(scope->name()) + "_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 /* Scan the signals of the vector, passing the initial value
to the inputs of all the connected devices. */ to the inputs of all the connected devices. */
for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1) { 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(" init_code << " " << mangle(sig->name()) << ".init_P("
<< idx << ", "; << idx << ", ";
@ -973,7 +1021,12 @@ void target_vvm::emit_init_value_(const NetObj::Link&lnk, verinum::V val)
if (! dynamic_cast<const NetObj*>(cur->get_obj())) if (! dynamic_cast<const NetObj*>(cur->get_obj()))
continue; continue;
if (dynamic_cast<const NetNet*>(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<const NetNet*>(cur->get_obj())
&& dynamic_cast<const NetNet*>(lnk.get_obj()))
continue; continue;
// Build an init statement for the link, that writes the // 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) 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()); string rval = emit_proc_rval(defn, 8, amem->rval());
const NetMemory*mem = amem->memory(); const NetMemory*mem = amem->memory();
assert(mem->width() <= amem->rval()->expr_width());
defn << " /* " << amem->get_line() << " */" << endl; defn << " /* " << amem->get_line() << " */" << endl;
if (mem->width() == amem->rval()->expr_width()) {
defn << " " << mangle(mem->name()) <<
".set_word(" << index << ".as_unsigned(), " <<
rval << ");" << endl;
} else { /* Set the indexed word from the rval. Note that this
assert(mem->width() <= amem->rval()->expr_width()); assignment will work even if the rval is too wide, because
string tmp = make_temp(); the set_word method takes only the low bits of the width of
defn << " vvm_bitset_t<" << mem->width() << ">" << the memory. */
tmp << ";" << endl;
for (unsigned idx = 0 ; idx < mem->width() ; idx += 1) defn << " " << mangle(mem->name()) <<
defn << " " << tmp << "[" << idx << "] = " << ".set_word(" << index << ".as_unsigned(), " <<
rval << "[" << idx << "];" << endl; rval << ");" << endl;
defn << " " << mangle(mem->name()) << ".set_word("
<< index << ".as_unsigned(), " << tmp << ");" << endl;
}
} }
void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net) 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) 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()); string rval = emit_proc_rval(defn, 8, amem->rval());
const NetMemory*mem = amem->memory(); const NetMemory*mem = amem->memory();
defn << " /* " << amem->get_line() << " */" << endl; 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()); defn << " (new vvm_memory_t<" << mem->width() << ","
string tmp = make_temp(); << mem->count() << ">::assign_nb(" << mangle(mem->name())
defn << " vvm_bitset_t<" << mem->width() << ">" << << ", " << index << ".as_unsigned(), " << rval <<
tmp << ";" << endl; ")) -> schedule();" << 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;
}
} }
bool target_vvm::proc_block(ostream&os, const NetBlock*net) 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 $ * $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 * Revision 1.125 2000/03/25 05:02:24 steve
* signal bits are referenced at run time by the vpiSignal struct. * signal bits are referenced at run time by the vpiSignal struct.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm_func.h" # include "vvm_func.h"
@ -44,6 +44,13 @@ vpip_bit_t vvm_unop_lnot(const vvm_bits_t&r)
return B_NOT(v); 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) vpip_bit_t vvm_unop_or(const vvm_bits_t&r)
{ {
for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) { 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); 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 vvm_unop_xor(const vvm_bits_t&r)
{ {
vpip_bit_t v = St0; vpip_bit_t v = St0;
@ -77,6 +93,84 @@ vpip_bit_t vvm_unop_xnor(const vvm_bits_t&r)
return B_NOT(v); 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) vpip_bit_t vvm_binop_eq(const vvm_bits_t&l, const vvm_bits_t&r)
{ {
const unsigned lwid = l.get_width(); 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); 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 $ * $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 * Revision 1.4 2000/03/25 02:43:56 steve
* Remove all remain vvm_bitset_t return values, * Remove all remain vvm_bitset_t return values,
* and disallow vvm_bitset_t copying. * and disallow vvm_bitset_t copying.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -29,12 +29,7 @@
* Implement the unary NOT operator in the verilog way. This takes a * 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. * vector of a certain width and returns a result of the same width.
*/ */
template <unsigned WIDTH> extern void vvm_unop_not(vvm_bitset_t&v, const vvm_bitset_t&p);
void vvm_unop_not(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t<WIDTH>&p)
{
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = B_NOT(p[idx]);
}
/* /*
* The unary AND is the reduction AND. It returns a single bit. * 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_xor(const vvm_bits_t&r);
extern vpip_bit_t vvm_unop_xnor(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) * simple-minded unary minus operator (two's complement)
// */
template <unsigned WIDTH> extern void vvm_unop_uminus(vvm_bitset_t&v, const vvm_bitset_t&l);
void vvm_unop_uminus(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t<WIDTH>&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);
}
/* /*
* Implement the binary AND operator. This is a bitwise and with all * Implement the binary AND operator. This is a bitwise and with all
* the parameters and the result having the same width. * the parameters and the result having the same width.
*/ */
template <unsigned WIDTH> extern void vvm_binop_and(vvm_bitset_t&v,
void vvm_binop_and(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&r)
{
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = B_AND(l[idx], r[idx]);
}
/* /*
* Implement the binary OR operator. This is a bitwise and with all * Implement the binary OR operator. This is a bitwise and with all
* the parameters and the result having the same width. * the parameters and the result having the same width.
*/ */
template <unsigned WIDTH> extern void vvm_binop_or(vvm_bitset_t&v,
void vvm_binop_or(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&r)
{
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = B_OR(l[idx], r[idx]);
}
template <unsigned WIDTH> extern void vvm_binop_nor(vvm_bitset_t&v,
void vvm_binop_nor(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&r)
{
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = B_NOT(B_OR(l[idx], r[idx]));
}
/* /*
* Implement the binary + operator in the verilog way. This takes * Implement the binary + operator in the verilog way. This takes
* vectors of identical width and returns another vector of same width * vectors of identical width and returns another vector of same width
* that contains the arithmetic sum. Z values are converted to X. * that contains the arithmetic sum. Z values are converted to X.
*/ */
template <unsigned WIDTH> extern void vvm_binop_plus(vvm_bitset_t&v,
void vvm_binop_plus(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&r)
{
vpip_bit_t carry = St0;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = add_with_carry(l[idx], r[idx], carry);
}
/* /*
* The binary - operator is turned into + by doing 2's complement * 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 * arithmetic. l-r == l+~r+1. The "+1" is accomplished by adding in a
* carry of 1 to the 0 bit position. * carry of 1 to the 0 bit position.
*/ */
template <unsigned WIDTH> extern void vvm_binop_minus(vvm_bitset_t&v,
void vvm_binop_minus(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&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);
}
/* /*
* The multiply binary operator takes an A and B parameter and returns * 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*a, unsigned na,
const vpip_bit_t*b, unsigned nb); const vpip_bit_t*b, unsigned nb);
template <unsigned WR, unsigned WA, unsigned WB> inline void vvm_binop_mult(vvm_bitset_t&r,
void vvm_binop_mult(vvm_bitset_t<WR>&r, const vvm_bitset_t&a,
const vvm_bitset_t<WA>&a, const vvm_bitset_t&b)
const vvm_bitset_t<WB>&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<WR>&r,
* The binary ^ (xor) operator is a bitwise XOR of equal width inputs * The binary ^ (xor) operator is a bitwise XOR of equal width inputs
* to generate the corresponsing output. * to generate the corresponsing output.
*/ */
template <unsigned WIDTH> extern void vvm_binop_xor(vvm_bitset_t&v,
void vvm_binop_xor(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&r)
{
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = B_XOR(l[idx], r[idx]);
}
template <unsigned WIDTH> extern void vvm_binop_xnor(vvm_bitset_t&v,
void vvm_binop_xnor(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bitset_t&r);
const vvm_bitset_t<WIDTH>&r)
{
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
v[idx] = B_NOT(B_XOR(l[idx], r[idx]));
}
/* /*
* the binary 'l' operator is a logic left-shift by the number of positions * 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 * indicated by argument r. r is an unsigned integer, which is represented
* internally as a 32-bit bitvector. * internally as a 32-bit bitvector.
*/ */
template <unsigned WIDTH> extern void vvm_binop_shiftl(vvm_bitset_t&v,
void vvm_binop_shiftl(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bits_t&r);
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];
}
/* /*
* The binary 'r' operator is a logic right-shift by the number of positions * 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 * indicated by argument r. r is an unsigned integer, which is represented
* internally by a 32-bit bitvector. * internally by a 32-bit bitvector.
*/ */
template <unsigned WIDTH> extern void vvm_binop_shiftr(vvm_bitset_t&v,
void vvm_binop_shiftr(vvm_bitset_t<WIDTH>&v, const vvm_bitset_t&l,
const vvm_bitset_t<WIDTH>&l, const vvm_bits_t&r);
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;
}
/* /*
* Tests for equality are a bit tricky, as they allow for the left and * 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); extern vpip_bit_t vvm_binop_lor(const vvm_bits_t&l, const vvm_bits_t&r);
template <unsigned W> extern void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c,
void vvm_ternary(vvm_bitset_t<W>&v, vpip_bit_t c, const vvm_bitset_t&t,
const vvm_bitset_t<W>&t, const vvm_bitset_t&f);
const vvm_bitset_t<W>&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;
}
}
/* /*
* $Log: vvm_func.h,v $ * $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 * Revision 1.25 2000/03/25 02:43:57 steve
* Remove all remain vvm_bitset_t return values, * Remove all remain vvm_bitset_t return values,
* and disallow vvm_bitset_t copying. * and disallow vvm_bitset_t copying.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -488,7 +488,8 @@ class vvm_ram_dq : protected vvm_ram_callback, public vvm_nexus::recvr_t {
} }
void send_out_() void send_out_()
{ vvm_bitset_t<WIDTH>ov; { vpip_bit_t*ov_bits[WIDTH];
vvm_bitset_t ov(bits, WIDTH);
mem_->get_word(addr_val_, ov); mem_->get_word(addr_val_, ov);
for (unsigned bit = 0 ; bit < WIDTH ; bit += 1) { for (unsigned bit = 0 ; bit < WIDTH ; bit += 1) {
vvm_out_event*ev = new vvm_out_event(ov[bit], out_+bit); vvm_out_event*ev = new vvm_out_event(ov[bit], out_+bit);
@ -785,7 +786,7 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
private: private:
vvm_sync*target_; vvm_sync*target_;
vvm_bitset_t<WIDTH> value_; vpip_bit_t value_[WIDTH];
EDGE edge_; EDGE edge_;
private: // not implemented private: // not implemented
@ -795,6 +796,9 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
/* /*
* $Log: vvm_gates.h,v $ * $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 * Revision 1.51 2000/03/25 02:43:57 steve
* Remove all remain vvm_bitset_t return values, * Remove all remain vvm_bitset_t return values,
* and disallow vvm_bitset_t copying. * and disallow vvm_bitset_t copying.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -31,26 +31,25 @@
* single bits. The fixed array is used when possible because of the * single bits. The fixed array is used when possible because of the
* more thorough type checking and (hopefully) better optimization. * more thorough type checking and (hopefully) better optimization.
*/ */
template <unsigned WIDTH> class vvm_bitset_t : public vvm_bits_t { class vvm_bitset_t : public vvm_bits_t {
public: public:
vvm_bitset_t() explicit vvm_bitset_t(vpip_bit_t*b, unsigned nb)
{ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) : bits(b), nbits(nb) { }
bits[idx] = HiZ;
}
vpip_bit_t operator[] (unsigned idx) const { return bits[idx]; } vpip_bit_t operator[] (unsigned idx) const { return bits[idx]; }
vpip_bit_t&operator[] (unsigned idx) { 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]; } vpip_bit_t get_bit(unsigned idx) const { return bits[idx]; }
public: public:
vpip_bit_t bits[WIDTH]; vpip_bit_t*bits;
unsigned nbits;
private: // not implemented private: // not implemented
vvm_bitset_t(const vvm_bitset_t<WIDTH>&); vvm_bitset_t(const vvm_bitset_t&);
vvm_bitset_t<WIDTH>& operator= (const vvm_bitset_t<WIDTH>&); vvm_bitset_t& operator= (const vvm_bitset_t&);
}; };
/* /*
@ -88,8 +87,7 @@ class vvm_memory_t : public __vpiMemory {
{ cb_list_ = 0; { cb_list_ = 0;
} }
void set_word(unsigned addr, void set_word(unsigned addr, const vvm_bitset_t&val)
const vvm_bitset_t<WIDTH>&val)
{ unsigned base = WIDTH * addr; { unsigned base = WIDTH * addr;
assert(addr < size); assert(addr < size);
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
@ -106,7 +104,7 @@ class vvm_memory_t : public __vpiMemory {
call_list_(addr); call_list_(addr);
} }
void get_word(unsigned addr, vvm_bitset_t<WIDTH>&val) const void get_word(unsigned addr, vvm_bitset_t&val) const
{ unsigned base = WIDTH * addr; { unsigned base = WIDTH * addr;
assert(addr < size); assert(addr < size);
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
@ -121,8 +119,8 @@ class vvm_memory_t : public __vpiMemory {
class assign_nb : public vvm_event { class assign_nb : public vvm_event {
public: public:
assign_nb(vvm_memory_t<WIDTH,SIZE>&m, unsigned i, assign_nb(vvm_memory_t<WIDTH,SIZE>&m, unsigned i,
const vvm_bitset_t<WIDTH>&v) const vvm_bitset_t&v)
: mem_(m), index_(i) : mem_(m), index_(i), val_(bits_, WIDTH)
{ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
val_[idx] = v[idx]; val_[idx] = v[idx];
} }
@ -132,7 +130,8 @@ class vvm_memory_t : public __vpiMemory {
private: private:
vvm_memory_t<WIDTH,SIZE>&mem_; vvm_memory_t<WIDTH,SIZE>&mem_;
unsigned index_; unsigned index_;
vvm_bitset_t<WIDTH> val_; vpip_bit_t bits_[WIDTH];
vvm_bitset_t val_;
}; };
private: private:
@ -146,6 +145,9 @@ class vvm_memory_t : public __vpiMemory {
/* /*
* $Log: vvm_signal.h,v $ * $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 * Revision 1.6 2000/03/25 05:02:25 steve
* signal bits are referenced at run time by the vpiSignal struct. * signal bits are referenced at run time by the vpiSignal struct.
* *