Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 461 lines (382 sloc) 10.401 kb
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
1 /*
225ca1e2 » caryr
2010-10-23 Change iterators to use prefix ++ since it is more efficient.
2 * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
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
badad63a » steve
2003-03-06 All NetObj objects have lex_string base names.
20 # include "config.h"
21 # include "compiler.h"
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
22 # include "netlist.h"
23
4c67de5c » steve
2003-03-01 Add the lex_strings string handler, and put
24 /*
25 * NOTE: The name_ is perm-allocated by the caller.
26 */
536068bd » steve
2004-02-19 Memory and Event names use perm_string.
27 NetEvent::NetEvent(perm_string n)
4c67de5c » steve
2003-03-01 Add the lex_strings string handler, and put
28 : name_(n)
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
29 {
30 scope_ = 0;
31 snext_ = 0;
4493e968 » steve
2000-04-12 Finally remove the NetNEvent and NetPEvent classes,
32 probes_ = 0;
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
33 trig_ = 0;
34 waitref_ = 0;
f1cc9d86 » steve
2003-04-22 Support event names as expressions elements.
35 exprref_ = 0;
c1c01688 » steve
2000-05-31 Globally merge redundant event objects.
36 wlist_ = 0;
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
37 }
38
39 NetEvent::~NetEvent()
40 {
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
41 assert(waitref_ == 0);
74c43032 » steve
2000-04-18 Clean up unneeded NetEvent objects.
42 if (scope_) scope_->rem_event(this);
43 while (probes_) {
44 NetEvProbe*tmp = probes_->enext_;
45 delete probes_;
ea53f2b5 » steve
2000-09-19 Typo stepping ot next probe in delete.
46 probes_ = tmp;
74c43032 » steve
2000-04-18 Clean up unneeded NetEvent objects.
47 }
4c67de5c » steve
2003-03-01 Add the lex_strings string handler, and put
48 /* name_ is lex_strings. */
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
49 }
50
536068bd » steve
2004-02-19 Memory and Event names use perm_string.
51 perm_string NetEvent::name() const
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
52 {
53 return name_;
54 }
55
c7d97f41 » steve
2007-06-02 Properly evaluate scope path expressions.
56 NetScope* NetEvent::scope()
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
57 {
58 assert(scope_);
c7d97f41 » steve
2007-06-02 Properly evaluate scope path expressions.
59 return scope_;
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
60 }
61
a4e528f0 » steve
2001-03-28 Add the ivl_event_t to ivl_target, and use that to generate
62 const NetScope* NetEvent::scope() const
63 {
64 assert(scope_);
65 return scope_;
66 }
67
4493e968 » steve
2000-04-12 Finally remove the NetNEvent and NetPEvent classes,
68 unsigned NetEvent::nprobe() const
69 {
70 unsigned cnt = 0;
71 NetEvProbe*cur = probes_;
72 while (cur) {
73 cnt += 1;
74 cur = cur->enext_;
75 }
76
77 return cnt;
78 }
79
80 NetEvProbe* NetEvent::probe(unsigned idx)
81 {
82 NetEvProbe*cur = probes_;
83 while (cur && idx) {
84 cur = cur->enext_;
85 idx -= 1;
86 }
87 return cur;
88 }
89
ad8565f8 » steve
2001-03-29 Add const probe method to NetEvent.
90 const NetEvProbe* NetEvent::probe(unsigned idx) const
91 {
92 NetEvProbe*cur = probes_;
93 while (cur && idx) {
94 cur = cur->enext_;
95 idx -= 1;
96 }
97 return cur;
98 }
99
74c43032 » steve
2000-04-18 Clean up unneeded NetEvent objects.
100 unsigned NetEvent::ntrig() const
101 {
102 unsigned cnt = 0;
103 NetEvTrig*cur = trig_;
104 while (cur) {
105 cnt += 1;
106 cur = cur->enext_;
107 }
108
109 return cnt;
110 }
111
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
112 unsigned NetEvent::nwait() const
113 {
114 return waitref_;
115 }
116
f1cc9d86 » steve
2003-04-22 Support event names as expressions elements.
117 unsigned NetEvent::nexpr() const
118 {
119 return exprref_;
120 }
121
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
122 /*
123 * A "similar" event is one that has an identical non-nil set of
124 * probes.
125 */
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
126 void NetEvent::find_similar_event(list<NetEvent*>&event_list)
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
127 {
128 if (probes_ == 0)
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
129 return;
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
130
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
131 set<NetEvent*> candidate_events;
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
132
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
133 /* First, get a list of all the NetEvProbes that are connected
134 to my first probe. Then use that to create a set of
135 candidate events. These candidate events are a superset of
136 the similar events, so I will be culling this list later. */
137 list<NetEvProbe*>first_probes;
138 probes_->find_similar_probes(first_probes);
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
139
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
140 for (list<NetEvProbe*>::iterator idx = first_probes.begin()
225ca1e2 » caryr
2010-10-23 Change iterators to use prefix ++ since it is more efficient.
141 ; idx != first_probes.end() ; ++ idx ) {
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
142
143 candidate_events.insert( (*idx)->event() );
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
144 }
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
145
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
146 if (candidate_events.empty())
147 return;
148
149 /* Now scan the remaining probes, in each case checking that
150 the probe event is a candidate event. After each iteration,
151 events that don't have a similar probe will be removed from
152 the candidate_events set. If the candidate_events set
153 becomes empty, then give up. */
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
154 unsigned probe_count = 1;
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
155 for (NetEvProbe*cur = probes_->enext_ ; cur; cur = cur->enext_) {
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
156 list<NetEvProbe*>similar_probes;
157 cur->find_similar_probes(similar_probes);
158
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
159 set<NetEvent*> candidate_tmp;
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
160 for (list<NetEvProbe*>::iterator idx = similar_probes.begin()
225ca1e2 » caryr
2010-10-23 Change iterators to use prefix ++ since it is more efficient.
161 ; idx != similar_probes.end() ; ++ idx ) {
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
162
163 NetEvent*tmp = (*idx)->event();
164 if (candidate_events.find(tmp) != candidate_events.end())
165 candidate_tmp .insert(tmp);
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
166 }
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
167
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
168 // None of the candidate events match this probe? Give up!
169 if (candidate_tmp.empty())
170 return;
171
172 candidate_events = candidate_tmp;
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
173 probe_count += 1;
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
174 }
175
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
176 /* Scan the surviving candidate events. We know that they all
177 have probes that match the current event's probes. Check
178 for remaining compatibility details and save the survivors
179 in the event_list that the caller passed. */
180 for (set<NetEvent*>::iterator idx = candidate_events.begin()
225ca1e2 » caryr
2010-10-23 Change iterators to use prefix ++ since it is more efficient.
181 ; idx != candidate_events.end() ; ++ idx ) {
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
182
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
183 NetEvent*tmp = *idx;
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
184
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
185 // This shouldn't be possible?
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
186 if (tmp == this)
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
187 continue;
188
18edf2f1 » Martin Whitaker
2008-10-28 Rework of automatic task/function support.
189 /* For automatic tasks, the VVP runtime holds state for events
190 in the automatically allocated context. This means we can't
191 merge similar events in different automatic tasks. */
192 if (scope()->is_auto() && (tmp->scope() != scope()))
193 continue;
194
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
195 unsigned tcnt = 0;
196 for (NetEvProbe*cur = tmp->probes_ ; cur ; cur = cur->enext_)
197 tcnt += 1;
bcbd5b2c » steve
2000-12-15 Remove limits from the similar events search.
198
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
199 if (tcnt == probe_count)
200 event_list .push_back(tmp);
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
201 }
202
203 }
204
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
205
c1c01688 » steve
2000-05-31 Globally merge redundant event objects.
206 void NetEvent::replace_event(NetEvent*that)
207 {
208 while (wlist_) {
209 wlist_->obj->replace_event(this, that);
210 }
211 }
212
9b6b081e » steve
2002-06-30 Add structure for asynchronous logic synthesis.
213 NexusSet* NetEvent::nex_async_()
214 {
215 /* If there are behavioral trigger statements attached to me,
216 then this is not an asynchronous event. */
217 if (trig_ != 0)
218 return 0;
219
e4ae8321 » steve
2004-10-04 Clean up spurious trailing white space.
220
9b6b081e » steve
2002-06-30 Add structure for asynchronous logic synthesis.
221 NexusSet*tmp = new NexusSet;
222 for (NetEvProbe*cur = probes_ ; cur != 0 ; cur = cur->enext_) {
223 if (cur->edge() != NetEvProbe::ANYEDGE) {
224 delete tmp;
225 return 0;
226 }
227
228 for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1)
229 tmp->add(cur->pin(idx).nexus());
230
231 }
232
233 return tmp;
234 }
235
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
236 NetEvTrig::NetEvTrig(NetEvent*ev)
237 : event_(ev)
238 {
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
239 enext_ = event_->trig_;
240 event_->trig_ = this;
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
241 }
242
243 NetEvTrig::~NetEvTrig()
244 {
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
245 if (event_->trig_ == this) {
246 event_->trig_ = enext_;
247
248 } else {
249 NetEvTrig*cur = event_->trig_;
250 while (cur->enext_ != this) {
251 assert(cur->enext_);
252 cur = cur->enext_;
253 }
254
255 cur->enext_ = this->enext_;
256 }
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
257 }
258
259 const NetEvent* NetEvTrig::event() const
260 {
261 return event_;
262 }
263
27af95d4 » steve
2004-02-18 Use perm_strings for named langiage items.
264 NetEvProbe::NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt,
8dbd6412 » steve
2000-04-10 All events now use the NetEvent class.
265 edge_t t, unsigned p)
27af95d4 » steve
2004-02-18 Use perm_strings for named langiage items.
266 : NetNode(s, n, p), event_(tgt), edge_(t)
8dbd6412 » steve
2000-04-10 All events now use the NetEvent class.
267 {
268 for (unsigned idx = 0 ; idx < p ; idx += 1) {
269 pin(idx).set_dir(Link::INPUT);
270 }
4493e968 » steve
2000-04-12 Finally remove the NetNEvent and NetPEvent classes,
271
272 enext_ = event_->probes_;
273 event_->probes_ = this;
8dbd6412 » steve
2000-04-10 All events now use the NetEvent class.
274 }
275
276 NetEvProbe::~NetEvProbe()
277 {
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
278 if (event_->probes_ == this) {
279 event_->probes_ = enext_;
280
281 } else {
282 NetEvProbe*cur = event_->probes_;
283 while (cur->enext_ != this) {
284 assert(cur->enext_);
285 cur = cur->enext_;
286 }
287
288 cur->enext_ = this->enext_;
289 }
8dbd6412 » steve
2000-04-10 All events now use the NetEvent class.
290 }
291
292 NetEvProbe::edge_t NetEvProbe::edge() const
293 {
294 return edge_;
295 }
296
fd09bc3e » steve
2000-05-27 Merge similar probes within a module.
297 NetEvent* NetEvProbe::event()
298 {
299 return event_;
300 }
301
8dbd6412 » steve
2000-04-10 All events now use the NetEvent class.
302 const NetEvent* NetEvProbe::event() const
303 {
304 return event_;
305 }
306
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
307 /*
308 * A similar NetEvProbe is one that is connected to all the same nexa
309 * that this probe is connected to, and also is the same edge
310 * type. Don't count myself as a similar probe.
311 */
312 void NetEvProbe::find_similar_probes(list<NetEvProbe*>&plist)
313 {
314 Nexus*nex = pin(0).nexus();
315
316 for (Link*lcur = nex->first_nlink(); lcur; lcur = lcur->next_nlink()) {
b292a5fc » steveicarus
2008-08-04 Create a branch object to be the argument to the access function.
317 NetPins*obj = lcur->get_obj();
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
318 if (obj->pin_count() != pin_count())
319 continue;
320
321 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(obj);
322 if (tmp == 0)
323 continue;
324
325 if (tmp == this)
326 continue;
327
328 if (edge() != tmp->edge())
329 continue;
330
331 bool ok_flag = true;
38cce38e » steveicarus
2009-12-11 Slightly improve performance of collapsing NetEvent objects
332 for (unsigned idx = 1 ; ok_flag && idx < pin_count() ; idx += 1)
333 if (! pin(idx).is_linked(tmp->pin(idx)))
58ec62c8 » steve
2002-07-24 Rewrite find_similar_event to support doing
334 ok_flag = false;
335
336 if (ok_flag == true)
337 plist .push_back(tmp);
338 }
339 }
340
b1fd927a » steve
2000-04-12 Named events really should be expressed with PEIdent
341 NetEvWait::NetEvWait(NetProc*pr)
342 : statement_(pr), nevents_(0), events_(0)
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
343 {
344 }
345
346 NetEvWait::~NetEvWait()
347 {
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
348 if (events_) {
349 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
350 NetEvent*tgt = events_[idx];
351 tgt->waitref_ -= 1;
c1c01688 » steve
2000-05-31 Globally merge redundant event objects.
352
353 struct NetEvent::wcell_*tmp = tgt->wlist_;
354 if (tmp->obj == this) {
355 tgt->wlist_ = tmp->next;
356 delete tmp;
357 } else {
358 assert(tmp->next);
359 while (tmp->next->obj != this) {
360 tmp = tmp->next;
361 assert(tmp->next);
362 }
363 tmp->next = tmp->next->next;
364 delete tmp;
365 }
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
366 }
367 delete[]events_;
368 }
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
369 delete statement_;
370 }
371
b1fd927a » steve
2000-04-12 Named events really should be expressed with PEIdent
372 void NetEvWait::add_event(NetEvent*tgt)
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
373 {
b1fd927a » steve
2000-04-12 Named events really should be expressed with PEIdent
374 assert(tgt);
375 if (nevents_ == 0) {
376 events_ = new NetEvent*[1];
377
378 } else {
379 NetEvent**tmp = new NetEvent*[nevents_+1];
380 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
381 tmp[idx] = events_[idx];
382 assert(tmp[idx] != tgt);
383 }
384 delete[]events_;
385 events_ = tmp;
386 }
387
388 events_[nevents_] = tgt;
389 nevents_ += 1;
726f7b8b » steve
2000-04-16 Synthesis of comparator in expressions.
390
391 // Remember to tell the NetEvent that there is someone
392 // pointing to it.
393 tgt->waitref_ += 1;
c1c01688 » steve
2000-05-31 Globally merge redundant event objects.
394
395 struct NetEvent::wcell_*tmp = new NetEvent::wcell_;
396 tmp->obj = this;
397 tmp->next = tgt->wlist_;
398 tgt->wlist_ = tmp;
399 }
400
401 void NetEvWait::replace_event(NetEvent*src, NetEvent*repl)
402 {
403 unsigned idx;
404 for (idx = 0 ; idx < nevents_ ; idx += 1) {
405 if (events_[idx] == src)
406 break;
407 }
408
409 assert(idx < nevents_);
410
411 /* First, remove me from the list held by the src NetEvent. */
412 assert(src->waitref_ > 0);
413 src->waitref_ -= 1;
414 struct NetEvent::wcell_*tmp = src->wlist_;
415 if (tmp->obj == this) {
416 src->wlist_ = tmp->next;
417 delete tmp;
418 } else {
419 assert(tmp->next);
420 while (tmp->next->obj != this) {
421 tmp = tmp->next;
422 assert(tmp->next);
423 }
424 tmp->next = tmp->next->next;
425 delete tmp;
426 }
427
428 events_[idx] = repl;
429
430 // Remember to tell the replacement NetEvent that there is
431 // someone pointing to it.
432 repl->waitref_ += 1;
433
434 tmp = new NetEvent::wcell_;
435 tmp->obj = this;
436 tmp->next = repl->wlist_;
437 repl->wlist_ = tmp;
438
b1fd927a » steve
2000-04-12 Named events really should be expressed with PEIdent
439 }
440
441 unsigned NetEvWait::nevents() const
442 {
443 return nevents_;
444 }
445
446 const NetEvent* NetEvWait::event(unsigned idx) const
447 {
448 assert(idx < nevents_);
449 return events_[idx];
30e82892 » steve
2000-04-04 Simulate named event trigger and waits.
450 }
451
4493e968 » steve
2000-04-12 Finally remove the NetNEvent and NetPEvent classes,
452 NetEvent* NetEvWait::event(unsigned idx)
453 {
454 assert(idx < nevents_);
455 return events_[idx];
456 }
457
458 NetProc* NetEvWait::statement()
459 {
460 return statement_;
461 }
Something went wrong with that request. Please try again.