Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / vcd / vcd_interface.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : VCD Version 2.00 */
6 /* Fichier : vcd_interface.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Gilles Augustins */
12 /* */
13 /****************************************************************************/
14
15 /****************************************************************************/
16 /* includes */
17 /****************************************************************************/
18
19 #include VCD_H
20 #include "vcd_parse.h"
21
22 /****************************************************************************/
23 /* globals */
24 /****************************************************************************/
25
26 /****************************************************************************/
27 /* externs */
28 /****************************************************************************/
29
30 int vcd_db_check ()
31 {
32 if (!vcd_db) {
33 fprintf (stderr, "[VCD ERR] no VCD database loaded\n");
34 return 0;
35 }
36 else return 1;
37 }
38
39 /****************************************************************************/
40
41 void vcd_list_sigs ()
42 {
43 int i;
44 chain_list *chain;
45 char *signame;
46
47 if (!vcd_db_check ()) return;
48
49 for (i = 0; i < vcd_db->SIG_IDX; i++) {
50 for(chain = vcd_db->SIG_TAB[i]; chain; chain = chain->NEXT){
51 signame = (char*)chain->DATA;
52 if (isvss (signame) || isglobalvss (signame)) continue;
53 if (isvdd (signame) || isglobalvdd (signame)) continue;
54 fprintf (stdout, " %s\n", signame);
55 }
56 }
57 }
58
59 /****************************************************************************/
60 /****************************************************************************/
61 /****************************************************************************/
62
63 void vcd_print_waveform (trans_list *waveform)
64 {
65 trans_list *trans;
66 chain_list *chain;
67
68 if (!vcd_db_check ()) return;
69
70 for(chain = vcd_db->SIG_TAB[waveform->INDEX]; chain; chain = chain->NEXT){
71 fprintf (stdout, "%s : ", (char*)chain->DATA);
72 }
73 for (trans = waveform; trans; trans = trans->NEXT)
74 fprintf (stdout, " (%d, '%s')", trans->TIME, trans->VAL);
75 fprintf (stdout, "\n");
76 }
77 /****************************************************************************/
78
79 trans_list *vcd_get_waveform (char *signal)
80 {
81 long index;
82 char buf[1024];
83
84 if (!vcd_db_check ()) return NULL;
85
86 sscanf(signal,"%[^[][%*d:%*d]",buf);
87
88 if ((index = gethtitem (vcd_db->SIG_HT, namealloc (buf))) == EMPTYHT) {
89 fprintf (stderr, "[VCD ERR] signal '%s' does not exist in VCD file\n", signal);
90 return NULL;
91 }
92
93 return vcd_db->SIG_ENTRY[index];
94 }
95
96 /****************************************************************************/
97
98 trans_list *vcd_get_first_event (trans_list *waveform)
99 {
100 return waveform;
101 }
102
103 /****************************************************************************/
104
105 trans_list *vcd_get_next_event (trans_list *event)
106 {
107 if (event->NEXT)
108 return event->NEXT;
109 else
110 return event;
111 }
112
113 /****************************************************************************/
114
115 trans_list *vcd_get_prev_event (trans_list *event)
116 {
117 if (event->PREV)
118 return event->PREV;
119 else
120 return event;
121 }
122
123 /****************************************************************************/
124
125 void vcd_print_event (trans_list *event)
126 {
127 fprintf (stdout, "\n (%d, '%s')\n", event->TIME, event->VAL);
128 }
129
130 /****************************************************************************/
131 /****************************************************************************/
132 /****************************************************************************/
133
134 chain_list *vcd_get_current_events ()
135 {
136
137 if (!vcd_db_check ()) return NULL;
138
139 return vcd_db->TIME_ENTRY[vcd_db->CUR_TIME_IDX];
140 }
141
142 /****************************************************************************/
143
144 long vcd_count_events (chain_list *events)
145 {
146 chain_list *ch;
147 int count = 0;
148
149 if (!vcd_db_check ()) return 0;
150
151 for (ch = events; ch; ch = ch->NEXT) count++;
152
153 return count;
154 }
155
156 /****************************************************************************/
157
158 void vcd_print_current_events (chain_list *events)
159 {
160 chain_list *ch;
161 trans_list *trans;
162 chain_list *chain;
163
164 if (!vcd_db_check ()) return;
165
166 fprintf (stdout, "%d : ", ((trans_list*)events->DATA)->TIME);
167 for (ch = events; ch; ch = ch->NEXT) {
168 trans = (trans_list*)ch->DATA;
169 for(chain = vcd_db->SIG_TAB[trans->INDEX]; chain; chain = chain->NEXT){
170 fprintf (stdout, " (%s, '%s')", (char*)chain->DATA, trans->VAL);
171 }
172 }
173 fprintf (stdout, "\n");
174 }
175
176 /****************************************************************************/
177 /****************************************************************************/
178 /****************************************************************************/
179
180 static void vcd_goto_init_state ()
181 {
182 if (vcd_db->CUR_STATE) freechain (vcd_db->CUR_STATE);
183 vcd_db->CUR_STATE = dupchainlst (vcd_db->TIME_ENTRY[0]);
184 }
185
186 /****************************************************************************/
187
188 static void vcd_goto_state (long time)
189 {
190 int i;
191 trans_list *trans;
192 chain_list *ch;
193
194 if (!vcd_db_check ()) return;
195
196 if (!vcd_db->CUR_STATE) { // search from time 0
197 for (i = 0; i < vcd_db->SIG_IDX; i++)
198 for (trans = vcd_db->SIG_ENTRY[i]; trans; trans = trans->NEXT)
199 if (!trans->NEXT || (trans->NEXT->TIME > time) || (trans->TIME == time)) {
200 vcd_db->CUR_STATE = addchain (vcd_db->CUR_STATE, trans);
201 break;
202 }
203 }
204 else if (time > vcd_db->TIME_TAB[vcd_db->CUR_TIME_IDX]) { // update current state forward
205 for (ch = vcd_db->CUR_STATE; ch; ch = ch->NEXT)
206 for (trans = (trans_list*)ch->DATA; trans; trans = trans->NEXT)
207 if (!trans->NEXT || (trans->NEXT->TIME > time) || (trans->TIME == time)) {
208 ch->DATA = trans;
209 break;
210 }
211 }
212 else if (time < vcd_db->TIME_TAB[vcd_db->CUR_TIME_IDX]) // update current state backward
213 for (ch = vcd_db->CUR_STATE; ch; ch = ch->NEXT)
214 for (trans = (trans_list*)ch->DATA; trans; trans = trans->PREV)
215 if (!trans->PREV || (trans->TIME <= time)) {
216 ch->DATA = trans;
217 break;
218 }
219 }
220
221 /****************************************************************************/
222
223 chain_list *vcd_get_state ()
224 {
225 if (!vcd_db_check ()) return NULL;
226
227 return vcd_db->CUR_STATE;
228 }
229
230 /****************************************************************************/
231
232 void vcd_print_state (chain_list *state)
233 {
234 chain_list *ch;
235 trans_list *trans;
236 chain_list *chain;
237
238 if (!vcd_db_check ()) return;
239
240 for (ch = state; ch; ch = ch->NEXT) {
241 trans = (trans_list*)ch->DATA;
242 for(chain = vcd_db->SIG_TAB[trans->INDEX]; chain; chain = chain->NEXT){
243 fprintf (stdout, "%s : '%s' (t = %d)\n", (char*)chain->DATA, trans->VAL, trans->TIME);
244 }
245 }
246 }
247
248 /****************************************************************************/
249 /****************************************************************************/
250 /****************************************************************************/
251
252 long vcd_get_time_from_index (long index)
253 {
254 if (!vcd_db_check ()) return 0;
255
256 return vcd_db->TIME_TAB[index];
257 }
258
259 /****************************************************************************/
260
261 float vcd_get_nrj_from_index (long index)
262 {
263 if (!vcd_db_check ()) return 0;
264
265 return vcd_db->NRJ_ENTRY[index];
266 }
267
268 /****************************************************************************/
269
270 long vcd_get_max_index ()
271 {
272 if (!vcd_db_check ()) return 0;
273
274 return vcd_db->TIME_IDX;
275 }
276
277 /****************************************************************************/
278
279 long vcd_get_time ()
280 {
281 if (!vcd_db_check ()) return 0;
282
283 return vcd_db->TIME_TAB[vcd_db->CUR_TIME_IDX];
284 }
285
286 /****************************************************************************/
287
288 void vcd_goto_time (long time)
289 {
290 int i;
291
292 if (!vcd_db_check ()) return;
293
294 vcd_goto_state (time);
295
296 for (i = 0; i < vcd_db->TIME_IDX; i++)
297 if (vcd_db->TIME_TAB[i] >= time) break;
298 vcd_db->CUR_TIME_IDX = i;
299 }
300
301 /****************************************************************************/
302
303 char vcd_goto_next_time ()
304 {
305 long time;
306
307 if (!vcd_db_check ()) return 0;
308
309 if (vcd_db->CUR_TIME_IDX < vcd_db->TIME_IDX) {
310 vcd_db->CUR_TIME_IDX++;
311 time = vcd_get_time ();
312 vcd_db->CUR_TIME_IDX--;
313 vcd_goto_state (time);
314 vcd_db->CUR_TIME_IDX++;
315 return 1;
316 }
317
318 return 0;
319 }
320
321 /****************************************************************************/
322
323 void vcd_goto_prev_time ()
324 {
325 long time;
326
327 if (!vcd_db_check ()) return;
328
329 if (vcd_db->CUR_TIME_IDX >= 0) {
330 vcd_db->CUR_TIME_IDX--;
331 time = vcd_get_time ();
332 vcd_db->CUR_TIME_IDX++;
333 vcd_goto_state (time);
334 vcd_db->CUR_TIME_IDX--;
335 }
336 }
337
338 /****************************************************************************/
339
340 void vcd_goto_init_time ()
341 {
342 if (!vcd_db_check ()) return;
343
344 vcd_db->CUR_TIME_IDX = 0;
345 vcd_goto_init_state ();
346 }
347
348 /****************************************************************************/
349
350 void vcd_goto_first_time ()
351 {
352 if (!vcd_db_check ()) return;
353
354 vcd_goto_init_state ();
355 vcd_db->CUR_TIME_IDX = 0;
356 vcd_goto_state (0);
357 vcd_db->CUR_TIME_IDX = 1;
358 }
359
360 /****************************************************************************/
361
362 void vcd_add_nrj (float nrj)
363 {
364 if (!vcd_db_check ()) return;
365
366 vcd_db->NRJ_ENTRY[vcd_db->CUR_TIME_IDX] = nrj;
367 }
368
369 /****************************************************************************/
370
371 void vcd_add_trans_nrj (trans_list *trans, float nrj)
372 {
373 if (!vcd_db_check ()) return;
374
375 trans->NRJ = nrj;
376 }
377