nodangle functor accounts for NexusSet links
In a design, there may be lingering NexusSet objects, or the nodangle may itself use NexusSet objects. This creates links, and this should not confuse the functor. While we are at it, clean up some handling of events structures.
This commit is contained in:
parent
109c5d895d
commit
020e280a98
4
async.cc
4
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;
|
||||
|
|
|
|||
60
net_event.cc
60
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<NetEvProbe*>&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<NetEvProbe*>&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_;
|
||||
|
|
|
|||
22
net_link.cc
22
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_;
|
||||
|
|
|
|||
10
netlist.cc
10
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];
|
||||
}
|
||||
|
||||
|
|
|
|||
16
netlist.h
16
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::vector<NetEvent*>events_;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&out, const NetEvWait&obj);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
sync.cc
2
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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue