Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 500 lines (422 sloc) 11.737 kB
30e8289 Simulate named event trigger and waits.
steve authored
1 /*
2 * Copyright (c) 2000 Stephen Williams (steve@icarus.com)
3 *
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.
9 *
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.
14 *
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
18 */
19 #if !defined(WINNT) && !defined(macintosh)
a4e528f Add the ivl_event_t to ivl_target, and use that to generate
steve authored
20 #ident "$Id: net_event.cc,v 1.13 2001/03/28 06:07:39 steve Exp $"
30e8289 Simulate named event trigger and waits.
steve authored
21 #endif
22
23 # include "netlist.h"
24
25 NetEvent::NetEvent(const string&n)
aac5fc2 Use char8 instead of string to store name.
steve authored
26 : name_(0)
30e8289 Simulate named event trigger and waits.
steve authored
27 {
28 scope_ = 0;
29 snext_ = 0;
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
30 probes_ = 0;
726f7b8 Synthesis of comparator in expressions.
steve authored
31 trig_ = 0;
32 waitref_ = 0;
c1c0168 Globally merge redundant event objects.
steve authored
33 wlist_ = 0;
aac5fc2 Use char8 instead of string to store name.
steve authored
34 name_ = new char[n.length()+1];
35 strcpy(name_, n.c_str());
30e8289 Simulate named event trigger and waits.
steve authored
36 }
37
38 NetEvent::~NetEvent()
39 {
726f7b8 Synthesis of comparator in expressions.
steve authored
40 assert(waitref_ == 0);
74c4303 Clean up unneeded NetEvent objects.
steve authored
41 if (scope_) scope_->rem_event(this);
42 while (probes_) {
43 NetEvProbe*tmp = probes_->enext_;
44 delete probes_;
ea53f2b Typo stepping ot next probe in delete.
steve authored
45 probes_ = tmp;
74c4303 Clean up unneeded NetEvent objects.
steve authored
46 }
aac5fc2 Use char8 instead of string to store name.
steve authored
47 delete[]name_;
30e8289 Simulate named event trigger and waits.
steve authored
48 }
49
aac5fc2 Use char8 instead of string to store name.
steve authored
50 const char* NetEvent::name() const
30e8289 Simulate named event trigger and waits.
steve authored
51 {
52 return name_;
53 }
54
55 string NetEvent::full_name() const
56 {
57 assert(scope_);
58 return scope_->name() + "." + name_;
59 }
60
a4e528f Add the ivl_event_t to ivl_target, and use that to generate
steve authored
61 const NetScope* NetEvent::scope() const
62 {
63 assert(scope_);
64 return scope_;
65 }
66
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
67 unsigned NetEvent::nprobe() const
68 {
69 unsigned cnt = 0;
70 NetEvProbe*cur = probes_;
71 while (cur) {
72 cnt += 1;
73 cur = cur->enext_;
74 }
75
76 return cnt;
77 }
78
79 NetEvProbe* NetEvent::probe(unsigned idx)
80 {
81 NetEvProbe*cur = probes_;
82 while (cur && idx) {
83 cur = cur->enext_;
84 idx -= 1;
85 }
86 return cur;
87 }
88
74c4303 Clean up unneeded NetEvent objects.
steve authored
89 unsigned NetEvent::ntrig() const
90 {
91 unsigned cnt = 0;
92 NetEvTrig*cur = trig_;
93 while (cur) {
94 cnt += 1;
95 cur = cur->enext_;
96 }
97
98 return cnt;
99 }
100
726f7b8 Synthesis of comparator in expressions.
steve authored
101 unsigned NetEvent::nwait() const
102 {
103 return waitref_;
104 }
105
bcbd5b2 Remove limits from the similar events search.
steve authored
106 /*
107 * A "similar" event is one that has an identical non-nil set of
108 * probes.
109 */
fd09bc3 Merge similar probes within a module.
steve authored
110 NetEvent* NetEvent::find_similar_event()
111 {
112 if (probes_ == 0)
113 return 0;
bcbd5b2 Remove limits from the similar events search.
steve authored
114
115 struct table_s {
116 NetEvent*ev;
117 bool mark;
118 } *table;
119
120 //NetEvent**cand;
121 //bool*cflg;
122 unsigned max_cand = 0, ncand = 0;
fd09bc3 Merge similar probes within a module.
steve authored
123
124 NetEvProbe*cur = probes_;
125
bcbd5b2 Remove limits from the similar events search.
steve authored
126 /* Get an estimate of the number of candidate events there
127 are. To get it, count the number of probes that are
128 connected to my first probe. Since there is no more then
129 one NetEvent per NetEvProbe, this is the maximum number of
130 similar events possible.
131
132 Once we get that count, allocate the arrays needed to
133 account for these events. */
fd09bc3 Merge similar probes within a module.
steve authored
134
135 for (NetNode*idx = cur->next_node()
136 ; idx && (idx != cur) ; idx = idx->next_node()) {
137 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
138 if (tmp == 0)
139 continue;
140 if (tmp->edge() != cur->edge())
141 continue;
142
bcbd5b2 Remove limits from the similar events search.
steve authored
143 max_cand += 1;
fd09bc3 Merge similar probes within a module.
steve authored
144 }
145
bcbd5b2 Remove limits from the similar events search.
steve authored
146 table = new struct table_s[max_cand];
147
148
149 /* First, locate all the candidate events from my first
150 probe. Look for all the NetEvProbe objects connected to my
151 probe (that are the same edge) and save the NetEvent that
152 that probe drives. */
153
154 for (NetNode*idx = cur->next_node()
155 ; idx && (idx != cur) ; idx = idx->next_node()) {
156 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
157 if (tmp == 0)
158 continue;
159 if (tmp->edge() != cur->edge())
160 continue;
161
162 table[ncand++].ev = tmp->event();
163 assert(ncand <= max_cand);
164 }
165
166
167 /* All the events in the cand array are now known to connect
168 through at least one NetEvProbe. Now go through all my
169 remaining probes and check that each candidate event is
170 also connected (through a NetEvProbe) to me.
171
172 By the time I finish this scan, only NetEvents that have
173 equivilent NetEvProbes remain. These are candidates. The
174 events may have *more* NetEvProbes then me, I'll catch
175 those later. */
39c71ef fix problem coalescing events w/ probes.
steve authored
176
fd09bc3 Merge similar probes within a module.
steve authored
177 for (cur = cur->enext_ ; cur && ncand ; cur = cur->enext_) {
178 for (unsigned idx = 0 ; idx < ncand ; idx += 1)
bcbd5b2 Remove limits from the similar events search.
steve authored
179 table[idx].mark = false;
fd09bc3 Merge similar probes within a module.
steve authored
180
39c71ef fix problem coalescing events w/ probes.
steve authored
181 /* For this probe, look for other probes connected to it
182 and find the event connected to it. Mark that event
183 as connected to this probe. */
184
fd09bc3 Merge similar probes within a module.
steve authored
185 for (NetNode*idx = cur->next_node()
186 ; idx && (idx != cur) ; idx = idx->next_node()) {
187 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
188 if (tmp == 0)
189 continue;
190 if (tmp->edge() != cur->edge())
191 continue;
192
193 for (unsigned srch = 0 ; srch < ncand ; srch += 1)
bcbd5b2 Remove limits from the similar events search.
steve authored
194 if (table[srch].ev == tmp->event()) {
195 table[srch].mark = true;
fd09bc3 Merge similar probes within a module.
steve authored
196 break;
197 }
198 }
199
39c71ef fix problem coalescing events w/ probes.
steve authored
200 /* Look for all the candidates that did not connect to
201 this probe (cflg is false) and eliminate them. */
202
fd09bc3 Merge similar probes within a module.
steve authored
203 for (unsigned idx = 0 ; idx < ncand ; ) {
bcbd5b2 Remove limits from the similar events search.
steve authored
204 if (table[idx].mark) {
fd09bc3 Merge similar probes within a module.
steve authored
205 idx += 1;
206 continue;
207 }
208
bcbd5b2 Remove limits from the similar events search.
steve authored
209 for (unsigned tmp = idx ; (tmp+1) < ncand ; tmp += 1)
210 table[tmp] = table[tmp+1];
211
fd09bc3 Merge similar probes within a module.
steve authored
212 ncand -= 1;
213 }
214 }
215
bcbd5b2 Remove limits from the similar events search.
steve authored
216
217 /* Scan the remaining candidates for a similar
218 NetEvent. Eliminate NetEvent objects that have more
219 NetEvProbe objects then I, because those have a proper
220 superset of my probes and were not eliminated by the
221 previous scan.
222
223 As soon as we find a similar event, we're done. */
39c71ef fix problem coalescing events w/ probes.
steve authored
224
fd09bc3 Merge similar probes within a module.
steve authored
225 for (unsigned idx = 0 ; idx < ncand ; idx += 1) {
bcbd5b2 Remove limits from the similar events search.
steve authored
226 if (table[idx].ev->nprobe() == nprobe()) {
227 NetEvent*res = table[idx].ev;
228 delete[]table;
229 return res;
230 }
fd09bc3 Merge similar probes within a module.
steve authored
231 }
232
bcbd5b2 Remove limits from the similar events search.
steve authored
233
234 /* Oops, fell off the list without finding a result. return nil. */
235 delete[]table;
fd09bc3 Merge similar probes within a module.
steve authored
236 return 0;
237 }
238
c1c0168 Globally merge redundant event objects.
steve authored
239 void NetEvent::replace_event(NetEvent*that)
240 {
241 while (wlist_) {
242 wlist_->obj->replace_event(this, that);
243 }
244 }
245
30e8289 Simulate named event trigger and waits.
steve authored
246 NetEvTrig::NetEvTrig(NetEvent*ev)
247 : event_(ev)
248 {
726f7b8 Synthesis of comparator in expressions.
steve authored
249 enext_ = event_->trig_;
250 event_->trig_ = this;
30e8289 Simulate named event trigger and waits.
steve authored
251 }
252
253 NetEvTrig::~NetEvTrig()
254 {
726f7b8 Synthesis of comparator in expressions.
steve authored
255 if (event_->trig_ == this) {
256 event_->trig_ = enext_;
257
258 } else {
259 NetEvTrig*cur = event_->trig_;
260 while (cur->enext_ != this) {
261 assert(cur->enext_);
262 cur = cur->enext_;
263 }
264
265 cur->enext_ = this->enext_;
266 }
30e8289 Simulate named event trigger and waits.
steve authored
267 }
268
269 const NetEvent* NetEvTrig::event() const
270 {
271 return event_;
272 }
273
8dbd641 All events now use the NetEvent class.
steve authored
274 NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
275 edge_t t, unsigned p)
276 : NetNode(n, p), event_(tgt), edge_(t)
277 {
278 for (unsigned idx = 0 ; idx < p ; idx += 1) {
279 pin(idx).set_dir(Link::INPUT);
280 pin(idx).set_name("P", idx);
281 }
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
282
283 enext_ = event_->probes_;
284 event_->probes_ = this;
8dbd641 All events now use the NetEvent class.
steve authored
285 }
286
287 NetEvProbe::~NetEvProbe()
288 {
726f7b8 Synthesis of comparator in expressions.
steve authored
289 if (event_->probes_ == this) {
290 event_->probes_ = enext_;
291
292 } else {
293 NetEvProbe*cur = event_->probes_;
294 while (cur->enext_ != this) {
295 assert(cur->enext_);
296 cur = cur->enext_;
297 }
298
299 cur->enext_ = this->enext_;
300 }
8dbd641 All events now use the NetEvent class.
steve authored
301 }
302
303 NetEvProbe::edge_t NetEvProbe::edge() const
304 {
305 return edge_;
306 }
307
fd09bc3 Merge similar probes within a module.
steve authored
308 NetEvent* NetEvProbe::event()
309 {
310 return event_;
311 }
312
8dbd641 All events now use the NetEvent class.
steve authored
313 const NetEvent* NetEvProbe::event() const
314 {
315 return event_;
316 }
317
b1fd927 Named events really should be expressed with PEIdent
steve authored
318 NetEvWait::NetEvWait(NetProc*pr)
319 : statement_(pr), nevents_(0), events_(0)
30e8289 Simulate named event trigger and waits.
steve authored
320 {
321 }
322
323 NetEvWait::~NetEvWait()
324 {
726f7b8 Synthesis of comparator in expressions.
steve authored
325 if (events_) {
326 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
327 NetEvent*tgt = events_[idx];
328 tgt->waitref_ -= 1;
c1c0168 Globally merge redundant event objects.
steve authored
329
330 struct NetEvent::wcell_*tmp = tgt->wlist_;
331 if (tmp->obj == this) {
332 tgt->wlist_ = tmp->next;
333 delete tmp;
334 } else {
335 assert(tmp->next);
336 while (tmp->next->obj != this) {
337 tmp = tmp->next;
338 assert(tmp->next);
339 }
340 tmp->next = tmp->next->next;
341 delete tmp;
342 }
726f7b8 Synthesis of comparator in expressions.
steve authored
343 }
344 delete[]events_;
345 }
30e8289 Simulate named event trigger and waits.
steve authored
346 delete statement_;
347 }
348
b1fd927 Named events really should be expressed with PEIdent
steve authored
349 void NetEvWait::add_event(NetEvent*tgt)
30e8289 Simulate named event trigger and waits.
steve authored
350 {
b1fd927 Named events really should be expressed with PEIdent
steve authored
351 assert(tgt);
352 if (nevents_ == 0) {
353 events_ = new NetEvent*[1];
354
355 } else {
356 NetEvent**tmp = new NetEvent*[nevents_+1];
357 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
358 tmp[idx] = events_[idx];
359 assert(tmp[idx] != tgt);
360 }
361 delete[]events_;
362 events_ = tmp;
363 }
364
365 events_[nevents_] = tgt;
366 nevents_ += 1;
726f7b8 Synthesis of comparator in expressions.
steve authored
367
368 // Remember to tell the NetEvent that there is someone
369 // pointing to it.
370 tgt->waitref_ += 1;
c1c0168 Globally merge redundant event objects.
steve authored
371
372 struct NetEvent::wcell_*tmp = new NetEvent::wcell_;
373 tmp->obj = this;
374 tmp->next = tgt->wlist_;
375 tgt->wlist_ = tmp;
376 }
377
378 void NetEvWait::replace_event(NetEvent*src, NetEvent*repl)
379 {
380 unsigned idx;
381 for (idx = 0 ; idx < nevents_ ; idx += 1) {
382 if (events_[idx] == src)
383 break;
384 }
385
386 assert(idx < nevents_);
387
388 /* First, remove me from the list held by the src NetEvent. */
389 assert(src->waitref_ > 0);
390 src->waitref_ -= 1;
391 struct NetEvent::wcell_*tmp = src->wlist_;
392 if (tmp->obj == this) {
393 src->wlist_ = tmp->next;
394 delete tmp;
395 } else {
396 assert(tmp->next);
397 while (tmp->next->obj != this) {
398 tmp = tmp->next;
399 assert(tmp->next);
400 }
401 tmp->next = tmp->next->next;
402 delete tmp;
403 }
404
405 events_[idx] = repl;
406
407 // Remember to tell the replacement NetEvent that there is
408 // someone pointing to it.
409 repl->waitref_ += 1;
410
411 tmp = new NetEvent::wcell_;
412 tmp->obj = this;
413 tmp->next = repl->wlist_;
414 repl->wlist_ = tmp;
415
b1fd927 Named events really should be expressed with PEIdent
steve authored
416 }
417
418 unsigned NetEvWait::nevents() const
419 {
420 return nevents_;
421 }
422
423 const NetEvent* NetEvWait::event(unsigned idx) const
424 {
425 assert(idx < nevents_);
426 return events_[idx];
30e8289 Simulate named event trigger and waits.
steve authored
427 }
428
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
429 NetEvent* NetEvWait::event(unsigned idx)
430 {
431 assert(idx < nevents_);
432 return events_[idx];
433 }
434
435 NetProc* NetEvWait::statement()
436 {
437 return statement_;
438 }
439
30e8289 Simulate named event trigger and waits.
steve authored
440 /*
441 * $Log: net_event.cc,v $
a4e528f Add the ivl_event_t to ivl_target, and use that to generate
steve authored
442 * Revision 1.13 2001/03/28 06:07:39 steve
443 * Add the ivl_event_t to ivl_target, and use that to generate
444 * .event statements in vvp way ahead of the thread that uses it.
445 *
bcbd5b2 Remove limits from the similar events search.
steve authored
446 * Revision 1.12 2000/12/15 17:45:07 steve
447 * Remove limits from the similar events search.
448 *
aac5fc2 Use char8 instead of string to store name.
steve authored
449 * Revision 1.11 2000/10/04 16:30:39 steve
450 * Use char8 instead of string to store name.
451 *
ea53f2b Typo stepping ot next probe in delete.
steve authored
452 * Revision 1.10 2000/09/19 03:00:36 steve
453 * Typo stepping ot next probe in delete.
454 *
39c71ef fix problem coalescing events w/ probes.
steve authored
455 * Revision 1.9 2000/07/29 03:55:38 steve
456 * fix problem coalescing events w/ probes.
457 *
c1c0168 Globally merge redundant event objects.
steve authored
458 * Revision 1.8 2000/05/31 02:26:49 steve
459 * Globally merge redundant event objects.
460 *
fd09bc3 Merge similar probes within a module.
steve authored
461 * Revision 1.7 2000/05/27 19:33:23 steve
462 * Merge similar probes within a module.
463 *
74c4303 Clean up unneeded NetEvent objects.
steve authored
464 * Revision 1.6 2000/04/18 04:50:20 steve
465 * Clean up unneeded NetEvent objects.
466 *
726f7b8 Synthesis of comparator in expressions.
steve authored
467 * Revision 1.5 2000/04/16 23:32:18 steve
468 * Synthesis of comparator in expressions.
469 *
470 * Connect the NetEvent and related classes
471 * together better.
472 *
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
473 * Revision 1.4 2000/04/12 20:02:53 steve
474 * Finally remove the NetNEvent and NetPEvent classes,
475 * Get synthesis working with the NetEvWait class,
476 * and get started supporting multiple events in a
477 * wait in vvm.
478 *
b1fd927 Named events really should be expressed with PEIdent
steve authored
479 * Revision 1.3 2000/04/12 04:23:58 steve
480 * Named events really should be expressed with PEIdent
481 * objects in the pform,
482 *
483 * Handle named events within the mix of net events
484 * and edges. As a unified lot they get caught together.
485 * wait statements are broken into more complex statements
486 * that include a conditional.
487 *
488 * Do not generate NetPEvent or NetNEvent objects in
489 * elaboration. NetEvent, NetEvWait and NetEvProbe
490 * take over those functions in the netlist.
491 *
8dbd641 All events now use the NetEvent class.
steve authored
492 * Revision 1.2 2000/04/10 05:26:06 steve
493 * All events now use the NetEvent class.
494 *
30e8289 Simulate named event trigger and waits.
steve authored
495 * Revision 1.1 2000/04/04 03:20:15 steve
496 * Simulate named event trigger and waits.
497 *
498 */
499
Something went wrong with that request. Please try again.