diff --git a/async.cc b/async.cc index fa5bbaee0..311b1af2c 100644 --- a/async.cc +++ b/async.cc @@ -50,8 +50,8 @@ bool NetEvWait::is_asynchronous() level sensitive, but the nex_async_ method takes care of that test. */ NexusSet*sense = new NexusSet; - for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) { - NexusSet*tmp = event(idx)->nex_async_(); + for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) { + NexusSet*tmp = events_[idx]->nex_async_(); if (tmp == 0) { delete sense; return false; diff --git a/net_event.cc b/net_event.cc index 5ad61063a..9b67b5b99 100644 --- a/net_event.cc +++ b/net_event.cc @@ -20,6 +20,7 @@ # include "config.h" # include "compiler.h" # include "netlist.h" +# include "ivl_assert.h" /* * NOTE: The name_ is perm-allocated by the caller. @@ -316,6 +317,10 @@ void NetEvProbe::find_similar_probes(list&plist) for (Link*lcur = nex->first_nlink(); lcur; lcur = lcur->next_nlink()) { NetPins*obj = lcur->get_obj(); + // Skip NexusSet objects + if (obj == 0) + continue; + if (obj->pin_count() != pin_count()) continue; @@ -340,14 +345,14 @@ void NetEvProbe::find_similar_probes(list&plist) } NetEvWait::NetEvWait(NetProc*pr) -: statement_(pr), nevents_(0), events_(0) +: statement_(pr) { } NetEvWait::~NetEvWait() { - if (events_) { - for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) { + if (! events_.empty()) { + for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) { NetEvent*tgt = events_[idx]; tgt->waitref_ -= 1; @@ -365,7 +370,7 @@ NetEvWait::~NetEvWait() delete tmp; } } - delete[]events_; + events_.clear(); } delete statement_; } @@ -374,29 +379,12 @@ void NetEvWait::add_event(NetEvent*tgt) { /* A wait fork is an empty event. */ if (! tgt) { - assert(nevents_ == 0); - nevents_ = 1; - events_ = new NetEvent*[1]; - events_[0] = 0; + assert(events_.empty()); + events_.push_back(0); return; } - if (nevents_ == 0) { - events_ = new NetEvent*[1]; - - } else { - assert(events_[0]); - NetEvent**tmp = new NetEvent*[nevents_+1]; - for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) { - tmp[idx] = events_[idx]; - assert(tmp[idx] != tgt); - } - delete[]events_; - events_ = tmp; - } - - events_[nevents_] = tgt; - nevents_ += 1; + events_.push_back(tgt); // Remember to tell the NetEvent that there is someone // pointing to it. @@ -411,14 +399,14 @@ void NetEvWait::add_event(NetEvent*tgt) void NetEvWait::replace_event(NetEvent*src, NetEvent*repl) { unsigned idx; - for (idx = 0 ; idx < nevents_ ; idx += 1) { + for (idx = 0 ; idx < events_.size() ; idx += 1) { if (events_[idx] == src) break; } - assert(idx < nevents_); + assert(idx < events_.size()); - /* First, remove me from the list held by the src NetEvent. */ + // First, remove me from the list held by the src NetEvent. assert(src->waitref_ > 0); src->waitref_ -= 1; struct NetEvent::wcell_*tmp = src->wlist_; @@ -435,6 +423,7 @@ void NetEvWait::replace_event(NetEvent*src, NetEvent*repl) delete tmp; } + // Replace the src pointer with the repl pointer. events_[idx] = repl; // Remember to tell the replacement NetEvent that there is @@ -448,23 +437,6 @@ void NetEvWait::replace_event(NetEvent*src, NetEvent*repl) } -unsigned NetEvWait::nevents() const -{ - return nevents_; -} - -const NetEvent* NetEvWait::event(unsigned idx) const -{ - assert(idx < nevents_); - return events_[idx]; -} - -NetEvent* NetEvWait::event(unsigned idx) -{ - assert(idx < nevents_); - return events_[idx]; -} - NetProc* NetEvWait::statement() { return statement_; diff --git a/net_link.cc b/net_link.cc index 74e7f8790..bccb4c065 100644 --- a/net_link.cc +++ b/net_link.cc @@ -90,13 +90,19 @@ void Nexus::connect(Link&r) void connect(Link&l, Link&r) { + Nexus*tmp; assert(&l != &r); - if (l.nexus_ != 0) { - connect(l.nexus_, r); - } else if (r.nexus_ != 0) { - connect(r.nexus_, l); + // If either the l or r link already are part of a Nexus, then + // re-use that nexus. Go through some effort so that we are + // not gratuitously creating Nexus object. + if (l.next_ && (tmp=l.find_nexus_())) { + connect(tmp, r); + } else if (r.next_ && (tmp=r.find_nexus_())) { + connect(tmp, l); } else { - Nexus*tmp = new Nexus(l); + // No existing Nexus (both links are so far unconnected) + // so start one. + tmp = new Nexus(l); tmp->connect(r); } } @@ -224,9 +230,11 @@ bool Link::is_linked() const bool Link::is_linked(const Link&that) const { - if (next_ == 0) + // If this or that link is linked to nothing, then they cannot + // be linked to each other. + if (! this->is_linked()) return false; - if (that.next_ == 0) + if (! that.is_linked()) return false; const Link*cur = next_; diff --git a/netlist.cc b/netlist.cc index bd0070c6c..ebbf29d0f 100644 --- a/netlist.cc +++ b/netlist.cc @@ -180,7 +180,11 @@ NetPins::NetPins(unsigned npins) NetPins::~NetPins() { - delete[] pins_; + if (pins_) { + assert(pins_[0].node_ == this); + assert(pins_[0].pin_zero_); + delete[] pins_; + } } Link& NetPins::pin(unsigned idx) @@ -194,7 +198,7 @@ Link& NetPins::pin(unsigned idx) } assert(idx < npins_); - assert(idx == 0? pins_[0].pin_zero_ : pins_[idx].pin_==idx); + assert(idx == 0? (pins_[0].pin_zero_ && pins_[0].node_==this) : pins_[idx].pin_==idx); return pins_[idx]; } @@ -208,7 +212,7 @@ const Link& NetPins::pin(unsigned idx) const } assert(pins_); assert(idx < npins_); - assert(idx == 0? pins_[0].pin_zero_ : pins_[idx].pin_==idx); + assert(idx == 0? (pins_[0].pin_zero_ && pins_[0].node_==this) : pins_[idx].pin_==idx); return pins_[idx]; } diff --git a/netlist.h b/netlist.h index bb8a2ac73..13b61e0a4 100644 --- a/netlist.h +++ b/netlist.h @@ -153,7 +153,10 @@ class Link { bool is_equal(const Link&that) const; // Return information about the object that this link is - // a part of. + // a part of. Note that the get_obj() method can return NIL if + // this Link is part of a NexusSet. That should be OK, because + // they are collection variables, and not functional parts of + // a design. const NetPins*get_obj() const; NetPins*get_obj(); unsigned get_pin() const; @@ -3200,9 +3203,9 @@ class NetEvWait : public NetProc { void add_event(NetEvent*tgt); void replace_event(NetEvent*orig, NetEvent*repl); - unsigned nevents() const; - const NetEvent*event(unsigned) const; - NetEvent*event(unsigned); + inline unsigned nevents() const { return events_.size(); } + inline const NetEvent*event(unsigned idx) const { return events_[idx]; } + inline NetEvent*event(unsigned idx) { return events_[idx]; } NetProc*statement(); @@ -3236,9 +3239,8 @@ class NetEvWait : public NetProc { private: NetProc*statement_; - - unsigned nevents_; - NetEvent**events_; + // Events that I might wait for. + std::vectorevents_; }; ostream& operator << (ostream&out, const NetEvWait&obj); diff --git a/nodangle.cc b/nodangle.cc index 19336fc23..9c9940f28 100644 --- a/nodangle.cc +++ b/nodangle.cc @@ -117,7 +117,7 @@ void nodangle_f::event(Design*, NetEvent*ev) NetEvent*tmp = *idx; assert(tmp != ev); - tmp ->replace_event(ev); + tmp ->replace_event(ev); } } } diff --git a/sync.cc b/sync.cc index 1b3a62d88..41c210ac2 100644 --- a/sync.cc +++ b/sync.cc @@ -33,7 +33,7 @@ bool NetProc::is_synchronous() bool NetEvWait::is_synchronous() { - for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) { + for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) { NetEvent*ev = events_[idx]; if (ev->nprobe() == 0) diff --git a/synth2.cc b/synth2.cc index 35362d1ee..ad6f9b7ec 100644 --- a/synth2.cc +++ b/synth2.cc @@ -1002,7 +1002,7 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope, /* This can't be other than one unless there are named events, which I cannot synthesize. */ - assert(nevents_ == 1); + ivl_assert(*this, events_.size() == 1); NetEvent*ev = events_[0]; assert(ev->nprobe() >= 1);