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:
steve 2002-07-24 16:24:45 +00:00
parent 843e1f9c44
commit 58ec62c895
4 changed files with 148 additions and 165 deletions

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.