vvm_bitset_t is no longer a template.
This commit is contained in:
parent
9f84deeb56
commit
8a10511105
213
t-vvm.cc
213
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 <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.
|
||||
*
|
||||
|
|
|
|||
125
vvm/vvm_func.cc
125
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.
|
||||
|
|
|
|||
169
vvm/vvm_func.h
169
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 <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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue