Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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