Add to netlist links pin name and instance number,

and arrange in vvm for pin connections by name
 and instance number.
This commit is contained in:
steve 1999-10-31 04:11:27 +00:00
parent 5a2015ee67
commit 71ecf8c143
9 changed files with 398 additions and 146 deletions

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) #if !defined(WINNT)
#ident "$Id: PExpr.cc,v 1.10 1999/09/25 02:57:29 steve Exp $" #ident "$Id: PExpr.cc,v 1.11 1999/10/31 04:11:27 steve Exp $"
#endif #endif
# include "PExpr.h" # include "PExpr.h"
@ -38,7 +38,7 @@ bool PExpr::is_constant(Module*) const
return false; return false;
} }
NetNet* PExpr::elaborate_net(Design*des, const string&path, NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
unsigned long, unsigned long,
unsigned long, unsigned long,
unsigned long) const unsigned long) const
@ -128,6 +128,11 @@ bool PETernary::is_constant(Module*) const
/* /*
* $Log: PExpr.cc,v $ * $Log: PExpr.cc,v $
* Revision 1.11 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.10 1999/09/25 02:57:29 steve * Revision 1.10 1999/09/25 02:57:29 steve
* Parse system function calls. * Parse system function calls.
* *

52
PExpr.h
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) #if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.20 1999/09/25 02:57:29 steve Exp $" #ident "$Id: PExpr.h,v 1.21 1999/10/31 04:11:27 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -52,11 +52,12 @@ class PExpr : public LineInfo {
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
// This method elaborate the expression as gates, for use in a // This method elaborate the expression as gates, for use in a
// continuous assign or other wholy structural context. // continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0, unsigned lwidth,
unsigned long fall =0, unsigned long rise,
unsigned long decay =0) const; unsigned long fall,
unsigned long decay) const;
// This method elaborates the expression as gates, but // This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments. // restricted for use as l-values of continuous assignments.
@ -91,9 +92,10 @@ class PEConcat : public PExpr {
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetNet* elaborate_lnet(Design*des, const string&path) const; virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0, unsigned width,
unsigned long fall =0, unsigned long rise,
unsigned long decay =0) const; unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual bool is_constant(Module*) const; virtual bool is_constant(Module*) const;
@ -132,9 +134,10 @@ class PEIdent : public PExpr {
// Structural r-values are OK. // Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0, unsigned lwidth,
unsigned long fall =0, unsigned long rise,
unsigned long decay =0) const; unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
@ -168,9 +171,10 @@ class PENumber : public PExpr {
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0, unsigned lwidth,
unsigned long fall =0, unsigned long rise,
unsigned long decay =0) const; unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const string&path) const; virtual verinum* eval_const(const Design*des, const string&path) const;
@ -205,9 +209,10 @@ class PEUnary : public PExpr {
virtual void dump(ostream&out) const; virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0, unsigned width,
unsigned long fall =0, unsigned long rise,
unsigned long decay =0) const; unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
private: private:
@ -225,9 +230,10 @@ class PEBinary : public PExpr {
virtual void dump(ostream&out) const; virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0, unsigned width,
unsigned long fall =0, unsigned long rise,
unsigned long decay =0) const; unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const string&path) const; virtual verinum* eval_const(const Design*des, const string&path) const;
@ -251,6 +257,7 @@ class PETernary : public PExpr {
virtual void dump(ostream&out) const; virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path, virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned width,
unsigned long rise =0, unsigned long rise =0,
unsigned long fall =0, unsigned long fall =0,
unsigned long decay =0) const; unsigned long decay =0) const;
@ -283,6 +290,11 @@ class PECallFunction : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $Log: PExpr.h,v $
* Revision 1.21 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.20 1999/09/25 02:57:29 steve * Revision 1.20 1999/09/25 02:57:29 steve
* Parse system function calls. * Parse system function calls.
* *

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) #if !defined(WINNT)
#ident "$Id: design_dump.cc,v 1.50 1999/10/10 01:59:54 steve Exp $" #ident "$Id: design_dump.cc,v 1.51 1999/10/31 04:11:27 steve Exp $"
#endif #endif
/* /*
@ -84,7 +84,9 @@ void NetNode::dump_node(ostream&o, unsigned ind) const
void NetObj::dump_node_pins(ostream&o, unsigned ind) const void NetObj::dump_node_pins(ostream&o, unsigned ind) const
{ {
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
o << setw(ind) << "" << idx; o << setw(ind) << "" << idx << " " << pin(idx).get_name()
<< "<" << pin(idx).get_inst() << ">";
switch (pin(idx).get_dir()) { switch (pin(idx).get_dir()) {
case Link::PASSIVE: case Link::PASSIVE:
o << " p"; o << " p";
@ -795,6 +797,11 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.51 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.50 1999/10/10 01:59:54 steve * Revision 1.50 1999/10/10 01:59:54 steve
* Structural case equals device. * Structural case equals device.
* *

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) #if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.118 1999/10/18 00:02:21 steve Exp $" #ident "$Id: elaborate.cc,v 1.119 1999/10/31 04:11:27 steve Exp $"
#endif #endif
/* /*
@ -186,8 +186,9 @@ void PGAssign::elaborate(Design*des, const string&path) const
/* Elaborate the r-value. Account for the initial decays, /* Elaborate the r-value. Account for the initial decays,
which are going to be attached to the last gate before the which are going to be attached to the last gate before the
generated NetNet. */ generated NetNet. */
NetNet*rval = pin(1)->elaborate_net(des, path, rise_time, NetNet*rval = pin(1)->elaborate_net(des, path,
fall_time, decay_time); lval->pin_count(),
rise_time, fall_time, decay_time);
if (rval == 0) { if (rval == 0) {
cerr << get_line() << ": error: Unable to elaborate r-value: " cerr << get_line() << ": error: Unable to elaborate r-value: "
<< *pin(1) << endl; << *pin(1) << endl;
@ -199,7 +200,7 @@ void PGAssign::elaborate(Design*des, const string&path) const
if (lval->pin_count() > rval->pin_count()) { if (lval->pin_count() > rval->pin_count()) {
cerr << get_line() << ": sorry: lval width (" << cerr << get_line() << ": sorry: lval width (" <<
lval->pin_count() << ") < rval width (" << lval->pin_count() << ") > rval width (" <<
rval->pin_count() << ")." << endl; rval->pin_count() << ")." << endl;
delete lval; delete lval;
delete rval; delete rval;
@ -338,7 +339,7 @@ void PGBuiltin::elaborate(Design*des, const string&path) const
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*ex = pin(idx); const PExpr*ex = pin(idx);
NetNet*sig = ex->elaborate_net(des, path); NetNet*sig = ex->elaborate_net(des, path, 0, 0, 0, 0);
if (sig == 0) if (sig == 0)
continue; continue;
@ -455,14 +456,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
// Skip unconnected module ports. // Skip unconnected module ports.
if ((*pins)[idx] == 0) if ((*pins)[idx] == 0)
continue; continue;
NetNet*sig = (*pins)[idx]->elaborate_net(des, path);
if (sig == 0) {
cerr << "internal error: Expression too complicated "
"for elaboration." << endl;
continue;
}
assert(sig);
// Inside the module, the port is one or more signals, // Inside the module, the port is one or more signals,
// that were already elaborated. List all those signals, // that were already elaborated. List all those signals,
@ -478,6 +471,17 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
prts_pin_count += prts[ldx]->pin_count(); prts_pin_count += prts[ldx]->pin_count();
} }
NetNet*sig = (*pins)[idx]->elaborate_net(des, path,
prts_pin_count,
0, 0, 0);
if (sig == 0) {
cerr << "internal error: Expression too complicated "
"for elaboration." << endl;
continue;
}
assert(sig);
// Check that the parts have matching pin counts. If // Check that the parts have matching pin counts. If
// not, they are different widths. // not, they are different widths.
if (prts_pin_count != sig->pin_count()) { if (prts_pin_count != sig->pin_count()) {
@ -525,7 +529,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const
if (pin(idx) == 0) if (pin(idx) == 0)
continue; continue;
NetNet*sig = pin(idx)->elaborate_net(des, path); NetNet*sig = pin(idx)->elaborate_net(des, path, 1, 0, 0, 0);
if (sig == 0) { if (sig == 0) {
cerr << "internal error: Expression too complicated " cerr << "internal error: Expression too complicated "
"for elaboration:" << *pin(idx) << endl; "for elaboration:" << *pin(idx) << endl;
@ -593,12 +597,13 @@ void PGModule::elaborate(Design*des, const string&path) const
* connecting the lot together with the right kind of gate. * connecting the lot together with the right kind of gate.
*/ */
NetNet* PEBinary::elaborate_net(Design*des, const string&path, NetNet* PEBinary::elaborate_net(Design*des, const string&path,
unsigned width,
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const unsigned long decay) const
{ {
NetNet*lsig = left_->elaborate_net(des, path), NetNet*lsig = left_->elaborate_net(des, path, width, 0, 0, 0),
*rsig = right_->elaborate_net(des, path); *rsig = right_->elaborate_net(des, path, width, 0, 0, 0);
if (lsig == 0) { if (lsig == 0) {
cerr << get_line() << ": error: Cannot elaborate "; cerr << get_line() << ": error: Cannot elaborate ";
left_->dump(cerr); left_->dump(cerr);
@ -848,6 +853,7 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
* connected to all the pins of the elaborated expression nets. * connected to all the pins of the elaborated expression nets.
*/ */
NetNet* PEConcat::elaborate_net(Design*des, const string&path, NetNet* PEConcat::elaborate_net(Design*des, const string&path,
unsigned,
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const unsigned long decay) const
@ -864,7 +870,8 @@ NetNet* PEConcat::elaborate_net(Design*des, const string&path,
/* Elaborate the operands of the concatenation. */ /* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) { for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
nets[idx] = parms_[idx]->elaborate_net(des, path, rise,fall,decay); nets[idx] = parms_[idx]->elaborate_net(des, path, 0,
rise,fall,decay);
if (nets[idx] == 0) if (nets[idx] == 0)
errors += 1; errors += 1;
else else
@ -957,6 +964,7 @@ NetNet* PEConcat::elaborate_lnet(Design*des, const string&path) const
} }
NetNet* PEIdent::elaborate_net(Design*des, const string&path, NetNet* PEIdent::elaborate_net(Design*des, const string&path,
unsigned lwidth,
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const unsigned long decay) const
@ -1158,13 +1166,18 @@ NetNet* PEIdent::elaborate_lnet(Design*des, const string&path) const
} }
/* /*
* Elaborate a number as a NetConst object.
*/ */
NetNet* PENumber::elaborate_net(Design*des, const string&path, NetNet* PENumber::elaborate_net(Design*des, const string&path,
unsigned lwidth,
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const unsigned long decay) const
{ {
unsigned width = value_->len(); unsigned width = value_->len();
if (lwidth < width)
width = lwidth;
NetNet*net = new NetNet(des->local_symbol(path), NetNet*net = new NetNet(des->local_symbol(path),
NetNet::IMPLICIT, width); NetNet::IMPLICIT, width);
net->local_flag(true); net->local_flag(true);
@ -1180,13 +1193,14 @@ NetNet* PENumber::elaborate_net(Design*des, const string&path,
} }
NetNet* PETernary::elaborate_net(Design*des, const string&path, NetNet* PETernary::elaborate_net(Design*des, const string&path,
unsigned width,
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const unsigned long decay) const
{ {
NetNet* expr_sig = expr_->elaborate_net(des, path); NetNet* expr_sig = expr_->elaborate_net(des, path, 0, 0, 0, 0);
NetNet* tru_sig = tru_->elaborate_net(des, path); NetNet* tru_sig = tru_->elaborate_net(des, path, width, 0, 0, 0);
NetNet* fal_sig = fal_->elaborate_net(des, path); NetNet* fal_sig = fal_->elaborate_net(des, path, width, 0, 0, 0);
if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) { if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) {
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -1243,11 +1257,13 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path,
} }
NetNet* PEUnary::elaborate_net(Design*des, const string&path, NetNet* PEUnary::elaborate_net(Design*des, const string&path,
unsigned width,
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const unsigned long decay) const
{ {
NetNet* sub_sig = expr_->elaborate_net(des, path); NetNet* sub_sig = expr_->elaborate_net(des, path, width,
0, 0, 0);
if (sub_sig == 0) { if (sub_sig == 0) {
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -1459,7 +1475,7 @@ NetNet* PAssign_::elaborate_lval(Design*des, const string&path,
elaboration. Make a synthetic register that connects to the elaboration. Make a synthetic register that connects to the
generated circuit and return that as the l-value. */ generated circuit and return that as the l-value. */
if (id == 0) { if (id == 0) {
NetNet*ll = lval_->elaborate_net(des, path); NetNet*ll = lval_->elaborate_net(des, path, 0, 0, 0, 0);
if (ll == 0) { if (ll == 0) {
cerr << get_line() << ": Assignment l-value too complex." cerr << get_line() << ": Assignment l-value too complex."
<< endl; << endl;
@ -2094,7 +2110,8 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
/* Elaborate the parameter expression as a net so that /* Elaborate the parameter expression as a net so that
it can be used as an l-value. Then check that the it can be used as an l-value. Then check that the
parameter width match up. */ parameter width match up. */
NetNet*val = parms_[idx]->elaborate_net(des, path); NetNet*val = parms_[idx]->elaborate_net(des, path,
0, 0, 0, 0);
assert(val); assert(val);
@ -2169,7 +2186,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet); NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet);
for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path); NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path,
0, 0, 0, 0);
if (expr == 0) { if (expr == 0) {
expr_[0]->dump(cerr); expr_[0]->dump(cerr);
cerr << endl; cerr << endl;
@ -2643,6 +2661,11 @@ Design* elaborate(const map<string,Module*>&modules,
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.119 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.118 1999/10/18 00:02:21 steve * Revision 1.118 1999/10/18 00:02:21 steve
* Catch unindexed memory reference. * Catch unindexed memory reference.
* *

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) #if !defined(WINNT)
#ident "$Id: netlist.cc,v 1.77 1999/10/10 23:29:37 steve Exp $" #ident "$Id: netlist.cc,v 1.78 1999/10/31 04:11:27 steve Exp $"
#endif #endif
# include <cassert> # include <cassert>
@ -95,6 +95,28 @@ void connect(NetObj::Link&l, NetObj::Link&r)
} while (cur != &l); } while (cur != &l);
} }
NetObj::Link::Link()
: dir_(PASSIVE), inst_(0), next_(this), prev_(this)
{
}
NetObj::Link::~Link()
{
unlink();
}
void NetObj::Link::unlink()
{
next_->prev_ = prev_;
prev_->next_ = next_;
next_ = prev_ = this;
}
bool NetObj::Link::is_linked() const
{
return next_ != this;
}
bool NetObj::Link::is_linked(const NetObj&that) const bool NetObj::Link::is_linked(const NetObj&that) const
{ {
for (const Link*idx = next_ ; this != idx ; idx = idx->next_) for (const Link*idx = next_ ; this != idx ; idx = idx->next_)
@ -113,6 +135,37 @@ bool NetObj::Link::is_linked(const NetObj::Link&that) const
return false; return false;
} }
const NetObj*NetObj::Link::get_obj() const
{
return node_;
}
NetObj*NetObj::Link::get_obj()
{
return node_;
}
unsigned NetObj::Link::get_pin() const
{
return pin_;
}
void NetObj::Link::set_name(const string&n, unsigned i)
{
name_ = n;
inst_ = i;
}
const string& NetObj::Link::get_name() const
{
return name_;
}
unsigned NetObj::Link::get_inst() const
{
return inst_;
}
bool connected(const NetObj&l, const NetObj&r) bool connected(const NetObj&l, const NetObj&r)
{ {
for (unsigned idx = 0 ; idx < l.pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < l.pin_count() ; idx += 1)
@ -338,16 +391,19 @@ const NetProc* NetProcTop::statement() const
NetAddSub::NetAddSub(const string&n, unsigned w) NetAddSub::NetAddSub(const string&n, unsigned w)
: NetNode(n, w*3+6) : NetNode(n, w*3+6)
{ {
pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_name("Add_Sub", 0);
pin(1).set_dir(NetObj::Link::INPUT); pin(1).set_dir(NetObj::Link::INPUT); pin(1).set_name("Aclr", 0);
pin(2).set_dir(NetObj::Link::INPUT); pin(2).set_dir(NetObj::Link::INPUT); pin(2).set_name("Clock", 0);
pin(3).set_dir(NetObj::Link::INPUT); pin(3).set_dir(NetObj::Link::INPUT); pin(3).set_name("Cin", 0);
pin(4).set_dir(NetObj::Link::OUTPUT); pin(4).set_dir(NetObj::Link::OUTPUT); pin(4).set_name("Cout", 0);
pin(5).set_dir(NetObj::Link::OUTPUT); pin(5).set_dir(NetObj::Link::OUTPUT); pin(5).set_name("Overflow", 0);
for (unsigned idx = 0 ; idx < w ; idx += 1) { for (unsigned idx = 0 ; idx < w ; idx += 1) {
pin_DataA(idx).set_dir(NetObj::Link::INPUT); pin_DataA(idx).set_dir(NetObj::Link::INPUT);
pin_DataB(idx).set_dir(NetObj::Link::INPUT); pin_DataB(idx).set_dir(NetObj::Link::INPUT);
pin_Result(idx).set_dir(NetObj::Link::OUTPUT); pin_Result(idx).set_dir(NetObj::Link::OUTPUT);
pin_DataA(idx).set_name("DataA", idx);
pin_DataB(idx).set_name("DataB", idx);
pin_Result(idx).set_name("Result", idx);
} }
} }
@ -381,11 +437,20 @@ NetObj::Link& NetAddSub::pin_Result(unsigned idx)
return pin(idx); return pin(idx);
} }
const NetObj::Link& NetAddSub::pin_Result(unsigned idx) const
{
idx = 8 + idx*3;
assert(idx < pin_count());
return pin(idx);
}
NetAssign_::NetAssign_(const string&n, unsigned w) NetAssign_::NetAssign_(const string&n, unsigned w)
: NetNode(n, w), rval_(0), bmux_(0) : NetNode(n, w), rval_(0), bmux_(0)
{ {
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(NetObj::Link::OUTPUT); pin(idx).set_dir(NetObj::Link::OUTPUT);
pin(idx).set_name("P", idx);
}
} }
@ -565,6 +630,20 @@ void NetBlock::append(NetProc*cur)
} }
} }
NetBUFZ::NetBUFZ(const string&n)
: NetNode(n, 2)
{
pin(0).set_dir(Link::OUTPUT);
pin(1).set_dir(Link::INPUT);
pin(0).set_name("O", 0);
pin(1).set_name("I", 0);
}
NetBUFZ::~NetBUFZ()
{
}
NetCase::NetCase(NetCase::TYPE c, NetExpr*ex, unsigned cnt) NetCase::NetCase(NetCase::TYPE c, NetExpr*ex, unsigned cnt)
: type_(c), expr_(ex), nitems_(cnt) : type_(c), expr_(ex), nitems_(cnt)
{ {
@ -647,6 +726,7 @@ NetConst::NetConst(const string&n, verinum::V v)
: NetNode(n, 1), value_(v) : NetNode(n, 1), value_(v)
{ {
pin(0).set_dir(Link::OUTPUT); pin(0).set_dir(Link::OUTPUT);
pin(0).set_name("O", 0);
} }
NetConst::~NetConst() NetConst::~NetConst()
@ -693,6 +773,9 @@ const NetNet* NetFuncDef::port(unsigned idx) const
NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe) NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe)
: NetNode(ev, wid), sref<NetPEvent,NetNEvent>(pe), edge_(e) : NetNode(ev, wid), sref<NetPEvent,NetNEvent>(pe), edge_(e)
{ {
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
pin(idx).set_name("P", idx);
}
} }
NetNEvent::~NetNEvent() NetNEvent::~NetNEvent()
@ -1067,6 +1150,7 @@ NetESignal::NetESignal(NetNet*n)
{ {
set_line(*n); set_line(*n);
for (unsigned idx = 0 ; idx < n->pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < n->pin_count() ; idx += 1) {
pin(idx).set_name("P", idx);
connect(pin(idx), n->pin(idx)); connect(pin(idx), n->pin(idx));
} }
} }
@ -1075,6 +1159,8 @@ NetESignal::NetESignal(const string&n, unsigned np)
: NetExpr(np), NetNode(n, np) : NetExpr(np), NetNode(n, np)
{ {
expr_width(pin_count()); expr_width(pin_count());
for(unsigned idx = 0 ; idx < np ; idx += 1)
pin(idx).set_name("P", idx);
} }
NetESignal::~NetESignal() NetESignal::~NetESignal()
@ -1089,7 +1175,7 @@ NetESignal* NetESignal::dup_expr() const
NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*ex) NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*ex)
: sig_(sig), idx_(ex) : sig_(sig), idx_(ex)
{ {
// This suppots mux type indexing of an expression, so the // This supports mux type indexing of an expression, so the
// with is by definition 1 bit. // with is by definition 1 bit.
expr_width(1); expr_width(1);
} }
@ -1177,8 +1263,11 @@ NetLogic::NetLogic(const string&n, unsigned pins, TYPE t)
: NetNode(n, pins), type_(t) : NetNode(n, pins), type_(t)
{ {
pin(0).set_dir(Link::OUTPUT); pin(0).set_dir(Link::OUTPUT);
for (unsigned idx = 1 ; idx < pins ; idx += 1) pin(0).set_name("O", 0);
for (unsigned idx = 1 ; idx < pins ; idx += 1) {
pin(idx).set_dir(Link::INPUT); pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("I", idx-1);
}
} }
NetRepeat::NetRepeat(NetExpr*e, NetProc*p) NetRepeat::NetRepeat(NetExpr*e, NetProc*p)
@ -1789,6 +1878,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.78 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.77 1999/10/10 23:29:37 steve * Revision 1.77 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time. * Support evaluating + operator at compile time.
* *

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) #if !defined(WINNT)
#ident "$Id: netlist.h,v 1.80 1999/10/10 23:29:37 steve Exp $" #ident "$Id: netlist.h,v 1.81 1999/10/31 04:11:27 steve Exp $"
#endif #endif
/* /*
@ -76,8 +76,8 @@ class NetObj {
public: public:
enum DIR { PASSIVE, INPUT, OUTPUT }; enum DIR { PASSIVE, INPUT, OUTPUT };
Link() : dir_(PASSIVE), next_(this), prev_(this) { } Link();
~Link() { unlink(); } ~Link();
// Manipulate the link direction. // Manipulate the link direction.
void set_dir(DIR d) { dir_ = d; } void set_dir(DIR d) { dir_ = d; }
@ -103,14 +103,10 @@ class NetObj {
// Remove this link from the set of connected pins. The // Remove this link from the set of connected pins. The
// destructor will automatically do this if needed. // destructor will automatically do this if needed.
void unlink() void unlink();
{ next_->prev_ = prev_;
prev_->next_ = next_;
next_ = prev_ = this;
}
// Return true if this link is connected to anything else. // Return true if this link is connected to anything else.
bool is_linked() const { return next_ != this; } bool is_linked() const;
// Return true if these pins are connected. // Return true if these pins are connected.
bool is_linked(const NetObj::Link&that) const; bool is_linked(const NetObj::Link&that) const;
@ -123,9 +119,13 @@ class NetObj {
// Return information about the object that this link is // Return information about the object that this link is
// a part of. // a part of.
const NetObj*get_obj() const { return node_; } const NetObj*get_obj() const;
NetObj*get_obj() { return node_; } NetObj*get_obj();
unsigned get_pin() const { return pin_; } unsigned get_pin() const;
void set_name(const string&, unsigned inst =0);
const string& get_name() const;
unsigned get_inst() const;
private: private:
// The NetNode manages these. They point back to the // The NetNode manages these. They point back to the
@ -134,6 +134,12 @@ class NetObj {
unsigned pin_; unsigned pin_;
DIR dir_; DIR dir_;
// These members name the pin of the link. If the name
// has width, then the ninst_ member is the index of the
// pin.
string name_;
unsigned inst_;
private: private:
Link *next_; Link *next_;
Link *prev_; Link *prev_;
@ -309,6 +315,8 @@ class NetAddSub : public NetNode {
NetObj::Link& pin_DataB(unsigned idx); NetObj::Link& pin_DataB(unsigned idx);
NetObj::Link& pin_Result(unsigned idx); NetObj::Link& pin_Result(unsigned idx);
const NetObj::Link& pin_Result(unsigned idx) const;
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const; virtual void emit_node(ostream&, struct target_t*) const;
}; };
@ -444,11 +452,8 @@ class NetTmp : public NetNet {
class NetBUFZ : public NetNode { class NetBUFZ : public NetNode {
public: public:
explicit NetBUFZ(const string&n) explicit NetBUFZ(const string&n);
: NetNode(n, 2) ~NetBUFZ();
{ pin(0).set_dir(Link::OUTPUT);
pin(1).set_dir(Link::INPUT);
}
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const; virtual void emit_node(ostream&, struct target_t*) const;
@ -1744,6 +1749,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.81 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.80 1999/10/10 23:29:37 steve * Revision 1.80 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time. * Support evaluating + operator at compile time.
* *

116
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) #if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.68 1999/10/28 21:51:21 steve Exp $" #ident "$Id: t-vvm.cc,v 1.69 1999/10/31 04:11:28 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
@ -82,7 +82,8 @@ class target_vvm : public target_t {
void end_process(ostream&os, const NetProcTop*); void end_process(ostream&os, const NetProcTop*);
private: private:
void emit_gate_outputfun_(const NetNode*); void emit_gate_outputfun_(const NetNode*, unsigned);
string defn_gate_outputfun_(ostream&os, const NetNode*, unsigned);
// This is the name of the thread (process or task) that is // This is the name of the thread (process or task) that is
// being generated. // being generated.
@ -681,11 +682,11 @@ void target_vvm::signal(ostream&os, const NetNet*sig)
written[lnk->get_obj()->name()] = true; written[lnk->get_obj()->name()] = true;
const NetNode*net; if (dynamic_cast<const NetNode*>(lnk->get_obj())) {
if ((net = dynamic_cast<const NetNode*>(lnk->get_obj()))) {
init_code << " " << init_code << " " <<
mangle(lnk->get_obj()->name()) << mangle(lnk->get_obj()->name()) <<
".init(" << lnk->get_pin() << ", V" << ".init_" << lnk->get_name() << "(" <<
lnk->get_inst() << ", V" <<
sig->get_ival(idx) << ");" << endl; sig->get_ival(idx) << ");" << endl;
} }
} }
@ -752,28 +753,52 @@ void target_vvm::func_def(ostream&os, const NetFuncDef*def)
defn << "}" << endl; defn << "}" << endl;
} }
string target_vvm::defn_gate_outputfun_(ostream&os,
const NetNode*gate,
unsigned gpin)
{
const NetObj::Link&lnk = gate->pin(gpin);
ostrstream tmp;
tmp << mangle(gate->name()) << "_output_" << lnk.get_name() <<
"_" << lnk.get_inst() << ends;
string name = tmp.str();
os << "static void " << name << "(vvm_simulation*, vpip_bit_t);" << endl;
return name;
}
/* /*
* This method handles writing output functions for gates that have a * This method handles writing output functions for gates that have a
* single output (at pin 0). This writes the output_fun method into * single output (at pin 0). This writes the output_fun method into
* the delayed stream to be emitted to the output file later. * the delayed stream to be emitted to the output file later.
*/ */
void target_vvm::emit_gate_outputfun_(const NetNode*gate) void target_vvm::emit_gate_outputfun_(const NetNode*gate, unsigned gpin)
{ {
const NetObj::Link&lnk = gate->pin(gpin);
delayed << "static void " << mangle(gate->name()) << delayed << "static void " << mangle(gate->name()) <<
"_output_fun(vvm_simulation*sim, vpip_bit_t val)" << "_output_" << lnk.get_name() << "_" << lnk.get_inst() <<
"(vvm_simulation*sim, vpip_bit_t val)" <<
endl << "{" << endl; endl << "{" << endl;
/* The output function connects to pin 0 of the netlist part /* The output function connects to gpin of the netlist part
and causes the inputs that it is connected to to be set and causes the inputs that it is connected to to be set
with the new value. */ with the new value. */
const NetObj*cur; const NetObj*cur;
unsigned pin; unsigned pin;
gate->pin(0).next_link(cur, pin); gate->pin(gpin).next_link(cur, pin);
while (cur != gate) { while (cur != gate) {
if (dynamic_cast<const NetNet*>(cur)) { if (dynamic_cast<const NetNet*>(cur)) {
// Skip signals // Skip signals
} else if (cur->pin(pin).get_name() != "") {
delayed << " " << mangle(cur->name()) << ".set_"
<< cur->pin(pin).get_name() << "(sim, " <<
cur->pin(pin).get_inst() << ", val);" << endl;
} else { } else {
delayed << " " << mangle(cur->name()) << ".set(sim, " delayed << " " << mangle(cur->name()) << ".set(sim, "
@ -788,15 +813,22 @@ void target_vvm::emit_gate_outputfun_(const NetNode*gate)
void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate) void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
{ {
os << "#error \"adders not yet supported in vvm.\"" << endl;
os << "static vvm_add_sub<" << gate->width() << "> " << os << "static vvm_add_sub<" << gate->width() << "> " <<
mangle(gate->name()) << ";" << endl; mangle(gate->name()) << ";" << endl;
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
unsigned pin = gate->pin_Result(idx).get_pin();
string outfun = defn_gate_outputfun_(os, gate, pin);
init_code << " " << mangle(gate->name()) <<
".config_rout(" << idx << ", &" << outfun << ");" << endl;
emit_gate_outputfun_(gate, pin);
}
} }
void target_vvm::logic(ostream&os, const NetLogic*gate) void target_vvm::logic(ostream&os, const NetLogic*gate)
{ {
os << "static void " << mangle(gate->name()) << string outfun = defn_gate_outputfun_(os, gate, 0);
"_output_fun(vvm_simulation*, vpip_bit_t);" << endl;
switch (gate->type()) { switch (gate->type()) {
case NetLogic::AND: case NetLogic::AND:
@ -834,10 +866,9 @@ void target_vvm::logic(ostream&os, const NetLogic*gate)
break; break;
} }
os << mangle(gate->name()) << "(&" << os << mangle(gate->name()) << "(&" << outfun << ");" << endl;
mangle(gate->name()) << "_output_fun);" << endl;
emit_gate_outputfun_(gate); emit_gate_outputfun_(gate, 0);
start_code << " " << mangle(gate->name()) << start_code << " " << mangle(gate->name()) <<
".start(&sim);" << endl; ".start(&sim);" << endl;
@ -845,13 +876,12 @@ void target_vvm::logic(ostream&os, const NetLogic*gate)
void target_vvm::bufz(ostream&os, const NetBUFZ*gate) void target_vvm::bufz(ostream&os, const NetBUFZ*gate)
{ {
os << "static void " << mangle(gate->name()) << string outfun = defn_gate_outputfun_(os, gate, 0);
"_output_fun(vvm_simulation*, vpip_bit_t);" << endl;
os << "static vvm_bufz " << mangle(gate->name()) << "(&" << os << "static vvm_bufz " << mangle(gate->name()) << "(&" <<
mangle(gate->name()) << "_output_fun);" << endl; outfun << ");" << endl;
emit_gate_outputfun_(gate); emit_gate_outputfun_(gate, 0);
} }
static string state_to_string(unsigned state, unsigned npins) static string state_to_string(unsigned state, unsigned npins)
@ -912,17 +942,16 @@ void target_vvm::udp(ostream&os, const NetUDP*gate)
} }
os << "};" << dec << setfill(' ') << endl; os << "};" << dec << setfill(' ') << endl;
os << "static void " << mangle(gate->name()) << string outfun = defn_gate_outputfun_(os, gate, 0);
"_output_fun(vvm_simulation*, vpip_bit_t);" << endl;
os << "static vvm_udp_ssequ<" << gate->pin_count()-1 << "> " << os << "static vvm_udp_ssequ<" << gate->pin_count()-1 << "> " <<
mangle(gate->name()) << "(&" << mangle(gate->name()) << mangle(gate->name()) << "(&" << outfun << ", V" <<
"_output_fun, V" << gate->get_initial() << ", " << gate->get_initial() << ", " << mangle(gate->name()) <<
mangle(gate->name()) << "_table);" << endl; "_table);" << endl;
/* The UDP output function is much like other logic gates. Use /* The UDP output function is much like other logic gates. Use
this general method to output the output function. */ this general method to output the output function. */
emit_gate_outputfun_(gate); emit_gate_outputfun_(gate, 0);
} }
@ -982,6 +1011,8 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net)
; net->pin(idx) != cur->pin(pin) ; net->pin(idx) != cur->pin(pin)
; cur->pin(pin).next_link(cur, pin)) { ; cur->pin(pin).next_link(cur, pin)) {
const NetObj::Link&lnk = cur->pin(pin);
// Skip output only pins. // Skip output only pins.
if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT) if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT)
continue; continue;
@ -991,8 +1022,9 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net)
if (dynamic_cast<const NetNet*>(cur)) if (dynamic_cast<const NetNet*>(cur))
continue; continue;
delayed << " " << mangle(cur->name()) << delayed << " " << mangle(cur->name())
".set(sim_, " << pin << ", value_[0]);" << endl; << ".set_" << lnk.get_name() << "sim_, "
<< lnk.get_inst() << ", value_[0]);" << endl;
} }
delayed << " break;" << endl; delayed << " break;" << endl;
@ -1011,6 +1043,8 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net)
; net->pin(idx) != cur->pin(pin) ; net->pin(idx) != cur->pin(pin)
; cur->pin(pin).next_link(cur, pin)) { ; cur->pin(pin).next_link(cur, pin)) {
const NetObj::Link&lnk = cur->pin(pin);
// Skip output only pins. // Skip output only pins.
if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT) if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT)
continue; continue;
@ -1021,7 +1055,8 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net)
continue; continue;
delayed << " " << mangle(cur->name()) << delayed << " " << mangle(cur->name()) <<
".set(sim_, " << pin << ", value_[" << ".set_" << lnk.get_name() << "(sim_, "
<< lnk.get_inst() << ", value_[" <<
idx << "]);" << endl; idx << "]);" << endl;
} }
} }
@ -1039,7 +1074,7 @@ void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate)
<< mangle(gate->name()) << "(&" << mangle(gate->name()) << << mangle(gate->name()) << "(&" << mangle(gate->name()) <<
"_output_fun);" << endl; "_output_fun);" << endl;
emit_gate_outputfun_(gate); emit_gate_outputfun_(gate, 0);
start_code << " " << mangle(gate->name()) << start_code << " " << mangle(gate->name()) <<
".start(&sim);" << endl; ".start(&sim);" << endl;
@ -1053,11 +1088,10 @@ void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate)
*/ */
void target_vvm::net_const(ostream&os, const NetConst*gate) void target_vvm::net_const(ostream&os, const NetConst*gate)
{ {
os << "static void " << mangle(gate->name()) << string outfun = defn_gate_outputfun_(os, gate, 0);
"_output_fun(vvm_simulation*, vpip_bit_t);" << endl;
os << "static vvm_bufz " << mangle(gate->name()) << "(&" << os << "static vvm_bufz " << mangle(gate->name()) << "(&" <<
mangle(gate->name()) << "_output_fun);" << endl; outfun << ");" << endl;
init_code << " " << mangle(gate->name()) << ".set(&sim, 1, "; init_code << " " << mangle(gate->name()) << ".set(&sim, 1, ";
switch (gate->value()) { switch (gate->value()) {
@ -1076,8 +1110,7 @@ void target_vvm::net_const(ostream&os, const NetConst*gate)
} }
init_code << ");" << endl; init_code << ");" << endl;
emit_gate_outputfun_(gate, 0);
emit_gate_outputfun_(gate);
} }
void target_vvm::net_esignal(ostream&os, const NetESignal*net) void target_vvm::net_esignal(ostream&os, const NetESignal*net)
@ -1211,8 +1244,9 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
written[cur->name()] = true; written[cur->name()] = true;
defn << " " << mangle(cur->name()) << defn << " " << mangle(cur->name()) <<
".set(sim_, " << pin << ", " << ".set_" << cur->pin(pin).get_name() <<
rval << "[0]);" << endl; "(sim_, " << cur->pin(pin).get_inst() <<
", " << rval << "[0]);" << endl;
} }
defn << " break;" << endl; defn << " break;" << endl;
@ -1251,8 +1285,9 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
written[cur->name()] = true; written[cur->name()] = true;
defn << " " << mangle(cur->name()) << defn << " " << mangle(cur->name()) <<
".set(sim_, " << pin << ", " << ".set_" << cur->pin(pin).get_name() <<
rval << "[" << idx << "]);" << endl; "(sim_, " << cur->pin(pin).get_inst() <<
", " << rval << "[" << idx << "]);" << endl;
} }
} }
} }
@ -1758,6 +1793,11 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.69 1999/10/31 04:11:28 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.68 1999/10/28 21:51:21 steve * Revision 1.68 1999/10/28 21:51:21 steve
* gate output pins use vpip_bit_t (Eric Aardoom) * gate output pins use vpip_bit_t (Eric Aardoom)
* *

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) #if !defined(WINNT)
#ident "$Id: vvm.h,v 1.18 1999/10/29 03:37:22 steve Exp $" #ident "$Id: vvm.h,v 1.19 1999/10/31 04:11:28 steve Exp $"
#endif #endif
# include <vector> # include <vector>
@ -237,15 +237,15 @@ template <unsigned WIDTH> class vvm_signal_t : public __vpiSignal {
} }
~vvm_signal_t() { } ~vvm_signal_t() { }
void init(unsigned idx, vpip_bit_t val) void init_P(unsigned idx, vpip_bit_t val)
{ bits[idx] = val; } { bits[idx] = val; }
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_P(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ bits[idx] = val; { bits[idx] = val;
vpip_run_value_changes(this); vpip_run_value_changes(this);
} }
void set(vvm_simulation*sim, const vvm_bitset_t<WIDTH>&val) void set_P(vvm_simulation*sim, const vvm_bitset_t<WIDTH>&val)
{ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
set(sim, idx, val[idx]); set(sim, idx, val[idx]);
} }
@ -253,6 +253,11 @@ template <unsigned WIDTH> class vvm_signal_t : public __vpiSignal {
/* /*
* $Log: vvm.h,v $ * $Log: vvm.h,v $
* Revision 1.19 1999/10/31 04:11:28 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.18 1999/10/29 03:37:22 steve * Revision 1.18 1999/10/29 03:37:22 steve
* Support vpiValueChance callbacks. * Support vpiValueChance callbacks.
* *

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) #if !defined(WINNT)
#ident "$Id: vvm_gates.h,v 1.15 1999/10/28 00:47:25 steve Exp $" #ident "$Id: vvm_gates.h,v 1.16 1999/10/31 04:11:28 steve Exp $"
#endif #endif
# include "vvm.h" # include "vvm.h"
@ -49,14 +49,65 @@ class vvm_out_event : public vvm_event {
const vpip_bit_t val_; const vpip_bit_t val_;
}; };
/*
* This template implements the LPM_ADD_SUB device type. The width of
* the device is a template parameter.
*/
template <unsigned WIDTH> class vvm_add_sub {
public:
vvm_add_sub() { }
void config_rout(unsigned idx, vvm_out_event::action_t a)
{ o_[idx] = a;
}
void init_DataA(unsigned idx, vpip_bit_t val)
{ a_[idx] = val;
}
void init_DataB(unsigned idx, vpip_bit_t val)
{ b_[idx] = val;
}
void set_DataA(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ a_[idx] = val;
compute_(sim);
}
void set_DataB(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ b_[idx] = val;
compute_(sim);
}
private:
vpip_bit_t a_[WIDTH];
vpip_bit_t b_[WIDTH];
vpip_bit_t r_[WIDTH];
vvm_out_event::action_t o_[WIDTH];
void compute_(vvm_simulation*sim)
{ vpip_bit_t carry = V0;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) {
vpip_bit_t val;
val = add_with_carry(a_[idx], b_[idx], carry);
if (val == r_[idx]) continue;
r_[idx] = val;
if (o_[idx] == 0) continue;
vvm_event*ev = new vvm_out_event(sim, val, o_[idx]);
sim->insert_event(0, ev);
}
}
};
template <unsigned WIDTH, unsigned long DELAY> class vvm_and { template <unsigned WIDTH, unsigned long DELAY> class vvm_and {
public: public:
explicit vvm_and(vvm_out_event::action_t o) explicit vvm_and(vvm_out_event::action_t o)
: output_(o) { } : output_(o) { }
void init(unsigned idx, vpip_bit_t val) void init_I(unsigned idx, vpip_bit_t val)
{ input_[idx-1] = val; } { input_[idx] = val; }
void start(vvm_simulation*sim) void start(vvm_simulation*sim)
{ vvm_event*ev = new vvm_out_event(sim, compute_(), output_); { vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
@ -66,10 +117,10 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_and {
sim->active_event(ev); sim->active_event(ev);
} }
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (input_[idx-1] == val) { if (input_[idx] == val)
return; return;
input_[idx-1] = val; input_[idx] = val;
vvm_event*ev = new vvm_out_event(sim, compute_(), output_); vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
if (DELAY > 0) if (DELAY > 0)
@ -96,8 +147,8 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_or {
explicit vvm_or(vvm_out_event::action_t o) explicit vvm_or(vvm_out_event::action_t o)
: output_(o) { } : output_(o) { }
void init(unsigned idx, vpip_bit_t val) void init_I(unsigned idx, vpip_bit_t val)
{ input_[idx-1] = val; } { input_[idx] = val; }
void start(vvm_simulation*sim) void start(vvm_simulation*sim)
{ vvm_event*ev = new vvm_out_event(sim, compute_(), output_); { vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
@ -107,10 +158,10 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_or {
sim->active_event(ev); sim->active_event(ev);
} }
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (input_[idx-1] == val) { if (input_[idx] == val)
return; return;
input_[idx-1] = val; input_[idx] = val;
vvm_event*ev = new vvm_out_event(sim, compute_(), output_); vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
if (DELAY > 0) if (DELAY > 0)
@ -137,8 +188,8 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_nor {
explicit vvm_nor(vvm_out_event::action_t o) explicit vvm_nor(vvm_out_event::action_t o)
: output_(o) { } : output_(o) { }
void init(unsigned idx, vpip_bit_t val) void init_I(unsigned idx, vpip_bit_t val)
{ input_[idx-1] = val; } { input_[idx] = val; }
void start(vvm_simulation*sim) void start(vvm_simulation*sim)
{ vvm_event*ev = new vvm_out_event(sim, compute_(), output_); { vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
@ -148,10 +199,10 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_nor {
sim->active_event(ev); sim->active_event(ev);
} }
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (input_[idx-1] == val) { if (input_[idx] == val)
return; return;
input_[idx-1] = val; input_[idx] = val;
vvm_event*ev = new vvm_out_event(sim, compute_(), output_); vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
if (DELAY > 0) if (DELAY > 0)
@ -251,10 +302,10 @@ template <unsigned long DELAY> class vvm_not {
: output_(o) : output_(o)
{ } { }
void init(unsigned, vpip_bit_t) { } void init_I(unsigned, vpip_bit_t) { }
void start(vvm_simulation*) { } void start(vvm_simulation*) { }
void set(vvm_simulation*sim, unsigned, vpip_bit_t val) void set_I(vvm_simulation*sim, unsigned, vpip_bit_t val)
{ vpip_bit_t outval = not(val); { vpip_bit_t outval = not(val);
vvm_event*ev = new vvm_out_event(sim, outval, output_); vvm_event*ev = new vvm_out_event(sim, outval, output_);
if (DELAY > 0) if (DELAY > 0)
@ -273,7 +324,7 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_xnor {
explicit vvm_xnor(vvm_out_event::action_t o) explicit vvm_xnor(vvm_out_event::action_t o)
: output_(o) { } : output_(o) { }
void init(unsigned idx, vpip_bit_t val) { input_[idx-1] = val; } void init_I(unsigned idx, vpip_bit_t val) { input_[idx] = val; }
void start(vvm_simulation*sim) void start(vvm_simulation*sim)
{ vvm_event*ev = new vvm_out_event(sim, compute_(), output_); { vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
if (DELAY > 0) if (DELAY > 0)
@ -284,10 +335,10 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_xnor {
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (input_[idx-1] == val) { if (input_[idx] == val)
return; return;
input_[idx-1] = val; input_[idx] = val;
vpip_bit_t outval = compute_(); vpip_bit_t outval = compute_();
vvm_event*ev = new vvm_out_event(sim, outval, output_); vvm_event*ev = new vvm_out_event(sim, outval, output_);
if (DELAY > 0) if (DELAY > 0)
@ -315,8 +366,8 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_xor {
explicit vvm_xor(vvm_out_event::action_t o) explicit vvm_xor(vvm_out_event::action_t o)
: output_(o) { } : output_(o) { }
void init(unsigned idx, vpip_bit_t val) void init_I(unsigned idx, vpip_bit_t val)
{ input_[idx-1] = val; } { input_[idx] = val; }
void start(vvm_simulation*sim) void start(vvm_simulation*sim)
{ vvm_event*ev = new vvm_out_event(sim, compute_(), output_); { vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
@ -326,10 +377,10 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_xor {
sim->active_event(ev); sim->active_event(ev);
} }
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (input_[idx-1] == val) { if (input_[idx] == val)
return; return;
input_[idx-1] = val; input_[idx] = val;
start(sim); start(sim);
} }
@ -502,7 +553,7 @@ template <unsigned WIDTH> class vvm_pevent {
vvm_bitset_t<WIDTH> get() const { return value_; } vvm_bitset_t<WIDTH> get() const { return value_; }
void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) void set_P(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (value_[idx] == val) return; { if (value_[idx] == val) return;
switch (edge_) { switch (edge_) {
case ANYEDGE: case ANYEDGE:
@ -520,7 +571,7 @@ template <unsigned WIDTH> class vvm_pevent {
value_[idx] = val; value_[idx] = val;
} }
void init(int idx, vpip_bit_t val) void init_P(int idx, vpip_bit_t val)
{ assert(idx < WIDTH); { assert(idx < WIDTH);
value_[idx] = val; value_[idx] = val;
} }
@ -537,6 +588,11 @@ template <unsigned WIDTH> class vvm_pevent {
/* /*
* $Log: vvm_gates.h,v $ * $Log: vvm_gates.h,v $
* Revision 1.16 1999/10/31 04:11:28 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.15 1999/10/28 00:47:25 steve * Revision 1.15 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more * Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler * persistent, rewrite the simulation scheduler