From 71ecf8c14376c98b9b49160ce3542812deab8654 Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 31 Oct 1999 04:11:27 +0000 Subject: [PATCH] Add to netlist links pin name and instance number, and arrange in vvm for pin connections by name and instance number. --- PExpr.cc | 9 +++- PExpr.h | 52 +++++++++++++--------- design_dump.cc | 11 ++++- elaborate.cc | 71 +++++++++++++++++++---------- netlist.cc | 114 ++++++++++++++++++++++++++++++++++++++++++----- netlist.h | 44 +++++++++++------- t-vvm.cc | 116 ++++++++++++++++++++++++++++++++---------------- vvm/vvm.h | 13 ++++-- vvm/vvm_gates.h | 114 +++++++++++++++++++++++++++++++++++------------ 9 files changed, 398 insertions(+), 146 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index 694b86819..d0f8d976c 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include "PExpr.h" @@ -38,7 +38,7 @@ bool PExpr::is_constant(Module*) const 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) const @@ -128,6 +128,11 @@ bool PETernary::is_constant(Module*) const /* * $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 * Parse system function calls. * diff --git a/PExpr.h b/PExpr.h index 5e38cb3ab..5af3859f1 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include @@ -52,11 +52,12 @@ class PExpr : public LineInfo { virtual NetExpr*elaborate_expr(Design*des, const string&path) const; // 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, - unsigned long rise =0, - unsigned long fall =0, - unsigned long decay =0) const; + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay) const; // This method elaborates the expression as gates, but // restricted for use as l-values of continuous assignments. @@ -91,9 +92,10 @@ class PEConcat : public PExpr { virtual void dump(ostream&) const; virtual NetNet* elaborate_lnet(Design*des, const string&path) const; virtual NetNet* elaborate_net(Design*des, const string&path, - unsigned long rise =0, - unsigned long fall =0, - unsigned long decay =0) const; + unsigned width, + unsigned long rise, + unsigned long fall, + unsigned long decay) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual bool is_constant(Module*) const; @@ -132,9 +134,10 @@ class PEIdent : public PExpr { // Structural r-values are OK. virtual NetNet* elaborate_net(Design*des, const string&path, - unsigned long rise =0, - unsigned long fall =0, - unsigned long decay =0) const; + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay) 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 NetNet* elaborate_net(Design*des, const string&path, - unsigned long rise =0, - unsigned long fall =0, - unsigned long decay =0) const; + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay) const; virtual NetExpr*elaborate_expr(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 NetNet* elaborate_net(Design*des, const string&path, - unsigned long rise =0, - unsigned long fall =0, - unsigned long decay =0) const; + unsigned width, + unsigned long rise, + unsigned long fall, + unsigned long decay) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const; private: @@ -225,9 +230,10 @@ class PEBinary : public PExpr { virtual void dump(ostream&out) const; virtual NetNet* elaborate_net(Design*des, const string&path, - unsigned long rise =0, - unsigned long fall =0, - unsigned long decay =0) const; + unsigned width, + unsigned long rise, + unsigned long fall, + unsigned long decay) const; virtual NetExpr*elaborate_expr(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 NetNet* elaborate_net(Design*des, const string&path, + unsigned width, unsigned long rise =0, unsigned long fall =0, unsigned long decay =0) const; @@ -283,6 +290,11 @@ class PECallFunction : public PExpr { /* * $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 * Parse system function calls. * diff --git a/design_dump.cc b/design_dump.cc index 327e795bc..4487f7104 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 /* @@ -84,7 +84,9 @@ void NetNode::dump_node(ostream&o, unsigned ind) const void NetObj::dump_node_pins(ostream&o, unsigned ind) const { 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()) { case Link::PASSIVE: o << " p"; @@ -795,6 +797,11 @@ void Design::dump(ostream&o) const /* * $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 * Structural case equals device. * diff --git a/elaborate.cc b/elaborate.cc index ed1d97910..26320f93f 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 /* @@ -186,8 +186,9 @@ void PGAssign::elaborate(Design*des, const string&path) const /* Elaborate the r-value. Account for the initial decays, which are going to be attached to the last gate before the generated NetNet. */ - NetNet*rval = pin(1)->elaborate_net(des, path, rise_time, - fall_time, decay_time); + NetNet*rval = pin(1)->elaborate_net(des, path, + lval->pin_count(), + rise_time, fall_time, decay_time); if (rval == 0) { cerr << get_line() << ": error: Unable to elaborate r-value: " << *pin(1) << endl; @@ -199,7 +200,7 @@ void PGAssign::elaborate(Design*des, const string&path) const if (lval->pin_count() > rval->pin_count()) { cerr << get_line() << ": sorry: lval width (" << - lval->pin_count() << ") < rval width (" << + lval->pin_count() << ") > rval width (" << rval->pin_count() << ")." << endl; delete lval; delete rval; @@ -338,7 +339,7 @@ void PGBuiltin::elaborate(Design*des, const string&path) const for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { 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) continue; @@ -455,14 +456,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const // Skip unconnected module ports. if ((*pins)[idx] == 0) 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, // 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(); } + 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 // not, they are different widths. 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) continue; - NetNet*sig = pin(idx)->elaborate_net(des, path); + NetNet*sig = pin(idx)->elaborate_net(des, path, 1, 0, 0, 0); if (sig == 0) { cerr << "internal error: Expression too complicated " "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. */ NetNet* PEBinary::elaborate_net(Design*des, const string&path, + unsigned width, unsigned long rise, unsigned long fall, unsigned long decay) const { - NetNet*lsig = left_->elaborate_net(des, path), - *rsig = right_->elaborate_net(des, path); + NetNet*lsig = left_->elaborate_net(des, path, width, 0, 0, 0), + *rsig = right_->elaborate_net(des, path, width, 0, 0, 0); if (lsig == 0) { cerr << get_line() << ": error: Cannot elaborate "; 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. */ NetNet* PEConcat::elaborate_net(Design*des, const string&path, + unsigned, unsigned long rise, unsigned long fall, unsigned long decay) const @@ -864,7 +870,8 @@ NetNet* PEConcat::elaborate_net(Design*des, const string&path, /* Elaborate the operands of the concatenation. */ 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) errors += 1; else @@ -957,6 +964,7 @@ NetNet* PEConcat::elaborate_lnet(Design*des, const string&path) const } NetNet* PEIdent::elaborate_net(Design*des, const string&path, + unsigned lwidth, unsigned long rise, unsigned long fall, 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, + unsigned lwidth, unsigned long rise, unsigned long fall, unsigned long decay) const { unsigned width = value_->len(); + if (lwidth < width) + width = lwidth; + NetNet*net = new NetNet(des->local_symbol(path), NetNet::IMPLICIT, width); 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, + unsigned width, unsigned long rise, unsigned long fall, unsigned long decay) const { - NetNet* expr_sig = expr_->elaborate_net(des, path); - NetNet* tru_sig = tru_->elaborate_net(des, path); - NetNet* fal_sig = fal_->elaborate_net(des, path); + NetNet* expr_sig = expr_->elaborate_net(des, path, 0, 0, 0, 0); + NetNet* tru_sig = tru_->elaborate_net(des, path, width, 0, 0, 0); + NetNet* fal_sig = fal_->elaborate_net(des, path, width, 0, 0, 0); if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) { des->errors += 1; return 0; @@ -1243,11 +1257,13 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path, } NetNet* PEUnary::elaborate_net(Design*des, const string&path, + unsigned width, unsigned long rise, unsigned long fall, 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) { des->errors += 1; return 0; @@ -1459,7 +1475,7 @@ NetNet* PAssign_::elaborate_lval(Design*des, const string&path, elaboration. Make a synthetic register that connects to the generated circuit and return that as the l-value. */ if (id == 0) { - NetNet*ll = lval_->elaborate_net(des, path); + NetNet*ll = lval_->elaborate_net(des, path, 0, 0, 0, 0); if (ll == 0) { cerr << get_line() << ": Assignment l-value too complex." << endl; @@ -2094,7 +2110,8 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const /* Elaborate the parameter expression as a net so that it can be used as an l-value. Then check that the 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); @@ -2169,7 +2186,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet); 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) { expr_[0]->dump(cerr); cerr << endl; @@ -2643,6 +2661,11 @@ Design* elaborate(const map&modules, /* * $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 * Catch unindexed memory reference. * diff --git a/netlist.cc b/netlist.cc index e3c5bf06e..940cce9e4 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include @@ -95,6 +95,28 @@ void connect(NetObj::Link&l, NetObj::Link&r) } 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 { 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; } +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) { 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) : NetNode(n, w*3+6) { - pin(0).set_dir(NetObj::Link::INPUT); - pin(1).set_dir(NetObj::Link::INPUT); - pin(2).set_dir(NetObj::Link::INPUT); - pin(3).set_dir(NetObj::Link::INPUT); - pin(4).set_dir(NetObj::Link::OUTPUT); - pin(5).set_dir(NetObj::Link::OUTPUT); + pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_name("Add_Sub", 0); + pin(1).set_dir(NetObj::Link::INPUT); pin(1).set_name("Aclr", 0); + pin(2).set_dir(NetObj::Link::INPUT); pin(2).set_name("Clock", 0); + pin(3).set_dir(NetObj::Link::INPUT); pin(3).set_name("Cin", 0); + pin(4).set_dir(NetObj::Link::OUTPUT); pin(4).set_name("Cout", 0); + pin(5).set_dir(NetObj::Link::OUTPUT); pin(5).set_name("Overflow", 0); for (unsigned idx = 0 ; idx < w ; idx += 1) { pin_DataA(idx).set_dir(NetObj::Link::INPUT); pin_DataB(idx).set_dir(NetObj::Link::INPUT); 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); } +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) : 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_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) : type_(c), expr_(ex), nitems_(cnt) { @@ -647,6 +726,7 @@ NetConst::NetConst(const string&n, verinum::V v) : NetNode(n, 1), value_(v) { pin(0).set_dir(Link::OUTPUT); + pin(0).set_name("O", 0); } NetConst::~NetConst() @@ -693,6 +773,9 @@ const NetNet* NetFuncDef::port(unsigned idx) const NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe) : NetNode(ev, wid), sref(pe), edge_(e) { + for (unsigned idx = 0 ; idx < wid ; idx += 1) { + pin(idx).set_name("P", idx); + } } NetNEvent::~NetNEvent() @@ -1067,6 +1150,7 @@ NetESignal::NetESignal(NetNet*n) { set_line(*n); for (unsigned idx = 0 ; idx < n->pin_count() ; idx += 1) { + pin(idx).set_name("P", idx); connect(pin(idx), n->pin(idx)); } } @@ -1075,6 +1159,8 @@ NetESignal::NetESignal(const string&n, unsigned np) : NetExpr(np), NetNode(n, np) { expr_width(pin_count()); + for(unsigned idx = 0 ; idx < np ; idx += 1) + pin(idx).set_name("P", idx); } NetESignal::~NetESignal() @@ -1089,7 +1175,7 @@ NetESignal* NetESignal::dup_expr() const NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*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. expr_width(1); } @@ -1177,8 +1263,11 @@ NetLogic::NetLogic(const string&n, unsigned pins, TYPE t) : NetNode(n, pins), type_(t) { 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_name("I", idx-1); + } } NetRepeat::NetRepeat(NetExpr*e, NetProc*p) @@ -1789,6 +1878,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $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 * Support evaluating + operator at compile time. * diff --git a/netlist.h b/netlist.h index bcd9901a4..d3a8bd8e4 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 /* @@ -76,8 +76,8 @@ class NetObj { public: enum DIR { PASSIVE, INPUT, OUTPUT }; - Link() : dir_(PASSIVE), next_(this), prev_(this) { } - ~Link() { unlink(); } + Link(); + ~Link(); // Manipulate the link direction. void set_dir(DIR d) { dir_ = d; } @@ -103,14 +103,10 @@ class NetObj { // Remove this link from the set of connected pins. The // destructor will automatically do this if needed. - void unlink() - { next_->prev_ = prev_; - prev_->next_ = next_; - next_ = prev_ = this; - } + void unlink(); // 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. bool is_linked(const NetObj::Link&that) const; @@ -123,9 +119,13 @@ class NetObj { // Return information about the object that this link is // a part of. - const NetObj*get_obj() const { return node_; } - NetObj*get_obj() { return node_; } - unsigned get_pin() const { return pin_; } + const NetObj*get_obj() const; + NetObj*get_obj(); + unsigned get_pin() const; + + void set_name(const string&, unsigned inst =0); + const string& get_name() const; + unsigned get_inst() const; private: // The NetNode manages these. They point back to the @@ -134,6 +134,12 @@ class NetObj { unsigned pin_; 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: Link *next_; Link *prev_; @@ -309,6 +315,8 @@ class NetAddSub : public NetNode { NetObj::Link& pin_DataB(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 emit_node(ostream&, struct target_t*) const; }; @@ -444,11 +452,8 @@ class NetTmp : public NetNet { class NetBUFZ : public NetNode { public: - explicit NetBUFZ(const string&n) - : NetNode(n, 2) - { pin(0).set_dir(Link::OUTPUT); - pin(1).set_dir(Link::INPUT); - } + explicit NetBUFZ(const string&n); + ~NetBUFZ(); virtual void dump_node(ostream&, unsigned ind) const; virtual void emit_node(ostream&, struct target_t*) const; @@ -1744,6 +1749,11 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $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 * Support evaluating + operator at compile time. * diff --git a/t-vvm.cc b/t-vvm.cc index 1b34ad39d..9b9138003 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#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 # include @@ -82,7 +82,8 @@ class target_vvm : public target_t { void end_process(ostream&os, const NetProcTop*); 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 // being generated. @@ -681,11 +682,11 @@ void target_vvm::signal(ostream&os, const NetNet*sig) written[lnk->get_obj()->name()] = true; - const NetNode*net; - if ((net = dynamic_cast(lnk->get_obj()))) { + if (dynamic_cast(lnk->get_obj())) { init_code << " " << mangle(lnk->get_obj()->name()) << - ".init(" << lnk->get_pin() << ", V" << + ".init_" << lnk->get_name() << "(" << + lnk->get_inst() << ", V" << sig->get_ival(idx) << ");" << endl; } } @@ -752,28 +753,52 @@ void target_vvm::func_def(ostream&os, const NetFuncDef*def) 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 * single output (at pin 0). This writes the output_fun method into * 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()) << - "_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; - /* 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 with the new value. */ const NetObj*cur; unsigned pin; - gate->pin(0).next_link(cur, pin); + gate->pin(gpin).next_link(cur, pin); while (cur != gate) { if (dynamic_cast(cur)) { // 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 { 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) { - os << "#error \"adders not yet supported in vvm.\"" << endl; os << "static vvm_add_sub<" << gate->width() << "> " << 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) { - os << "static void " << mangle(gate->name()) << - "_output_fun(vvm_simulation*, vpip_bit_t);" << endl; + string outfun = defn_gate_outputfun_(os, gate, 0); switch (gate->type()) { case NetLogic::AND: @@ -834,10 +866,9 @@ void target_vvm::logic(ostream&os, const NetLogic*gate) break; } - os << mangle(gate->name()) << "(&" << - mangle(gate->name()) << "_output_fun);" << endl; + os << mangle(gate->name()) << "(&" << outfun << ");" << endl; - emit_gate_outputfun_(gate); + emit_gate_outputfun_(gate, 0); start_code << " " << mangle(gate->name()) << ".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) { - os << "static void " << mangle(gate->name()) << - "_output_fun(vvm_simulation*, vpip_bit_t);" << endl; + string outfun = defn_gate_outputfun_(os, gate, 0); 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) @@ -912,17 +942,16 @@ void target_vvm::udp(ostream&os, const NetUDP*gate) } os << "};" << dec << setfill(' ') << endl; - os << "static void " << mangle(gate->name()) << - "_output_fun(vvm_simulation*, vpip_bit_t);" << endl; + string outfun = defn_gate_outputfun_(os, gate, 0); os << "static vvm_udp_ssequ<" << gate->pin_count()-1 << "> " << - mangle(gate->name()) << "(&" << mangle(gate->name()) << - "_output_fun, V" << gate->get_initial() << ", " << - mangle(gate->name()) << "_table);" << endl; + mangle(gate->name()) << "(&" << outfun << ", V" << + gate->get_initial() << ", " << mangle(gate->name()) << + "_table);" << endl; /* The UDP output function is much like other logic gates. Use 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) ; cur->pin(pin).next_link(cur, pin)) { + const NetObj::Link&lnk = cur->pin(pin); + // Skip output only pins. if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT) continue; @@ -991,8 +1022,9 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net) if (dynamic_cast(cur)) continue; - delayed << " " << mangle(cur->name()) << - ".set(sim_, " << pin << ", value_[0]);" << endl; + delayed << " " << mangle(cur->name()) + << ".set_" << lnk.get_name() << "sim_, " + << lnk.get_inst() << ", value_[0]);" << 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) ; cur->pin(pin).next_link(cur, pin)) { + const NetObj::Link&lnk = cur->pin(pin); + // Skip output only pins. if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT) continue; @@ -1021,7 +1055,8 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net) continue; delayed << " " << mangle(cur->name()) << - ".set(sim_, " << pin << ", value_[" << + ".set_" << lnk.get_name() << "(sim_, " + << lnk.get_inst() << ", value_[" << idx << "]);" << endl; } } @@ -1039,7 +1074,7 @@ void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate) << mangle(gate->name()) << "(&" << mangle(gate->name()) << "_output_fun);" << endl; - emit_gate_outputfun_(gate); + emit_gate_outputfun_(gate, 0); start_code << " " << mangle(gate->name()) << ".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) { - os << "static void " << mangle(gate->name()) << - "_output_fun(vvm_simulation*, vpip_bit_t);" << endl; + string outfun = defn_gate_outputfun_(os, gate, 0); os << "static vvm_bufz " << mangle(gate->name()) << "(&" << - mangle(gate->name()) << "_output_fun);" << endl; + outfun << ");" << endl; init_code << " " << mangle(gate->name()) << ".set(&sim, 1, "; switch (gate->value()) { @@ -1076,8 +1110,7 @@ void target_vvm::net_const(ostream&os, const NetConst*gate) } init_code << ");" << endl; - - emit_gate_outputfun_(gate); + emit_gate_outputfun_(gate, 0); } 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; defn << " " << mangle(cur->name()) << - ".set(sim_, " << pin << ", " << - rval << "[0]);" << endl; + ".set_" << cur->pin(pin).get_name() << + "(sim_, " << cur->pin(pin).get_inst() << + ", " << rval << "[0]);" << endl; } defn << " break;" << endl; @@ -1251,8 +1285,9 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net) written[cur->name()] = true; defn << " " << mangle(cur->name()) << - ".set(sim_, " << pin << ", " << - rval << "[" << idx << "]);" << endl; + ".set_" << cur->pin(pin).get_name() << + "(sim_, " << cur->pin(pin).get_inst() << + ", " << rval << "[" << idx << "]);" << endl; } } } @@ -1758,6 +1793,11 @@ extern const struct target tgt_vvm = { }; /* * $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 * gate output pins use vpip_bit_t (Eric Aardoom) * diff --git a/vvm/vvm.h b/vvm/vvm.h index dd61f3cc4..5888560c8 100644 --- a/vvm/vvm.h +++ b/vvm/vvm.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include @@ -237,15 +237,15 @@ template class vvm_signal_t : public __vpiSignal { } ~vvm_signal_t() { } - void init(unsigned idx, vpip_bit_t val) + void init_P(unsigned idx, vpip_bit_t 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; vpip_run_value_changes(this); } - void set(vvm_simulation*sim, const vvm_bitset_t&val) + void set_P(vvm_simulation*sim, const vvm_bitset_t&val) { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) set(sim, idx, val[idx]); } @@ -253,6 +253,11 @@ template class vvm_signal_t : public __vpiSignal { /* * $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 * Support vpiValueChance callbacks. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index 5d958cd28..7148741f1 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#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 # include "vvm.h" @@ -49,14 +49,65 @@ class vvm_out_event : public vvm_event { const vpip_bit_t val_; }; +/* + * This template implements the LPM_ADD_SUB device type. The width of + * the device is a template parameter. + */ +template 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 class vvm_and { public: explicit vvm_and(vvm_out_event::action_t 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) { vvm_event*ev = new vvm_out_event(sim, compute_(), output_); @@ -66,10 +117,10 @@ template class vvm_and { sim->active_event(ev); } - void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) - { if (input_[idx-1] == val) + void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val) + { if (input_[idx] == val) return; - input_[idx-1] = val; + input_[idx] = val; vvm_event*ev = new vvm_out_event(sim, compute_(), output_); if (DELAY > 0) @@ -96,8 +147,8 @@ template class vvm_or { explicit vvm_or(vvm_out_event::action_t 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) { vvm_event*ev = new vvm_out_event(sim, compute_(), output_); @@ -107,10 +158,10 @@ template class vvm_or { sim->active_event(ev); } - void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) - { if (input_[idx-1] == val) + void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val) + { if (input_[idx] == val) return; - input_[idx-1] = val; + input_[idx] = val; vvm_event*ev = new vvm_out_event(sim, compute_(), output_); if (DELAY > 0) @@ -137,8 +188,8 @@ template class vvm_nor { explicit vvm_nor(vvm_out_event::action_t 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) { vvm_event*ev = new vvm_out_event(sim, compute_(), output_); @@ -148,10 +199,10 @@ template class vvm_nor { sim->active_event(ev); } - void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) - { if (input_[idx-1] == val) + void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val) + { if (input_[idx] == val) return; - input_[idx-1] = val; + input_[idx] = val; vvm_event*ev = new vvm_out_event(sim, compute_(), output_); if (DELAY > 0) @@ -251,10 +302,10 @@ template class vvm_not { : output_(o) { } - void init(unsigned, vpip_bit_t) { } + void init_I(unsigned, vpip_bit_t) { } 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); vvm_event*ev = new vvm_out_event(sim, outval, output_); if (DELAY > 0) @@ -273,7 +324,7 @@ template class vvm_xnor { explicit vvm_xnor(vvm_out_event::action_t 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) { vvm_event*ev = new vvm_out_event(sim, compute_(), output_); if (DELAY > 0) @@ -284,10 +335,10 @@ template class vvm_xnor { - void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) - { if (input_[idx-1] == val) + void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val) + { if (input_[idx] == val) return; - input_[idx-1] = val; + input_[idx] = val; vpip_bit_t outval = compute_(); vvm_event*ev = new vvm_out_event(sim, outval, output_); if (DELAY > 0) @@ -315,8 +366,8 @@ template class vvm_xor { explicit vvm_xor(vvm_out_event::action_t 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) { vvm_event*ev = new vvm_out_event(sim, compute_(), output_); @@ -326,10 +377,10 @@ template class vvm_xor { sim->active_event(ev); } - void set(vvm_simulation*sim, unsigned idx, vpip_bit_t val) - { if (input_[idx-1] == val) + void set_I(vvm_simulation*sim, unsigned idx, vpip_bit_t val) + { if (input_[idx] == val) return; - input_[idx-1] = val; + input_[idx] = val; start(sim); } @@ -502,7 +553,7 @@ template class vvm_pevent { vvm_bitset_t 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; switch (edge_) { case ANYEDGE: @@ -520,7 +571,7 @@ template class vvm_pevent { value_[idx] = val; } - void init(int idx, vpip_bit_t val) + void init_P(int idx, vpip_bit_t val) { assert(idx < WIDTH); value_[idx] = val; } @@ -537,6 +588,11 @@ template class vvm_pevent { /* * $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 * Rewrite vvm VPI support to make objects more * persistent, rewrite the simulation scheduler