Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 452 lines (374 sloc) 9.964 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
58ec62c Rewrite find_similar_event to support doing
steve authored
131 map<NetEvent*,unsigned> event_matches;
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 ++) {
142 event_matches[ (*idx)->event() ] = 1;
143 }
fd09bc3 Merge similar probes within a module.
steve authored
144
58ec62c Rewrite find_similar_event to support doing
steve authored
145 /* Now scan the remaining probes, in each case ticking the
146 candidate event. The events that really are similar to this
147 one will turn up in every probe list. */
148 unsigned probe_count = 1;
149 for (NetEvProbe*cur = probes_->enext_ ; cur ; cur = cur->enext_) {
150 list<NetEvProbe*>similar_probes;
151 cur->find_similar_probes(similar_probes);
152
153 for (list<NetEvProbe*>::iterator idx = similar_probes.begin()
154 ; idx != similar_probes.end() ; idx ++) {
155 event_matches[ (*idx)->event() ] += 1;
156 }
fd09bc3 Merge similar probes within a module.
steve authored
157
58ec62c Rewrite find_similar_event to support doing
steve authored
158 probe_count += 1;
fd09bc3 Merge similar probes within a module.
steve authored
159 }
160
58ec62c Rewrite find_similar_event to support doing
steve authored
161 /* Now scan the candidate events. Those events that are
162 connected to all my probes (match_count[x] == probe_count)
163 are possible. If those events have the same number of
164 events, then jackpot. */
165 for (map<NetEvent*,unsigned>::iterator idx = event_matches.begin()
166 ; idx != event_matches.end() ; idx ++) {
bcbd5b2 Remove limits from the similar events search.
steve authored
167
58ec62c Rewrite find_similar_event to support doing
steve authored
168 NetEvent*tmp = (*idx).first;
bcbd5b2 Remove limits from the similar events search.
steve authored
169
58ec62c Rewrite find_similar_event to support doing
steve authored
170 if (tmp == this)
bcbd5b2 Remove limits from the similar events search.
steve authored
171 continue;
172
18edf2f Rework of automatic task/function support.
Martin Whitaker authored
173 /* For automatic tasks, the VVP runtime holds state for events
174 in the automatically allocated context. This means we can't
175 merge similar events in different automatic tasks. */
176 if (scope()->is_auto() && (tmp->scope() != scope()))
177 continue;
178
58ec62c Rewrite find_similar_event to support doing
steve authored
179 if ((*idx).second != probe_count)
54dab22 event find_similar should not find self.
steve authored
180 continue;
181
58ec62c Rewrite find_similar_event to support doing
steve authored
182 unsigned tcnt = 0;
183 for (NetEvProbe*cur = tmp->probes_ ; cur ; cur = cur->enext_)
184 tcnt += 1;
bcbd5b2 Remove limits from the similar events search.
steve authored
185
58ec62c Rewrite find_similar_event to support doing
steve authored
186 if (tcnt == probe_count)
187 event_list .push_back(tmp);
fd09bc3 Merge similar probes within a module.
steve authored
188 }
189
190 }
191
58ec62c Rewrite find_similar_event to support doing
steve authored
192
c1c0168 Globally merge redundant event objects.
steve authored
193 void NetEvent::replace_event(NetEvent*that)
194 {
195 while (wlist_) {
196 wlist_->obj->replace_event(this, that);
197 }
198 }
199
9b6b081 Add structure for asynchronous logic synthesis.
steve authored
200 NexusSet* NetEvent::nex_async_()
201 {
202 /* If there are behavioral trigger statements attached to me,
203 then this is not an asynchronous event. */
204 if (trig_ != 0)
205 return 0;
206
e4ae832 Clean up spurious trailing white space.
steve authored
207
9b6b081 Add structure for asynchronous logic synthesis.
steve authored
208 NexusSet*tmp = new NexusSet;
209 for (NetEvProbe*cur = probes_ ; cur != 0 ; cur = cur->enext_) {
210 if (cur->edge() != NetEvProbe::ANYEDGE) {
211 delete tmp;
212 return 0;
213 }
214
215 for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1)
216 tmp->add(cur->pin(idx).nexus());
217
218 }
219
220 return tmp;
221 }
222
30e8289 Simulate named event trigger and waits.
steve authored
223 NetEvTrig::NetEvTrig(NetEvent*ev)
224 : event_(ev)
225 {
726f7b8 Synthesis of comparator in expressions.
steve authored
226 enext_ = event_->trig_;
227 event_->trig_ = this;
30e8289 Simulate named event trigger and waits.
steve authored
228 }
229
230 NetEvTrig::~NetEvTrig()
231 {
726f7b8 Synthesis of comparator in expressions.
steve authored
232 if (event_->trig_ == this) {
233 event_->trig_ = enext_;
234
235 } else {
236 NetEvTrig*cur = event_->trig_;
237 while (cur->enext_ != this) {
238 assert(cur->enext_);
239 cur = cur->enext_;
240 }
241
242 cur->enext_ = this->enext_;
243 }
30e8289 Simulate named event trigger and waits.
steve authored
244 }
245
246 const NetEvent* NetEvTrig::event() const
247 {
248 return event_;
249 }
250
27af95d Use perm_strings for named langiage items.
steve authored
251 NetEvProbe::NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt,
8dbd641 All events now use the NetEvent class.
steve authored
252 edge_t t, unsigned p)
27af95d Use perm_strings for named langiage items.
steve authored
253 : NetNode(s, n, p), event_(tgt), edge_(t)
8dbd641 All events now use the NetEvent class.
steve authored
254 {
255 for (unsigned idx = 0 ; idx < p ; idx += 1) {
256 pin(idx).set_dir(Link::INPUT);
257 }
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
258
259 enext_ = event_->probes_;
260 event_->probes_ = this;
8dbd641 All events now use the NetEvent class.
steve authored
261 }
262
263 NetEvProbe::~NetEvProbe()
264 {
726f7b8 Synthesis of comparator in expressions.
steve authored
265 if (event_->probes_ == this) {
266 event_->probes_ = enext_;
267
268 } else {
269 NetEvProbe*cur = event_->probes_;
270 while (cur->enext_ != this) {
271 assert(cur->enext_);
272 cur = cur->enext_;
273 }
274
275 cur->enext_ = this->enext_;
276 }
8dbd641 All events now use the NetEvent class.
steve authored
277 }
278
279 NetEvProbe::edge_t NetEvProbe::edge() const
280 {
281 return edge_;
282 }
283
fd09bc3 Merge similar probes within a module.
steve authored
284 NetEvent* NetEvProbe::event()
285 {
286 return event_;
287 }
288
8dbd641 All events now use the NetEvent class.
steve authored
289 const NetEvent* NetEvProbe::event() const
290 {
291 return event_;
292 }
293
58ec62c Rewrite find_similar_event to support doing
steve authored
294 /*
295 * A similar NetEvProbe is one that is connected to all the same nexa
296 * that this probe is connected to, and also is the same edge
297 * type. Don't count myself as a similar probe.
298 */
299 void NetEvProbe::find_similar_probes(list<NetEvProbe*>&plist)
300 {
301 Nexus*nex = pin(0).nexus();
302
303 for (Link*lcur = nex->first_nlink(); lcur; lcur = lcur->next_nlink()) {
b292a5f @steveicarus Create a branch object to be the argument to the access function.
authored
304 NetPins*obj = lcur->get_obj();
58ec62c Rewrite find_similar_event to support doing
steve authored
305 if (obj->pin_count() != pin_count())
306 continue;
307
308 NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(obj);
309 if (tmp == 0)
310 continue;
311
312 if (tmp == this)
313 continue;
314
315 if (edge() != tmp->edge())
316 continue;
317
318 bool ok_flag = true;
319 for (unsigned idx = 1 ; idx < pin_count() ; idx += 1)
320 if (pin(idx).nexus() != tmp->pin(idx).nexus()) {
321 ok_flag = false;
322 break;
323 }
324
325 if (ok_flag == true)
326 plist .push_back(tmp);
327 }
328 }
329
b1fd927 Named events really should be expressed with PEIdent
steve authored
330 NetEvWait::NetEvWait(NetProc*pr)
331 : statement_(pr), nevents_(0), events_(0)
30e8289 Simulate named event trigger and waits.
steve authored
332 {
333 }
334
335 NetEvWait::~NetEvWait()
336 {
726f7b8 Synthesis of comparator in expressions.
steve authored
337 if (events_) {
338 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
339 NetEvent*tgt = events_[idx];
340 tgt->waitref_ -= 1;
c1c0168 Globally merge redundant event objects.
steve authored
341
342 struct NetEvent::wcell_*tmp = tgt->wlist_;
343 if (tmp->obj == this) {
344 tgt->wlist_ = tmp->next;
345 delete tmp;
346 } else {
347 assert(tmp->next);
348 while (tmp->next->obj != this) {
349 tmp = tmp->next;
350 assert(tmp->next);
351 }
352 tmp->next = tmp->next->next;
353 delete tmp;
354 }
726f7b8 Synthesis of comparator in expressions.
steve authored
355 }
356 delete[]events_;
357 }
30e8289 Simulate named event trigger and waits.
steve authored
358 delete statement_;
359 }
360
b1fd927 Named events really should be expressed with PEIdent
steve authored
361 void NetEvWait::add_event(NetEvent*tgt)
30e8289 Simulate named event trigger and waits.
steve authored
362 {
b1fd927 Named events really should be expressed with PEIdent
steve authored
363 assert(tgt);
364 if (nevents_ == 0) {
365 events_ = new NetEvent*[1];
366
367 } else {
368 NetEvent**tmp = new NetEvent*[nevents_+1];
369 for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
370 tmp[idx] = events_[idx];
371 assert(tmp[idx] != tgt);
372 }
373 delete[]events_;
374 events_ = tmp;
375 }
376
377 events_[nevents_] = tgt;
378 nevents_ += 1;
726f7b8 Synthesis of comparator in expressions.
steve authored
379
380 // Remember to tell the NetEvent that there is someone
381 // pointing to it.
382 tgt->waitref_ += 1;
c1c0168 Globally merge redundant event objects.
steve authored
383
384 struct NetEvent::wcell_*tmp = new NetEvent::wcell_;
385 tmp->obj = this;
386 tmp->next = tgt->wlist_;
387 tgt->wlist_ = tmp;
388 }
389
390 void NetEvWait::replace_event(NetEvent*src, NetEvent*repl)
391 {
392 unsigned idx;
393 for (idx = 0 ; idx < nevents_ ; idx += 1) {
394 if (events_[idx] == src)
395 break;
396 }
397
398 assert(idx < nevents_);
399
400 /* First, remove me from the list held by the src NetEvent. */
401 assert(src->waitref_ > 0);
402 src->waitref_ -= 1;
403 struct NetEvent::wcell_*tmp = src->wlist_;
404 if (tmp->obj == this) {
405 src->wlist_ = tmp->next;
406 delete tmp;
407 } else {
408 assert(tmp->next);
409 while (tmp->next->obj != this) {
410 tmp = tmp->next;
411 assert(tmp->next);
412 }
413 tmp->next = tmp->next->next;
414 delete tmp;
415 }
416
417 events_[idx] = repl;
418
419 // Remember to tell the replacement NetEvent that there is
420 // someone pointing to it.
421 repl->waitref_ += 1;
422
423 tmp = new NetEvent::wcell_;
424 tmp->obj = this;
425 tmp->next = repl->wlist_;
426 repl->wlist_ = tmp;
427
b1fd927 Named events really should be expressed with PEIdent
steve authored
428 }
429
430 unsigned NetEvWait::nevents() const
431 {
432 return nevents_;
433 }
434
435 const NetEvent* NetEvWait::event(unsigned idx) const
436 {
437 assert(idx < nevents_);
438 return events_[idx];
30e8289 Simulate named event trigger and waits.
steve authored
439 }
440
4493e96 Finally remove the NetNEvent and NetPEvent classes,
steve authored
441 NetEvent* NetEvWait::event(unsigned idx)
442 {
443 assert(idx < nevents_);
444 return events_[idx];
445 }
446
447 NetProc* NetEvWait::statement()
448 {
449 return statement_;
450 }
451
Something went wrong with that request. Please try again.