Merge similar probes within a module.
[iverilog.git] / net_event.cc
blob0f054bbc1344f125cf3564249941767cf1f708a1
1 /*
2 * Copyright (c) 2000 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #if !defined(WINNT) && !defined(macintosh)
20 #ident "$Id: net_event.cc,v 1.7 2000/05/27 19:33:23 steve Exp $"
21 #endif
23 # include "netlist.h"
25 NetEvent::NetEvent(const string&n)
26 : name_(n)
28 scope_ = 0;
29 snext_ = 0;
30 probes_ = 0;
31 trig_ = 0;
32 waitref_ = 0;
35 NetEvent::~NetEvent()
37 assert(waitref_ == 0);
38 if (scope_) scope_->rem_event(this);
39 while (probes_) {
40 NetEvProbe*tmp = probes_->enext_;
41 delete probes_;
42 tmp = probes_;
46 string NetEvent::name() const
48 return name_;
51 string NetEvent::full_name() const
53 assert(scope_);
54 return scope_->name() + "." + name_;
57 unsigned NetEvent::nprobe() const
59 unsigned cnt = 0;
60 NetEvProbe*cur = probes_;
61 while (cur) {
62 cnt += 1;
63 cur = cur->enext_;
66 return cnt;
69 NetEvProbe* NetEvent::probe(unsigned idx)
71 NetEvProbe*cur = probes_;
72 while (cur && idx) {
73 cur = cur->enext_;
74 idx -= 1;
76 return cur;
79 unsigned NetEvent::ntrig() const
81 unsigned cnt = 0;
82 NetEvTrig*cur = trig_;
83 while (cur) {
84 cnt += 1;
85 cur = cur->enext_;
88 return cnt;
91 unsigned NetEvent::nwait() const
93 return waitref_;
96 NetEvent* NetEvent::find_similar_event()
98 if (probes_ == 0)
99 return 0;
100 #define NCAND 256
101 NetEvent*cand[NCAND];
102 bool cflg[NCAND];
103 unsigned ncand = 0;
105 NetEvProbe*cur = probes_;
107 /* First locate all the canditate events from the probe
108 objects that are connected to them. */
110 for (NetNode*idx = cur->next_node()
111 ; idx && (idx != cur) ; idx = idx->next_node()) {
112 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
113 if (tmp == 0)
114 continue;
115 if (tmp->edge() != cur->edge())
116 continue;
118 cand[ncand++] = tmp->event();
119 assert(ncand <= NCAND);
122 for (cur = cur->enext_ ; cur && ncand ; cur = cur->enext_) {
123 for (unsigned idx = 0 ; idx < ncand ; idx += 1)
124 cflg[idx] = false;
126 for (NetNode*idx = cur->next_node()
127 ; idx && (idx != cur) ; idx = idx->next_node()) {
128 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
129 if (tmp == 0)
130 continue;
131 if (tmp->edge() != cur->edge())
132 continue;
134 for (unsigned srch = 0 ; srch < ncand ; srch += 1)
135 if (cand[srch] == tmp->event()) {
136 cflg[srch] = true;
137 break;
141 for (unsigned idx = 0 ; idx < ncand ; ) {
142 if (cflg[idx]) {
143 idx += 1;
144 continue;
147 for (unsigned tmp = idx ; idx+1 < ncand ; idx += 1) {
148 cflg[tmp] = cflg[tmp+1];
149 cand[tmp] = cand[tmp+1];
151 ncand -= 1;
155 for (unsigned idx = 0 ; idx < ncand ; idx += 1) {
156 if (cand[idx]->nprobe() == nprobe())
157 return cand[idx];
160 return 0;
163 NetEvTrig::NetEvTrig(NetEvent*ev)
164 : event_(ev)
166 enext_ = event_->trig_;
167 event_->trig_ = this;
170 NetEvTrig::~NetEvTrig()
172 if (event_->trig_ == this) {
173 event_->trig_ = enext_;
175 } else {
176 NetEvTrig*cur = event_->trig_;
177 while (cur->enext_ != this) {
178 assert(cur->enext_);
179 cur = cur->enext_;
182 cur->enext_ = this->enext_;
186 const NetEvent* NetEvTrig::event() const
188 return event_;
191 NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
192 edge_t t, unsigned p)
193 : NetNode(n, p), event_(tgt), edge_(t)
195 for (unsigned idx = 0 ; idx < p ; idx += 1) {
196 pin(idx).set_dir(Link::INPUT);
197 pin(idx).set_name("P", idx);
200 enext_ = event_->probes_;
201 event_->probes_ = this;
204 NetEvProbe::~NetEvProbe()
206 if (event_->probes_ == this) {
207 event_->probes_ = enext_;
209 } else {
210 NetEvProbe*cur = event_->probes_;
211 while (cur->enext_ != this) {
212 assert(cur->enext_);
213 cur = cur->enext_;
216 cur->enext_ = this->enext_;
220 NetEvProbe::edge_t NetEvProbe::edge() const
222 return edge_;
225 NetEvent* NetEvProbe::event()
227 return event_;
230 const NetEvent* NetEvProbe::event() const
232 return event_;
235 NetEvWait::NetEvWait(NetProc*pr)
236 : statement_(pr), nevents_(0), events_(0)
240 NetEvWait::~NetEvWait()
242 if (events_) {
243 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
244 NetEvent*tgt = events_[idx];
245 tgt->waitref_ -= 1;
247 delete[]events_;
249 delete statement_;
252 void NetEvWait::add_event(NetEvent*tgt)
254 assert(tgt);
255 if (nevents_ == 0) {
256 events_ = new NetEvent*[1];
258 } else {
259 NetEvent**tmp = new NetEvent*[nevents_+1];
260 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
261 tmp[idx] = events_[idx];
262 assert(tmp[idx] != tgt);
264 delete[]events_;
265 events_ = tmp;
268 events_[nevents_] = tgt;
269 nevents_ += 1;
271 // Remember to tell the NetEvent that there is someone
272 // pointing to it.
273 tgt->waitref_ += 1;
276 unsigned NetEvWait::nevents() const
278 return nevents_;
281 const NetEvent* NetEvWait::event(unsigned idx) const
283 assert(idx < nevents_);
284 return events_[idx];
287 NetEvent* NetEvWait::event(unsigned idx)
289 assert(idx < nevents_);
290 return events_[idx];
293 NetProc* NetEvWait::statement()
295 return statement_;
299 * $Log: net_event.cc,v $
300 * Revision 1.7 2000/05/27 19:33:23 steve
301 * Merge similar probes within a module.
303 * Revision 1.6 2000/04/18 04:50:20 steve
304 * Clean up unneeded NetEvent objects.
306 * Revision 1.5 2000/04/16 23:32:18 steve
307 * Synthesis of comparator in expressions.
309 * Connect the NetEvent and related classes
310 * together better.
312 * Revision 1.4 2000/04/12 20:02:53 steve
313 * Finally remove the NetNEvent and NetPEvent classes,
314 * Get synthesis working with the NetEvWait class,
315 * and get started supporting multiple events in a
316 * wait in vvm.
318 * Revision 1.3 2000/04/12 04:23:58 steve
319 * Named events really should be expressed with PEIdent
320 * objects in the pform,
322 * Handle named events within the mix of net events
323 * and edges. As a unified lot they get caught together.
324 * wait statements are broken into more complex statements
325 * that include a conditional.
327 * Do not generate NetPEvent or NetNEvent objects in
328 * elaboration. NetEvent, NetEvWait and NetEvProbe
329 * take over those functions in the netlist.
331 * Revision 1.2 2000/04/10 05:26:06 steve
332 * All events now use the NetEvent class.
334 * Revision 1.1 2000/04/04 03:20:15 steve
335 * Simulate named event trigger and waits.