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)
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
20 #ident "$Id: net_event.cc,v 1.27 2007/06/02 03:42:13 steve Exp $"
24 # include "compiler.h"
28 * NOTE: The name_ is perm-allocated by the caller.
30 NetEvent::NetEvent(perm_string n
)
44 assert(waitref_
== 0);
45 if (scope_
) scope_
->rem_event(this);
47 NetEvProbe
*tmp
= probes_
->enext_
;
51 /* name_ is lex_strings. */
54 perm_string
NetEvent::name() const
59 NetScope
* NetEvent::scope()
65 const NetScope
* NetEvent::scope() const
71 unsigned NetEvent::nprobe() const
74 NetEvProbe
*cur
= probes_
;
83 NetEvProbe
* NetEvent::probe(unsigned idx
)
85 NetEvProbe
*cur
= probes_
;
93 const NetEvProbe
* NetEvent::probe(unsigned idx
) const
95 NetEvProbe
*cur
= probes_
;
103 unsigned NetEvent::ntrig() const
106 NetEvTrig
*cur
= trig_
;
115 unsigned NetEvent::nwait() const
120 unsigned NetEvent::nexpr() const
126 * A "similar" event is one that has an identical non-nil set of
129 void NetEvent::find_similar_event(list
<NetEvent
*>&event_list
)
134 map
<NetEvent
*,unsigned> event_matches
;
136 /* First, get a list of all the NetEvProbes that are connected
137 to my first probe. Then use that to create a set of
138 candidate events. These candidate events are a superset of
139 the similar events, so I will be culling this list later. */
140 list
<NetEvProbe
*>first_probes
;
141 probes_
->find_similar_probes(first_probes
);
143 for (list
<NetEvProbe
*>::iterator idx
= first_probes
.begin()
144 ; idx
!= first_probes
.end() ; idx
++) {
145 event_matches
[ (*idx
)->event() ] = 1;
148 /* Now scan the remaining probes, in each case ticking the
149 candidate event. The events that really are similar to this
150 one will turn up in every probe list. */
151 unsigned probe_count
= 1;
152 for (NetEvProbe
*cur
= probes_
->enext_
; cur
; cur
= cur
->enext_
) {
153 list
<NetEvProbe
*>similar_probes
;
154 cur
->find_similar_probes(similar_probes
);
156 for (list
<NetEvProbe
*>::iterator idx
= similar_probes
.begin()
157 ; idx
!= similar_probes
.end() ; idx
++) {
158 event_matches
[ (*idx
)->event() ] += 1;
164 /* Now scan the candidate events. Those events that are
165 connected to all my probes (match_count[x] == probe_count)
166 are possible. If those events have the same number of
167 events, then jackpot. */
168 for (map
<NetEvent
*,unsigned>::iterator idx
= event_matches
.begin()
169 ; idx
!= event_matches
.end() ; idx
++) {
171 NetEvent
*tmp
= (*idx
).first
;
176 if ((*idx
).second
!= probe_count
)
180 for (NetEvProbe
*cur
= tmp
->probes_
; cur
; cur
= cur
->enext_
)
183 if (tcnt
== probe_count
)
184 event_list
.push_back(tmp
);
190 void NetEvent::replace_event(NetEvent
*that
)
193 wlist_
->obj
->replace_event(this, that
);
197 NexusSet
* NetEvent::nex_async_()
199 /* If there are behavioral trigger statements attached to me,
200 then this is not an asynchronous event. */
205 NexusSet
*tmp
= new NexusSet
;
206 for (NetEvProbe
*cur
= probes_
; cur
!= 0 ; cur
= cur
->enext_
) {
207 if (cur
->edge() != NetEvProbe::ANYEDGE
) {
212 for (unsigned idx
= 0 ; idx
< cur
->pin_count() ; idx
+= 1)
213 tmp
->add(cur
->pin(idx
).nexus());
220 NetEvTrig::NetEvTrig(NetEvent
*ev
)
223 enext_
= event_
->trig_
;
224 event_
->trig_
= this;
227 NetEvTrig::~NetEvTrig()
229 if (event_
->trig_
== this) {
230 event_
->trig_
= enext_
;
233 NetEvTrig
*cur
= event_
->trig_
;
234 while (cur
->enext_
!= this) {
239 cur
->enext_
= this->enext_
;
243 const NetEvent
* NetEvTrig::event() const
248 NetEvProbe::NetEvProbe(NetScope
*s
, perm_string n
, NetEvent
*tgt
,
249 edge_t t
, unsigned p
)
250 : NetNode(s
, n
, p
), event_(tgt
), edge_(t
)
252 for (unsigned idx
= 0 ; idx
< p
; idx
+= 1) {
253 pin(idx
).set_dir(Link::INPUT
);
254 pin(idx
).set_name(perm_string::literal("P"), idx
);
257 enext_
= event_
->probes_
;
258 event_
->probes_
= this;
261 NetEvProbe::~NetEvProbe()
263 if (event_
->probes_
== this) {
264 event_
->probes_
= enext_
;
267 NetEvProbe
*cur
= event_
->probes_
;
268 while (cur
->enext_
!= this) {
273 cur
->enext_
= this->enext_
;
277 NetEvProbe::edge_t
NetEvProbe::edge() const
282 NetEvent
* NetEvProbe::event()
287 const NetEvent
* NetEvProbe::event() const
293 * A similar NetEvProbe is one that is connected to all the same nexa
294 * that this probe is connected to, and also is the same edge
295 * type. Don't count myself as a similar probe.
297 void NetEvProbe::find_similar_probes(list
<NetEvProbe
*>&plist
)
299 Nexus
*nex
= pin(0).nexus();
301 for (Link
*lcur
= nex
->first_nlink(); lcur
; lcur
= lcur
->next_nlink()) {
302 NetObj
*obj
= lcur
->get_obj();
303 if (obj
->pin_count() != pin_count())
306 NetEvProbe
*tmp
= dynamic_cast<NetEvProbe
*>(obj
);
313 if (edge() != tmp
->edge())
317 for (unsigned idx
= 1 ; idx
< pin_count() ; idx
+= 1)
318 if (pin(idx
).nexus() != tmp
->pin(idx
).nexus()) {
324 plist
.push_back(tmp
);
328 NetEvWait::NetEvWait(NetProc
*pr
)
329 : statement_(pr
), nevents_(0), events_(0)
333 NetEvWait::~NetEvWait()
336 for (unsigned idx
= 0 ; idx
< nevents_
; idx
+= 1) {
337 NetEvent
*tgt
= events_
[idx
];
340 struct NetEvent::wcell_
*tmp
= tgt
->wlist_
;
341 if (tmp
->obj
== this) {
342 tgt
->wlist_
= tmp
->next
;
346 while (tmp
->next
->obj
!= this) {
350 tmp
->next
= tmp
->next
->next
;
359 void NetEvWait::add_event(NetEvent
*tgt
)
363 events_
= new NetEvent
*[1];
366 NetEvent
**tmp
= new NetEvent
*[nevents_
+1];
367 for (unsigned idx
= 0 ; idx
< nevents_
; idx
+= 1) {
368 tmp
[idx
] = events_
[idx
];
369 assert(tmp
[idx
] != tgt
);
375 events_
[nevents_
] = tgt
;
378 // Remember to tell the NetEvent that there is someone
382 struct NetEvent::wcell_
*tmp
= new NetEvent::wcell_
;
384 tmp
->next
= tgt
->wlist_
;
388 void NetEvWait::replace_event(NetEvent
*src
, NetEvent
*repl
)
391 for (idx
= 0 ; idx
< nevents_
; idx
+= 1) {
392 if (events_
[idx
] == src
)
396 assert(idx
< nevents_
);
398 /* First, remove me from the list held by the src NetEvent. */
399 assert(src
->waitref_
> 0);
401 struct NetEvent::wcell_
*tmp
= src
->wlist_
;
402 if (tmp
->obj
== this) {
403 src
->wlist_
= tmp
->next
;
407 while (tmp
->next
->obj
!= this) {
411 tmp
->next
= tmp
->next
->next
;
417 // Remember to tell the replacement NetEvent that there is
418 // someone pointing to it.
421 tmp
= new NetEvent::wcell_
;
423 tmp
->next
= repl
->wlist_
;
428 unsigned NetEvWait::nevents() const
433 const NetEvent
* NetEvWait::event(unsigned idx
) const
435 assert(idx
< nevents_
);
439 NetEvent
* NetEvWait::event(unsigned idx
)
441 assert(idx
< nevents_
);
445 NetProc
* NetEvWait::statement()
451 * $Log: net_event.cc,v $
452 * Revision 1.27 2007/06/02 03:42:13 steve
453 * Properly evaluate scope path expressions.
455 * Revision 1.26 2004/10/04 01:10:54 steve
456 * Clean up spurious trailing white space.
458 * Revision 1.25 2004/02/19 06:57:10 steve
459 * Memory and Event names use perm_string.
461 * Revision 1.24 2004/02/18 17:11:56 steve
462 * Use perm_strings for named langiage items.
464 * Revision 1.23 2003/04/22 04:48:29 steve
465 * Support event names as expressions elements.
467 * Revision 1.22 2003/03/06 00:28:41 steve
468 * All NetObj objects have lex_string base names.
470 * Revision 1.21 2003/03/01 06:25:30 steve
471 * Add the lex_strings string handler, and put
472 * scope names and system task/function names
473 * into this table. Also, permallocate event
474 * names from the beginning.
476 * Revision 1.20 2002/08/12 01:34:59 steve
477 * conditional ident string using autoconfig.
479 * Revision 1.19 2002/07/24 16:24:45 steve
480 * Rewrite find_similar_event to support doing
481 * all event matching and replacement in one
482 * shot, saving time in the scans.
484 * Revision 1.18 2002/06/30 02:21:31 steve
485 * Add structure for asynchronous logic synthesis.
487 * Revision 1.17 2002/02/02 06:13:38 steve
488 * event find_similar should not find self.
490 * Revision 1.16 2001/10/28 01:14:53 steve
491 * NetObj constructor finally requires a scope.
493 * Revision 1.15 2001/07/25 03:10:49 steve
494 * Create a config.h.in file to hold all the config
495 * junk, and support gcc 3.0. (Stephan Boettcher)
497 * Revision 1.14 2001/03/29 02:52:19 steve
498 * Add const probe method to NetEvent.
500 * Revision 1.13 2001/03/28 06:07:39 steve
501 * Add the ivl_event_t to ivl_target, and use that to generate
502 * .event statements in vvp way ahead of the thread that uses it.
504 * Revision 1.12 2000/12/15 17:45:07 steve
505 * Remove limits from the similar events search.
507 * Revision 1.11 2000/10/04 16:30:39 steve
508 * Use char8 instead of string to store name.
510 * Revision 1.10 2000/09/19 03:00:36 steve
511 * Typo stepping ot next probe in delete.
513 * Revision 1.9 2000/07/29 03:55:38 steve
514 * fix problem coalescing events w/ probes.
516 * Revision 1.8 2000/05/31 02:26:49 steve
517 * Globally merge redundant event objects.
519 * Revision 1.7 2000/05/27 19:33:23 steve
520 * Merge similar probes within a module.
522 * Revision 1.6 2000/04/18 04:50:20 steve
523 * Clean up unneeded NetEvent objects.
525 * Revision 1.5 2000/04/16 23:32:18 steve
526 * Synthesis of comparator in expressions.
528 * Connect the NetEvent and related classes
531 * Revision 1.4 2000/04/12 20:02:53 steve
532 * Finally remove the NetNEvent and NetPEvent classes,
533 * Get synthesis working with the NetEvWait class,
534 * and get started supporting multiple events in a
537 * Revision 1.3 2000/04/12 04:23:58 steve
538 * Named events really should be expressed with PEIdent
539 * objects in the pform,
541 * Handle named events within the mix of net events
542 * and edges. As a unified lot they get caught together.
543 * wait statements are broken into more complex statements
544 * that include a conditional.
546 * Do not generate NetPEvent or NetNEvent objects in
547 * elaboration. NetEvent, NetEvWait and NetEvProbe
548 * take over those functions in the netlist.
550 * Revision 1.2 2000/04/10 05:26:06 steve
551 * All events now use the NetEvent class.
553 * Revision 1.1 2000/04/04 03:20:15 steve
554 * Simulate named event trigger and waits.