Rewrite find_similar_event to support doing
all event matching and replacement in one shot, saving time in the scans.
This commit is contained in:
parent
843e1f9c44
commit
58ec62c895
200
net_event.cc
200
net_event.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_event.cc,v 1.18 2002/06/30 02:21:31 steve Exp $"
|
||||
#ident "$Id: net_event.cc,v 1.19 2002/07/24 16:24:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -119,140 +119,67 @@ unsigned NetEvent::nwait() const
|
|||
* A "similar" event is one that has an identical non-nil set of
|
||||
* probes.
|
||||
*/
|
||||
NetEvent* NetEvent::find_similar_event()
|
||||
void NetEvent::find_similar_event(list<NetEvent*>&event_list)
|
||||
{
|
||||
if (probes_ == 0)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
struct table_s {
|
||||
NetEvent*ev;
|
||||
bool mark;
|
||||
} *table;
|
||||
map<NetEvent*,unsigned> event_matches;
|
||||
|
||||
//NetEvent**cand;
|
||||
//bool*cflg;
|
||||
unsigned max_cand = 0, ncand = 0;
|
||||
/* First, get a list of all the NetEvProbes that are connected
|
||||
to my first probe. Then use that to create a set of
|
||||
candidate events. These candidate events are a superset of
|
||||
the similar events, so I will be culling this list later. */
|
||||
list<NetEvProbe*>first_probes;
|
||||
probes_->find_similar_probes(first_probes);
|
||||
|
||||
NetEvProbe*cur = probes_;
|
||||
|
||||
/* Get an estimate of the number of candidate events there
|
||||
are. To get it, count the number of probes that are
|
||||
connected to my first probe. Since there is no more then
|
||||
one NetEvent per NetEvProbe, this is the maximum number of
|
||||
similar events possible.
|
||||
|
||||
Once we get that count, allocate the arrays needed to
|
||||
account for these events. */
|
||||
|
||||
for (NetNode*idx = cur->next_node()
|
||||
; idx && (idx != cur) ; idx = idx->next_node()) {
|
||||
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
if (tmp->edge() != cur->edge())
|
||||
continue;
|
||||
|
||||
max_cand += 1;
|
||||
for (list<NetEvProbe*>::iterator idx = first_probes.begin()
|
||||
; idx != first_probes.end() ; idx ++) {
|
||||
event_matches[ (*idx)->event() ] = 1;
|
||||
}
|
||||
|
||||
table = new struct table_s[max_cand];
|
||||
/* Now scan the remaining probes, in each case ticking the
|
||||
candidate event. The events that really are similar to this
|
||||
one will turn up in every probe list. */
|
||||
unsigned probe_count = 1;
|
||||
for (NetEvProbe*cur = probes_->enext_ ; cur ; cur = cur->enext_) {
|
||||
list<NetEvProbe*>similar_probes;
|
||||
cur->find_similar_probes(similar_probes);
|
||||
|
||||
|
||||
/* First, locate all the candidate events from my first
|
||||
probe. Look for all the NetEvProbe objects connected to my
|
||||
probe (that are the same edge) and save the NetEvent that
|
||||
that probe drives. */
|
||||
|
||||
for (NetNode*idx = cur->next_node()
|
||||
; idx && (idx != cur) ; idx = idx->next_node()) {
|
||||
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
if (tmp->edge() != cur->edge())
|
||||
continue;
|
||||
|
||||
/* Don't include myself in the list of candidates. */
|
||||
NetEvent*etmp = tmp->event();
|
||||
if (etmp == this)
|
||||
continue;
|
||||
|
||||
table[ncand++].ev = etmp;
|
||||
assert(ncand <= max_cand);
|
||||
}
|
||||
|
||||
|
||||
/* All the events in the cand array are now known to connect
|
||||
through at least one NetEvProbe. Now go through all my
|
||||
remaining probes and check that each candidate event is
|
||||
also connected (through a NetEvProbe) to me.
|
||||
|
||||
By the time I finish this scan, only NetEvents that have
|
||||
equivilent NetEvProbes remain. These are candidates. The
|
||||
events may have *more* NetEvProbes then me, I'll catch
|
||||
those later. */
|
||||
|
||||
for (cur = cur->enext_ ; cur && ncand ; cur = cur->enext_) {
|
||||
for (unsigned idx = 0 ; idx < ncand ; idx += 1)
|
||||
table[idx].mark = false;
|
||||
|
||||
/* For this probe, look for other probes connected to it
|
||||
and find the event connected to it. Mark that event
|
||||
as connected to this probe. */
|
||||
|
||||
for (NetNode*idx = cur->next_node()
|
||||
; idx && (idx != cur) ; idx = idx->next_node()) {
|
||||
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
if (tmp->edge() != cur->edge())
|
||||
continue;
|
||||
|
||||
for (unsigned srch = 0 ; srch < ncand ; srch += 1)
|
||||
if (table[srch].ev == tmp->event()) {
|
||||
table[srch].mark = true;
|
||||
break;
|
||||
}
|
||||
for (list<NetEvProbe*>::iterator idx = similar_probes.begin()
|
||||
; idx != similar_probes.end() ; idx ++) {
|
||||
event_matches[ (*idx)->event() ] += 1;
|
||||
}
|
||||
|
||||
/* Look for all the candidates that did not connect to
|
||||
this probe (cflg is false) and eliminate them. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < ncand ; ) {
|
||||
if (table[idx].mark) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned tmp = idx ; (tmp+1) < ncand ; tmp += 1)
|
||||
table[tmp] = table[tmp+1];
|
||||
|
||||
ncand -= 1;
|
||||
}
|
||||
probe_count += 1;
|
||||
}
|
||||
|
||||
/* Now scan the candidate events. Those events that are
|
||||
connected to all my probes (match_count[x] == probe_count)
|
||||
are possible. If those events have the same number of
|
||||
events, then jackpot. */
|
||||
for (map<NetEvent*,unsigned>::iterator idx = event_matches.begin()
|
||||
; idx != event_matches.end() ; idx ++) {
|
||||
|
||||
/* Scan the remaining candidates for a similar
|
||||
NetEvent. Eliminate NetEvent objects that have more
|
||||
NetEvProbe objects then I, because those have a proper
|
||||
superset of my probes and were not eliminated by the
|
||||
previous scan.
|
||||
NetEvent*tmp = (*idx).first;
|
||||
|
||||
As soon as we find a similar event, we're done. */
|
||||
if (tmp == this)
|
||||
continue;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ncand ; idx += 1) {
|
||||
if (table[idx].ev->nprobe() == nprobe()) {
|
||||
NetEvent*res = table[idx].ev;
|
||||
delete[]table;
|
||||
return res;
|
||||
}
|
||||
if ((*idx).second != probe_count)
|
||||
continue;
|
||||
|
||||
unsigned tcnt = 0;
|
||||
for (NetEvProbe*cur = tmp->probes_ ; cur ; cur = cur->enext_)
|
||||
tcnt += 1;
|
||||
|
||||
if (tcnt == probe_count)
|
||||
event_list .push_back(tmp);
|
||||
}
|
||||
|
||||
|
||||
/* Oops, fell off the list without finding a result. return nil. */
|
||||
delete[]table;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void NetEvent::replace_event(NetEvent*that)
|
||||
{
|
||||
while (wlist_) {
|
||||
|
|
@ -355,6 +282,42 @@ const NetEvent* NetEvProbe::event() const
|
|||
return event_;
|
||||
}
|
||||
|
||||
/*
|
||||
* A similar NetEvProbe is one that is connected to all the same nexa
|
||||
* that this probe is connected to, and also is the same edge
|
||||
* type. Don't count myself as a similar probe.
|
||||
*/
|
||||
void NetEvProbe::find_similar_probes(list<NetEvProbe*>&plist)
|
||||
{
|
||||
Nexus*nex = pin(0).nexus();
|
||||
|
||||
for (Link*lcur = nex->first_nlink(); lcur; lcur = lcur->next_nlink()) {
|
||||
NetObj*obj = lcur->get_obj();
|
||||
if (obj->pin_count() != pin_count())
|
||||
continue;
|
||||
|
||||
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(obj);
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
|
||||
if (tmp == this)
|
||||
continue;
|
||||
|
||||
if (edge() != tmp->edge())
|
||||
continue;
|
||||
|
||||
bool ok_flag = true;
|
||||
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1)
|
||||
if (pin(idx).nexus() != tmp->pin(idx).nexus()) {
|
||||
ok_flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ok_flag == true)
|
||||
plist .push_back(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
NetEvWait::NetEvWait(NetProc*pr)
|
||||
: statement_(pr), nevents_(0), events_(0)
|
||||
{
|
||||
|
|
@ -479,6 +442,11 @@ NetProc* NetEvWait::statement()
|
|||
|
||||
/*
|
||||
* $Log: net_event.cc,v $
|
||||
* Revision 1.19 2002/07/24 16:24:45 steve
|
||||
* Rewrite find_similar_event to support doing
|
||||
* all event matching and replacement in one
|
||||
* shot, saving time in the scans.
|
||||
*
|
||||
* Revision 1.18 2002/06/30 02:21:31 steve
|
||||
* Add structure for asynchronous logic synthesis.
|
||||
*
|
||||
|
|
|
|||
37
netlist.cc
37
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.cc,v 1.193 2002/07/02 03:02:57 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.194 2002/07/24 16:24:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -233,36 +233,6 @@ NetNode::~NetNode()
|
|||
design_->del_node(this);
|
||||
}
|
||||
|
||||
NetNode* NetNode::next_node()
|
||||
{
|
||||
Link*pin0 = pin(0).next_nlink();
|
||||
if (pin0 == 0)
|
||||
pin0 = pin(0).nexus()->first_nlink();
|
||||
|
||||
while (pin0 != &pin(0)) {
|
||||
NetNode*cur = dynamic_cast<NetNode*>(pin0->get_obj());
|
||||
if (cur == 0)
|
||||
goto continue_label;
|
||||
if (cur->pin_count() != pin_count())
|
||||
goto continue_label;
|
||||
|
||||
{ bool flag = true;
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1)
|
||||
flag = flag && pin(idx).is_linked(cur->pin(idx));
|
||||
|
||||
if (flag == true)
|
||||
return cur;
|
||||
}
|
||||
|
||||
continue_label:
|
||||
pin0 = pin0->next_nlink();
|
||||
if (pin0 == 0)
|
||||
pin0 = pin(0).nexus()->first_nlink();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, const string&n, Type t, unsigned npins)
|
||||
: NetObj(s, n, npins), sig_next_(0), sig_prev_(0),
|
||||
type_(t), port_type_(NOT_A_PORT), signed_(false), msb_(npins-1), lsb_(0),
|
||||
|
|
@ -2371,6 +2341,11 @@ const NetProc*NetTaskDef::proc() const
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.194 2002/07/24 16:24:45 steve
|
||||
* Rewrite find_similar_event to support doing
|
||||
* all event matching and replacement in one
|
||||
* shot, saving time in the scans.
|
||||
*
|
||||
* Revision 1.193 2002/07/02 03:02:57 steve
|
||||
* Change the signal to a net when assignments go away.
|
||||
*
|
||||
|
|
|
|||
15
netlist.h
15
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.h,v 1.252 2002/07/07 22:32:15 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.253 2002/07/24 16:24:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -314,10 +314,6 @@ class NetNode : public NetObj {
|
|||
|
||||
virtual ~NetNode();
|
||||
|
||||
// This method locates the next node that has all its pins
|
||||
// connected to the same of my own pins.
|
||||
NetNode*next_node();
|
||||
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned) const;
|
||||
|
||||
|
|
@ -1639,7 +1635,7 @@ class NetEvent : public LineInfo {
|
|||
|
||||
// Locate the first event that matches my behavior and
|
||||
// monitors the same signals.
|
||||
NetEvent* find_similar_event();
|
||||
void find_similar_event(list<NetEvent*>&);
|
||||
|
||||
// This method replaces pointers to me with pointers to
|
||||
// that. It is typically used to replace similar events
|
||||
|
|
@ -1748,6 +1744,8 @@ class NetEvProbe : public NetNode {
|
|||
NetEvent* event();
|
||||
const NetEvent* event() const;
|
||||
|
||||
void find_similar_probes(list<NetEvProbe*>&);
|
||||
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
|
||||
|
|
@ -3002,6 +3000,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.253 2002/07/24 16:24:45 steve
|
||||
* Rewrite find_similar_event to support doing
|
||||
* all event matching and replacement in one
|
||||
* shot, saving time in the scans.
|
||||
*
|
||||
* Revision 1.252 2002/07/07 22:32:15 steve
|
||||
* Asynchronous synthesis of case statements.
|
||||
*
|
||||
|
|
|
|||
61
nodangle.cc
61
nodangle.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: nodangle.cc,v 1.15 2002/05/26 01:39:02 steve Exp $"
|
||||
#ident "$Id: nodangle.cc,v 1.16 2002/07/24 16:24:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
|
||||
class nodangle_f : public functor_t {
|
||||
public:
|
||||
|
|
@ -37,22 +38,32 @@ class nodangle_f : public functor_t {
|
|||
void signal(Design*des, NetNet*sig);
|
||||
|
||||
unsigned count_;
|
||||
unsigned stotal, etotal;
|
||||
};
|
||||
|
||||
void nodangle_f::event(Design*des, NetEvent*ev)
|
||||
{
|
||||
if (NetEvent*match = ev->find_similar_event()) {
|
||||
assert(match != ev);
|
||||
ev->replace_event(match);
|
||||
/* If there are no references to this event, then go right
|
||||
ahead and delete in. There is no use looking further at
|
||||
it. */
|
||||
if ((ev->nwait() + ev->ntrig()) == 0) {
|
||||
delete ev;
|
||||
etotal += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev->nwait() != 0)
|
||||
return;
|
||||
/* Try to find all the events that are similar to me, and
|
||||
replace their references with references to me. */
|
||||
list<NetEvent*> match;
|
||||
ev->find_similar_event(match);
|
||||
for (list<NetEvent*>::iterator idx = match.begin()
|
||||
; idx != match.end() ; idx ++) {
|
||||
|
||||
if (ev->ntrig() != 0)
|
||||
return;
|
||||
NetEvent*tmp = *idx;
|
||||
assert(tmp != ev);
|
||||
tmp ->replace_event(ev);
|
||||
}
|
||||
|
||||
delete ev;
|
||||
}
|
||||
|
||||
void nodangle_f::signal(Design*des, NetNet*sig)
|
||||
|
|
@ -74,12 +85,16 @@ void nodangle_f::signal(Design*des, NetNet*sig)
|
|||
|
||||
/* Check to see if the signal is completely unconnected. If
|
||||
all the bits are unlinked, then delete it. */
|
||||
unsigned unlinked = 0;
|
||||
bool linked_flag = false;
|
||||
for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1)
|
||||
if (! sig->pin(idx).is_linked()) unlinked += 1;
|
||||
if (sig->pin(idx).is_linked()) {
|
||||
linked_flag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlinked == sig->pin_count()) {
|
||||
if (! linked_flag) {
|
||||
delete sig;
|
||||
stotal += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -110,6 +125,9 @@ void nodangle_f::signal(Design*des, NetNet*sig)
|
|||
significant_flags += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (significant_flags <= idx)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If every pin is connected to another significant signal,
|
||||
|
|
@ -117,21 +135,40 @@ void nodangle_f::signal(Design*des, NetNet*sig)
|
|||
if (significant_flags == sig->pin_count()) {
|
||||
count_ += 1;
|
||||
delete sig;
|
||||
stotal += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void nodangle(Design*des)
|
||||
{
|
||||
nodangle_f fun;
|
||||
unsigned count_iterations = 0;
|
||||
fun.stotal = 0;
|
||||
fun.etotal = 0;
|
||||
|
||||
do {
|
||||
fun.count_ = 0;
|
||||
des->functor(&fun);
|
||||
count_iterations += 1;
|
||||
|
||||
if (verbose_flag) {
|
||||
cout << " ... " << count_iterations << " iterations"
|
||||
<< " deleted " << fun.stotal << " dangling signals"
|
||||
<< " and " << fun.etotal << " events."
|
||||
<< " (count=" << fun.count_ << ")" << endl;
|
||||
}
|
||||
|
||||
} while (fun.count_ > 0);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: nodangle.cc,v $
|
||||
* Revision 1.16 2002/07/24 16:24:45 steve
|
||||
* Rewrite find_similar_event to support doing
|
||||
* all event matching and replacement in one
|
||||
* shot, saving time in the scans.
|
||||
*
|
||||
* Revision 1.15 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
|
|
|
|||
Loading…
Reference in New Issue