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
*/
#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 <iostream>
@ -133,6 +133,8 @@ class target_vvm : public target_t {
map<string,bool>esignal_printed_flag;
map<string,bool>pevent_printed_flag;
unsigned signal_bit_counter;
map<string,unsigned>nexus_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["<<idx<<"] = ";
switch (expr->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<const NetEConst*>(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["<<bit<<"] = " <<
os_ << " " << bname << ".bits["<<bit<<"] = " <<
result << "["<<bit<<"];" << endl;
}
}
@ -350,17 +387,21 @@ void vvm_proc_rval::expr_ufunc(const NetEUFunc*expr)
/* Make the function call. */
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();
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<<"["<<idx<<"] = " <<
rbits<<"["<<idx<<"];" << endl;
}
}
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);
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<const NetObj*>(cur->get_obj()))
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;
// 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.
*

View File

@ -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.

View File

@ -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 <unsigned WIDTH>
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]);
}
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 <unsigned WIDTH>
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);
}
/*
* 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 <unsigned WIDTH>
void vvm_binop_and(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
const vvm_bitset_t<WIDTH>&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 <unsigned WIDTH>
void vvm_binop_or(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
const vvm_bitset_t<WIDTH>&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 <unsigned WIDTH>
void vvm_binop_nor(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
const vvm_bitset_t<WIDTH>&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 <unsigned WIDTH>
void vvm_binop_plus(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
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);
}
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 <unsigned WIDTH>
void vvm_binop_minus(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
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);
}
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 <unsigned WR, unsigned WA, unsigned WB>
void vvm_binop_mult(vvm_bitset_t<WR>&r,
const vvm_bitset_t<WA>&a,
const vvm_bitset_t<WB>&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<WR>&r,
* The binary ^ (xor) operator is a bitwise XOR of equal width inputs
* to generate the corresponsing output.
*/
template <unsigned WIDTH>
void vvm_binop_xor(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
const vvm_bitset_t<WIDTH>&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 <unsigned WIDTH>
void vvm_binop_xnor(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&l,
const vvm_bitset_t<WIDTH>&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 <unsigned WIDTH>
void vvm_binop_shiftl(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&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 <unsigned WIDTH>
void vvm_binop_shiftr(vvm_bitset_t<WIDTH>&v,
const vvm_bitset_t<WIDTH>&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 <unsigned W>
void vvm_ternary(vvm_bitset_t<W>&v, vpip_bit_t c,
const vvm_bitset_t<W>&t,
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;
}
}
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.

View File

@ -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_t<WIDTH>ov;
{ 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 <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
private:
vvm_sync*target_;
vvm_bitset_t<WIDTH> value_;
vpip_bit_t value_[WIDTH];
EDGE edge_;
private: // not implemented
@ -795,6 +796,9 @@ template <unsigned WIDTH> 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.

View File

@ -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 <unsigned WIDTH> 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<WIDTH>&);
vvm_bitset_t<WIDTH>& operator= (const vvm_bitset_t<WIDTH>&);
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<WIDTH>&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<WIDTH>&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<WIDTH,SIZE>&m, unsigned i,
const vvm_bitset_t<WIDTH>&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<WIDTH,SIZE>&mem_;
unsigned index_;
vvm_bitset_t<WIDTH> 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.
*