Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 463 lines (382 sloc) 10.397 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
badad63 All NetObj objects have lex_string base names.
steve authored
20 # include "config.h"
21 # include "compiler.h"
30e8289 Simulate named event trigger and waits.
steve authored
22 # include "netlist.h"
23
4c67de5 Add the lex_strings string handler, and put
steve authored
24 /*
25 * NOTE: The name_ is perm-allocated by the caller.
26 */
536068b Memory and Event names use perm_string.
steve authored
27 NetEvent::NetEvent(perm_string n)
4c67de5 Add the lex_strings string handler, and put
steve authored
28 : name_(n)
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;
f1cc9d8 Support event names as expressions elements.
steve authored
35 exprref_ = 0;
c1c0168 Globally merge redundant event objects.
steve authored
36 wlist_ = 0;
30e8289 Simulate named event trigger and waits.
steve authored
37 }
38
39 NetEvent::~NetEvent()
40 {
726f7b8 Synthesis of comparator in expressions.
steve authored
41 assert(waitref_ == 0);
74c4303 Clean up unneeded NetEvent objects.
steve authored
42 if (scope_) scope_->rem_event(this);
43 while (probes_) {
44 NetEvProbe*tmp = probes_->enext_;
45 delete probes_;
ea53f2b Typo stepping ot next probe in delete.
steve authored
46 probes_ = tmp;
74c4303 Clean up unneeded NetEvent objects.
steve authored
47 }
4c67de5 Add the lex_strings string handler, and put
steve authored
48 /* name_ is lex_strings. */
30e8289 Simulate named event trigger and waits.
steve authored
49 }
50
536068b Memory and Event names use perm_string.
steve authored
51 perm_string NetEvent::name() const
30e8289 Simulate named event trigger and waits.
steve authored
52 {
53 return name_;
54 }
55
c7d97f4 Properly evaluate scope path expressions.
steve authored
56 NetScope* NetEvent::scope()
30e8289 Simulate named event trigger and waits.
steve authored
57 {
58 assert(scope_);
c7d97f4 Properly evaluate scope path expressions.
steve authored
59 return scope_;
30e8289 Simulate named event trigger and waits.
steve authored
60 }
61
a4e528f Add the ivl_event_t to ivl_target, and use that to generate
steve authored
62 const NetScope* NetEvent::scope() const
63 {
64 assert(scope_);
65 return scope_;
66 }
67
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
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
ad8565f Add const probe method to NetEvent.
steve authored
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
74c4303 Clean up unneeded NetEvent objects.
steve authored
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
726f7b8 Synthesis of comparator in expressions.
steve authored
112 unsigned NetEvent::nwait() const
113 {
114 return waitref_;
115 }
116
f1cc9d8 Support event names as expressions elements.
steve authored
117 unsigned NetEvent::nexpr() const
118 {
119 return exprref_;
120 }
121
bcbd5b2 Remove limits from the similar events search.
steve authored
122 /*
123 * A "similar" event is one that has an identical non-nil set of
124 * probes.
125 */
58ec62c Rewrite find_similar_event to support doing
steve authored
126 void NetEvent::find_similar_event(list<NetEvent*>&event_list)
fd09bc3 Merge similar probes within a module.
steve authored
127 {
128 if (probes_ == 0)
58ec62c Rewrite find_similar_event to support doing
steve authored
129 return;
bcbd5b2 Remove limits from the similar events search.
steve authored
130
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
131 set<NetEvent*> candidate_events;
fd09bc3 Merge similar probes within a module.
steve authored
132
58ec62c Rewrite find_similar_event to support doing
steve authored
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);
bcbd5b2 Remove limits from the similar events search.
steve authored
139
58ec62c Rewrite find_similar_event to support doing
steve authored
140 for (list<NetEvProbe*>::iterator idx = first_probes.begin()
141 ; idx != first_probes.end() ; idx ++) {
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
142
143 candidate_events.insert( (*idx)->event() );
58ec62c Rewrite find_similar_event to support doing
steve authored
144 }
fd09bc3 Merge similar probes within a module.
steve authored
145
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
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. */
58ec62c Rewrite find_similar_event to support doing
steve authored
154 unsigned probe_count = 1;
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
155 for (NetEvProbe*cur = probes_->enext_ ; cur; cur = cur->enext_) {
58ec62c Rewrite find_similar_event to support doing
steve authored
156 list<NetEvProbe*>similar_probes;
157 cur->find_similar_probes(similar_probes);
158
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
159 set<NetEvent*> candidate_tmp;
58ec62c Rewrite find_similar_event to support doing
steve authored
160 for (list<NetEvProbe*>::iterator idx = similar_probes.begin()
161 ; idx != similar_probes.end() ; idx ++) {
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
162
163 NetEvent*tmp = (*idx)->event();
164 if (candidate_events.find(tmp) != candidate_events.end())
165 candidate_tmp .insert(tmp);
58ec62c Rewrite find_similar_event to support doing
steve authored
166 }
fd09bc3 Merge similar probes within a module.
steve authored
167
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
168 // None of the candidate events match this probe? Give up!
169 if (candidate_tmp.empty())
170 return;
171
172 candidate_events = candidate_tmp;
58ec62c Rewrite find_similar_event to support doing
steve authored
173 probe_count += 1;
fd09bc3 Merge similar probes within a module.
steve authored
174 }
175
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
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()
181 ; idx != candidate_events.end() ; idx ++) {
bcbd5b2 Remove limits from the similar events search.
steve authored
182
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
183 NetEvent*tmp = *idx;
bcbd5b2 Remove limits from the similar events search.
steve authored
184
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
185 // This shouldn't be possible?
58ec62c Rewrite find_similar_event to support doing
steve authored
186 if (tmp == this)
bcbd5b2 Remove limits from the similar events search.
steve authored
187 continue;
188
18edf2f Rework of automatic task/function support.
Martin Whitaker authored
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
58ec62c Rewrite find_similar_event to support doing
steve authored
195 unsigned tcnt = 0;
196 for (NetEvProbe*cur = tmp->probes_ ; cur ; cur = cur->enext_)
197 tcnt += 1;
bcbd5b2 Remove limits from the similar events search.
steve authored
198
58ec62c Rewrite find_similar_event to support doing
steve authored
199 if (tcnt == probe_count)
200 event_list .push_back(tmp);
fd09bc3 Merge similar probes within a module.
steve authored
201 }
202
203 }
204
58ec62c Rewrite find_similar_event to support doing
steve authored
205
c1c0168 Globally merge redundant event objects.
steve authored
206 void NetEvent::replace_event(NetEvent*that)
207 {
208 while (wlist_) {
209 wlist_->obj->replace_event(this, that);
210 }
211 }
212
9b6b081 Add structure for asynchronous logic synthesis.
steve authored
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
e4ae832 Clean up spurious trailing white space.
steve authored
220
9b6b081 Add structure for asynchronous logic synthesis.
steve authored
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
30e8289 Simulate named event trigger and waits.
steve authored
236 NetEvTrig::NetEvTrig(NetEvent*ev)
237 : event_(ev)
238 {
726f7b8 Synthesis of comparator in expressions.
steve authored
239 enext_ = event_->trig_;
240 event_->trig_ = this;
30e8289 Simulate named event trigger and waits.
steve authored
241 }
242
243 NetEvTrig::~NetEvTrig()
244 {
726f7b8 Synthesis of comparator in expressions.
steve authored
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 }
30e8289 Simulate named event trigger and waits.
steve authored
257 }
258
259 const NetEvent* NetEvTrig::event() const
260 {
261 return event_;
262 }
263
27af95d Use perm_strings for named langiage items.
steve authored
264 NetEvProbe::NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt,
8dbd641 All events now use the NetEvent class.
steve authored
265 edge_t t, unsigned p)
27af95d Use perm_strings for named langiage items.
steve authored
266 : NetNode(s, n, p), event_(tgt), edge_(t)
8dbd641 All events now use the NetEvent class.
steve authored
267 {
268 for (unsigned idx = 0 ; idx < p ; idx += 1) {
269 pin(idx).set_dir(Link::INPUT);
270 }
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
271
272 enext_ = event_->probes_;
273 event_->probes_ = this;
8dbd641 All events now use the NetEvent class.
steve authored
274 }
275
276 NetEvProbe::~NetEvProbe()
277 {
726f7b8 Synthesis of comparator in expressions.
steve authored
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 }
8dbd641 All events now use the NetEvent class.
steve authored
290 }
291
292 NetEvProbe::edge_t NetEvProbe::edge() const
293 {
294 return edge_;
295 }
296
fd09bc3 Merge similar probes within a module.
steve authored
297 NetEvent* NetEvProbe::event()
298 {
299 return event_;
300 }
301
8dbd641 All events now use the NetEvent class.
steve authored
302 const NetEvent* NetEvProbe::event() const
303 {
304 return event_;
305 }
306
58ec62c Rewrite find_similar_event to support doing
steve authored
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()) {
b292a5f Stephen Williams Create a branch object to be the argument to the access function.
authored
317 NetPins*obj = lcur->get_obj();
58ec62c Rewrite find_similar_event to support doing
steve authored
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;
38cce38 Stephen Williams Slightly improve performance of collapsing NetEvent objects
authored
332 for (unsigned idx = 1 ; ok_flag && idx < pin_count() ; idx += 1)
333 if (! pin(idx).is_linked(tmp->pin(idx)))
58ec62c Rewrite find_similar_event to support doing
steve authored
334 ok_flag = false;
335
336 if (ok_flag == true)
337 plist .push_back(tmp);
338 }
339 }
340
b1fd927 Named events really should be expressed with PEIdent
steve authored
341 NetEvWait::NetEvWait(NetProc*pr)
342 : statement_(pr), nevents_(0), events_(0)
30e8289 Simulate named event trigger and waits.
steve authored
343 {
344 }
345
346 NetEvWait::~NetEvWait()
347 {
726f7b8 Synthesis of comparator in expressions.
steve authored
348 if (events_) {
349 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
350 NetEvent*tgt = events_[idx];
351 tgt->waitref_ -= 1;
c1c0168 Globally merge redundant event objects.
steve authored
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 }
726f7b8 Synthesis of comparator in expressions.
steve authored
366 }
367 delete[]events_;
368 }
30e8289 Simulate named event trigger and waits.
steve authored
369 delete statement_;
370 }
371
b1fd927 Named events really should be expressed with PEIdent
steve authored
372 void NetEvWait::add_event(NetEvent*tgt)
30e8289 Simulate named event trigger and waits.
steve authored
373 {
b1fd927 Named events really should be expressed with PEIdent
steve authored
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;
726f7b8 Synthesis of comparator in expressions.
steve authored
390
391 // Remember to tell the NetEvent that there is someone
392 // pointing to it.
393 tgt->waitref_ += 1;
c1c0168 Globally merge redundant event objects.
steve authored
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
b1fd927 Named events really should be expressed with PEIdent
steve authored
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];
30e8289 Simulate named event trigger and waits.
steve authored
450 }
451
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
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 }
462
Something went wrong with that request. Please try again.