1 /*
2 * Copyright (c) Tony Bybell 1999-2017.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 */
9
10
11 /*
12 * vcd.c 23jan99ajb
13 * evcd parts 29jun99ajb
14 * profiler optimizations 15jul99ajb
15 * more profiler optimizations 25jan00ajb
16 * finsim parameter fix 26jan00ajb
17 * vector rechaining code 03apr00ajb
18 * multiple var section code 06apr00ajb
19 * fix for duplicate nets 19dec00ajb
20 * support for alt hier seps 23dec00ajb
21 * fix for rcs identifiers 16jan01ajb
22 * coredump fix for bad VCD 04apr02ajb
23 * min/maxid speedup 27feb03ajb
24 * bugfix on min/maxid speedup 06jul03ajb
25 * escaped hier modification 20feb06ajb
26 * added real_parameter vartype 04aug06ajb
27 * recoder using vlists 17aug06ajb
28 * code cleanup 04sep06ajb
29 * added in/out port vartype 31jan07ajb
30 * use gperf for port vartypes 19feb07ajb
31 * MTI SV implicit-var fix 05apr07ajb
32 * MTI SV len=0 is real var 05apr07ajb
33 * VCD fastloading 05mar09ajb
34 * Backtracking fix 16oct18ajb
35 */
36 #include <config.h>
37 #include "globals.h"
38 #include "vcd.h"
39 #include "vlist.h"
40 #include "lx2.h"
41 #include "hierpack.h"
42
43 /**/
44
malform_eof_fix(void)45 static void malform_eof_fix(void)
46 {
47 if(feof(GLOBALS->vcd_handle_vcd_recoder_c_2))
48 {
49 memset(GLOBALS->vcdbuf_vcd_recoder_c_3, ' ', VCD_BSIZ);
50 GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vend_vcd_recoder_c_3;
51 }
52 }
53
54 /**/
55
vlist_packer_emit_uv64(struct vlist_packer_t ** vl,guint64 v)56 static void vlist_packer_emit_uv64(struct vlist_packer_t **vl, guint64 v)
57 {
58 guint64 nxt;
59
60 while((nxt = v>>7))
61 {
62 vlist_packer_alloc(*vl, v&0x7f);
63 v = nxt;
64 }
65
66 vlist_packer_alloc(*vl, (v&0x7f) | 0x80);
67 }
68
69
vlist_packer_emit_utt(struct vlist_packer_t ** vl,UTimeType v)70 static void vlist_packer_emit_utt(struct vlist_packer_t **vl, UTimeType v)
71 {
72 UTimeType nxt;
73
74 while((nxt = v>>7))
75 {
76 vlist_packer_alloc(*vl, v&0x7f);
77 v = nxt;
78 }
79
80 vlist_packer_alloc(*vl, (v&0x7f) | 0x80);
81 }
82
83
vlist_packer_emit_uv32(struct vlist_packer_t ** vl,unsigned int v)84 static void vlist_packer_emit_uv32(struct vlist_packer_t **vl, unsigned int v)
85 {
86 unsigned int nxt;
87
88 while((nxt = v>>7))
89 {
90 vlist_packer_alloc(*vl, v&0x7f);
91 v = nxt;
92 }
93
94 vlist_packer_alloc(*vl, (v&0x7f) | 0x80);
95 }
96
97
vlist_packer_emit_string(struct vlist_packer_t ** vl,char * s)98 static void vlist_packer_emit_string(struct vlist_packer_t **vl, char *s)
99 {
100 while(*s)
101 {
102 vlist_packer_alloc(*vl, *s);
103 s++;
104 }
105 vlist_packer_alloc(*vl, 0);
106 }
107
vlist_packer_emit_mvl9_string(struct vlist_packer_t ** vl,char * s)108 static void vlist_packer_emit_mvl9_string(struct vlist_packer_t **vl, char *s)
109 {
110 unsigned int recoded_bit;
111 unsigned char which = 0;
112 unsigned char accum = 0;
113
114 while(*s)
115 {
116 switch(*s)
117 {
118 case '0': recoded_bit = AN_0; break;
119 case '1': recoded_bit = AN_1; break;
120 case 'x': case 'X': recoded_bit = AN_X; break;
121 case 'z': case 'Z': recoded_bit = AN_Z; break;
122 case 'h': case 'H': recoded_bit = AN_H; break;
123 case 'u': case 'U': recoded_bit = AN_U; break;
124 case 'w': case 'W': recoded_bit = AN_W; break;
125 case 'l': case 'L': recoded_bit = AN_L; break;
126 default: recoded_bit = AN_DASH; break;
127 }
128
129 if(!which)
130 {
131 accum = (recoded_bit << 4);
132 which = 1;
133 }
134 else
135 {
136 accum |= recoded_bit;
137 vlist_packer_alloc(*vl, accum);
138 which = accum = 0;
139 }
140 s++;
141 }
142
143 recoded_bit = AN_MSK; /* XXX : this is assumed it is going to remain a 4 bit max quantity! */
144 if(!which)
145 {
146 accum = (recoded_bit << 4);
147 }
148 else
149 {
150 accum |= recoded_bit;
151 }
152
153 vlist_packer_alloc(*vl, accum);
154 }
155
156 /**/
157
vlist_emit_uv32(struct vlist_t ** vl,unsigned int v)158 static void vlist_emit_uv32(struct vlist_t **vl, unsigned int v)
159 {
160 unsigned int nxt;
161 char *pnt;
162
163 if(GLOBALS->vlist_prepack) { vlist_packer_emit_uv32((struct vlist_packer_t **)vl, v); return; }
164
165 while((nxt = v>>7))
166 {
167 pnt = vlist_alloc(vl, 1);
168 *pnt = (v&0x7f);
169 v = nxt;
170 }
171
172 pnt = vlist_alloc(vl, 1);
173 *pnt = (v&0x7f) | 0x80;
174 }
175
176
vlist_emit_string(struct vlist_t ** vl,char * s)177 static void vlist_emit_string(struct vlist_t **vl, char *s)
178 {
179 char *pnt;
180
181 if(GLOBALS->vlist_prepack) { vlist_packer_emit_string((struct vlist_packer_t **)vl, s); return; }
182
183 while(*s)
184 {
185 pnt = vlist_alloc(vl, 1);
186 *pnt = *s;
187 s++;
188 }
189 pnt = vlist_alloc(vl, 1);
190 *pnt = 0;
191 }
192
vlist_emit_mvl9_string(struct vlist_t ** vl,char * s)193 static void vlist_emit_mvl9_string(struct vlist_t **vl, char *s)
194 {
195 char *pnt;
196 unsigned int recoded_bit;
197 unsigned char which;
198 unsigned char accum;
199
200 if(GLOBALS->vlist_prepack) { vlist_packer_emit_mvl9_string((struct vlist_packer_t **)vl, s); return; }
201
202 which = accum = 0;
203
204 while(*s)
205 {
206 switch(*s)
207 {
208 case '0': recoded_bit = AN_0; break;
209 case '1': recoded_bit = AN_1; break;
210 case 'x': case 'X': recoded_bit = AN_X; break;
211 case 'z': case 'Z': recoded_bit = AN_Z; break;
212 case 'h': case 'H': recoded_bit = AN_H; break;
213 case 'u': case 'U': recoded_bit = AN_U; break;
214 case 'w': case 'W': recoded_bit = AN_W; break;
215 case 'l': case 'L': recoded_bit = AN_L; break;
216 default: recoded_bit = AN_DASH; break;
217 }
218
219 if(!which)
220 {
221 accum = (recoded_bit << 4);
222 which = 1;
223 }
224 else
225 {
226 accum |= recoded_bit;
227 pnt = vlist_alloc(vl, 1);
228 *pnt = accum;
229 which = accum = 0;
230 }
231 s++;
232 }
233
234 recoded_bit = AN_MSK; /* XXX : this is assumed it is going to remain a 4 bit max quantity! */
235 if(!which)
236 {
237 accum = (recoded_bit << 4);
238 }
239 else
240 {
241 accum |= recoded_bit;
242 }
243
244 pnt = vlist_alloc(vl, 1);
245 *pnt = accum;
246 }
247
248 /**/
249
write_fastload_time_section(void)250 static void write_fastload_time_section(void)
251 {
252 struct vlist_t *vlist;
253 struct vlist_packer_t *vlist_p;
254
255 /* emit blackout regions */
256 if(GLOBALS->blackout_regions)
257 {
258 struct blackout_region_t *bt = GLOBALS->blackout_regions;
259 unsigned int bcnt = 0;
260 while(bt)
261 {
262 bcnt++;
263 bt = bt->next;
264 }
265
266 vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bcnt);
267
268 bt = GLOBALS->blackout_regions;
269 while(bt)
270 {
271 vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bt->bstart);
272 vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bt->bend);
273 bt = bt->next;
274 }
275 }
276 else
277 {
278 vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, 0);
279 }
280
281 vlist_p = (struct vlist_packer_t *)GLOBALS->time_vlist_vcd_recoder_write;
282 vlist_packer_finalize(vlist_p);
283 vlist = vlist_p->v;
284 free_2(vlist_p);
285 GLOBALS->time_vlist_vcd_recoder_write = vlist;
286 vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_write);
287 }
288
289 #ifdef HAVE_SYS_STAT_H
write_fastload_header(struct stat * mystat,unsigned int finalize_cnt)290 static void write_fastload_header(struct stat *mystat, unsigned int finalize_cnt)
291 #else
292 static void write_fastload_header(unsigned int finalize_cnt)
293 #endif
294 {
295 /*
296 write out the trailer information for vcd fastload...
297
298 vcd file size
299 vcd last modification time
300 number of finalize values
301 number of variable-length integer values in the time table (GLOBALS->time_vlist_count_vcd_recoder_c_1)
302 GLOBALS->time_vlist_vcd_recoder_write value
303 deltas from GLOBALS->time_vlist_vcd_recoder_write and on though stepping through list generated by vlist_emit_finalize()
304 */
305
306 struct vlist_packer_t *vlist_p = vlist_packer_create();
307 struct vlist_t *vlist_summary_index;
308
309 struct vcdsymbol *v = GLOBALS->vcdsymroot_vcd_recoder_c_3;
310 guint64 val = (guint64)(uintptr_t)GLOBALS->time_vlist_vcd_recoder_write;
311 guint64 nval;
312 char buf[33];
313 char *pnt;
314
315 memset(buf, 0, sizeof(buf)); /* scan-build */
316
317 #ifdef HAVE_SYS_STAT_H
318 vlist_packer_emit_uv64(&vlist_p, (guint64)mystat->st_size);
319 vlist_packer_emit_uv64(&vlist_p, (guint64)mystat->st_mtime);
320 #else
321 vlist_packer_emit_uv64(&vlist_p, (guint64)0);
322 vlist_packer_emit_uv64(&vlist_p, (guint64)0);
323 #endif
324
325 vlist_packer_emit_uv32(&vlist_p, finalize_cnt);
326 vlist_packer_emit_uv64(&vlist_p, GLOBALS->time_vlist_count_vcd_recoder_c_1);
327
328 vlist_packer_emit_uv64(&vlist_p, val);
329 val = 0;
330 while(v)
331 {
332 nptr n = v->narray[0];
333 nval = (guint64)(uintptr_t)n->mv.mvlfac_vlist;
334
335 vlist_packer_emit_uv64(&vlist_p, nval - val);
336 val = nval;
337
338 v = v->next;
339 }
340
341 vlist_packer_finalize(vlist_p);
342 vlist_summary_index = vlist_p->v;
343 free_2(vlist_p);
344 GLOBALS->time_vlist_vcd_recoder_write = vlist_summary_index;
345 vlist_freeze(&vlist_summary_index);
346
347 pnt = buf;
348 val = (guint64)(uintptr_t)vlist_summary_index;
349 while((nval = val>>7))
350 {
351 *(pnt++) = (val&0x7f);
352 val = nval;
353 }
354 *(pnt++) = ((val&0x7f) | 0x80);
355 do
356 {
357 pnt--;
358 fputc((unsigned char)*pnt, GLOBALS->vlist_handle);
359 } while(pnt != buf);
360
361 fflush(GLOBALS->vlist_handle);
362 }
363
364
read_fastload_body(void)365 static int read_fastload_body(void)
366 {
367 char *depacked = GLOBALS->fastload_depacked;
368 char *pnt = GLOBALS->fastload_current;
369 int rc = 0;
370 guint64 v = 0, vprev = 0;
371 int shamt = 0;
372 /* unsigned int num_finalize; */ /* scan-build */
373 unsigned int num_in_time_table, num_blackout_regions;
374 guint64 time_vlist_vcd_recoder_write;
375 struct vcdsymbol *vs;
376 struct vlist_t *vl;
377 unsigned int list_size;
378 unsigned int i;
379 struct blackout_region_t *bt_head = NULL, *bt_curr = NULL;
380
381 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
382 /* num_finalize = v; */ /* scan-build */
383
384 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
385 GLOBALS->time_vlist_count_vcd_recoder_c_1 = num_in_time_table = v;
386
387 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
388 time_vlist_vcd_recoder_write = v;
389
390 vs=GLOBALS->vcdsymroot_vcd_recoder_c_3;
391 while(vs)
392 {
393 nptr n = vs->narray[0];
394
395 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
396 v += vprev;
397 vprev = v;
398
399 n->mv.mvlfac_vlist = (struct vlist_t *)(intptr_t)(v);
400 vs = vs->next;
401 }
402
403 vlist_packer_decompress_destroy((char *)depacked);
404 GLOBALS->fastload_depacked = NULL;
405 GLOBALS->fastload_current = NULL;
406
407 /* now create the time table */
408 vl = (struct vlist_t *)(intptr_t)time_vlist_vcd_recoder_write;
409 vlist_uncompress(&vl);
410 depacked = pnt = (char *)vlist_packer_decompress(vl, &list_size);
411 vlist_destroy(vl);
412
413 vprev = 0;
414 for(i=0;i<num_in_time_table;i++)
415 {
416 TimeType tim;
417 TimeType *tt;
418
419 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
420
421 v += vprev;
422 vprev = v;
423
424 tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0);
425 *tt = tim = (TimeType)v;
426
427 if(!i)
428 {
429 GLOBALS->start_time_vcd_recoder_c_3=tim;
430 }
431
432 GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=tim;
433 }
434
435 /* now process blackout regions */
436 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
437 num_blackout_regions = v;
438
439 if(num_blackout_regions)
440 {
441 for(i=0;i<num_blackout_regions;i++)
442 {
443 struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t));
444 TimeType tim;
445
446 if(!bt_head)
447 {
448 bt_head = bt_curr = bt;
449 }
450 else
451 {
452 bt_curr->next = bt;
453 bt_curr = bt;
454 }
455
456 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
457 tim = v;
458 bt->bstart = tim;
459
460 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
461 tim = v;
462 bt->bend = tim;
463 }
464
465 GLOBALS->blackout_regions = bt_head;
466 }
467
468 vlist_packer_decompress_destroy((char *)depacked);
469
470 return(rc);
471 }
472
473 #ifdef HAVE_SYS_STAT_H
read_fastload_header(struct stat * st)474 static int read_fastload_header(struct stat *st)
475 #else
476 static int read_fastload_header(void)
477 #endif
478 {
479 int rc = 0;
480 int fs_rc = fseeko(GLOBALS->vlist_handle, 0, SEEK_END);
481 off_t ftlen = ftello(GLOBALS->vlist_handle);
482 guint64 v = 0;
483 int ch;
484 int shamt = 0;
485 unsigned char *depacked = NULL;
486 struct vlist_t *vl;
487 unsigned int list_size;
488 unsigned char *pnt;
489 #ifdef HAVE_SYS_STAT_H
490 struct stat mystat;
491 int stat_rc = stat(GLOBALS->loaded_file_name, &mystat);
492 #endif
493
494 if((fs_rc<0)||(!ftlen))
495 {
496 goto bail;
497 }
498
499 do {
500 ftlen--;
501 fseeko(GLOBALS->vlist_handle, ftlen, SEEK_SET);
502 ch = fgetc(GLOBALS->vlist_handle);
503 if(ch == EOF) { errno = 0; goto bail; }
504 v |= ((guint64)(ch & 0x7f)) << shamt;
505 shamt += 7;
506 } while(!(ch & 0x80));
507
508 vl = (struct vlist_t *)(intptr_t)v;
509 vlist_uncompress(&vl);
510 depacked = vlist_packer_decompress(vl, &list_size);
511 vlist_destroy(vl);
512
513 pnt = depacked;
514 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
515
516 #ifdef HAVE_SYS_STAT_H
517 if((stat_rc)||(v != (guint64)mystat.st_size))
518 {
519 goto bail;
520 }
521 #endif
522
523 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
524
525 #ifdef HAVE_SYS_STAT_H
526 if(v != (guint64)st->st_mtime)
527 {
528 goto bail;
529 }
530 #endif
531
532 rc = 1;
533 GLOBALS->fastload_depacked = (char *)depacked;
534 GLOBALS->fastload_current = (char *)pnt;
535
536 bail:
537 if(!rc) vlist_packer_decompress_destroy((char *)depacked);
538 return(rc);
539 }
540
541 /**/
542
543 #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */
544
545 static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector);
546 static void vcd_build_symbols(void);
547 static void vcd_cleanup(void);
548 static void evcd_strcpy(char *dst, char *src);
549
550 /******************************************************************/
551
552 enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE,
553 T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON,
554 T_DUMPVARS, T_ENDDEFINITIONS,
555 T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL,
556 T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO,
557 T_EOF, T_STRING, T_UNKNOWN_KEY };
558
559 static char *tokens[]={ "var", "end", "scope", "upscope",
560 "comment", "date", "dumpall", "dumpoff", "dumpon",
561 "dumpvars", "enddefinitions",
562 "dumpports", "dumpportsoff", "dumpportson", "dumpportsall",
563 "timescale", "version", "vcdclose", "timezero",
564 "", "", "" };
565
566 #define NUM_TOKENS 19
567
568
569 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break;
570
571 /******************************************************************/
572
vcdid_hash(char * s,int len)573 static unsigned int vcdid_hash(char *s, int len)
574 {
575 unsigned int val=0;
576 int i;
577
578 s+=(len-1);
579
580 for(i=0;i<len;i++)
581 {
582 val *= 94;
583 val += (((unsigned char)*s) - 32);
584 s--;
585 }
586
587 return(val);
588 }
589
590 /******************************************************************/
591
592 /*
593 * bsearch compare
594 */
vcdsymbsearchcompare(const void * s1,const void * s2)595 static int vcdsymbsearchcompare(const void *s1, const void *s2)
596 {
597 char *v1;
598 struct vcdsymbol *v2;
599
600 v1=(char *)s1;
601 v2=*((struct vcdsymbol **)s2);
602
603 return(strcmp(v1, v2->id));
604 }
605
606
607 /*
608 * actual bsearch
609 */
bsearch_vcd(char * key,int len)610 static struct vcdsymbol *bsearch_vcd(char *key, int len)
611 {
612 struct vcdsymbol **v;
613 struct vcdsymbol *t;
614
615 if(GLOBALS->indexed_vcd_recoder_c_3)
616 {
617 unsigned int hsh = vcdid_hash(key, len);
618 if((hsh>=GLOBALS->vcd_minid_vcd_recoder_c_3)&&(hsh<=GLOBALS->vcd_maxid_vcd_recoder_c_3))
619 {
620 return(GLOBALS->indexed_vcd_recoder_c_3[hsh-GLOBALS->vcd_minid_vcd_recoder_c_3]);
621 }
622
623 return(NULL);
624 }
625
626 if(GLOBALS->sorted_vcd_recoder_c_3)
627 {
628 v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_recoder_c_3, GLOBALS->numsyms_vcd_recoder_c_3,
629 sizeof(struct vcdsymbol *), vcdsymbsearchcompare);
630
631 if(v)
632 {
633 #ifndef VCD_BSEARCH_IS_PERFECT
634 for(;;)
635 {
636 t=*v;
637
638 if((v==GLOBALS->sorted_vcd_recoder_c_3)||(strcmp((*(--v))->id, key)))
639 {
640 return(t);
641 }
642 }
643 #else
644 return(*v);
645 #endif
646 }
647 else
648 {
649 return(NULL);
650 }
651 }
652 else
653 {
654 if(!GLOBALS->err_vcd_recoder_c_3)
655 {
656 fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
657 GLOBALS->err_vcd_recoder_c_3=1;
658 }
659 return(NULL);
660 }
661 }
662
663
664 /*
665 * sort on vcdsymbol pointers
666 */
vcdsymcompare(const void * s1,const void * s2)667 static int vcdsymcompare(const void *s1, const void *s2)
668 {
669 struct vcdsymbol *v1, *v2;
670
671 v1=*((struct vcdsymbol **)s1);
672 v2=*((struct vcdsymbol **)s2);
673
674 return(strcmp(v1->id, v2->id));
675 }
676
677
678 /*
679 * create sorted (by id) table
680 */
create_sorted_table(void)681 static void create_sorted_table(void)
682 {
683 struct vcdsymbol *v;
684 struct vcdsymbol **pnt;
685 unsigned int vcd_distance;
686
687 if(GLOBALS->sorted_vcd_recoder_c_3)
688 {
689 free_2(GLOBALS->sorted_vcd_recoder_c_3); /* this means we saw a 2nd enddefinition chunk! */
690 GLOBALS->sorted_vcd_recoder_c_3=NULL;
691 }
692
693 if(GLOBALS->indexed_vcd_recoder_c_3)
694 {
695 free_2(GLOBALS->indexed_vcd_recoder_c_3);
696 GLOBALS->indexed_vcd_recoder_c_3=NULL;
697 }
698
699 if(GLOBALS->numsyms_vcd_recoder_c_3)
700 {
701 vcd_distance = GLOBALS->vcd_maxid_vcd_recoder_c_3 - GLOBALS->vcd_minid_vcd_recoder_c_3 + 1;
702
703 if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill))
704 {
705 GLOBALS->indexed_vcd_recoder_c_3 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *));
706
707 /* printf("%d symbols span ID range of %d, using indexing... hash_kill = %d\n", GLOBALS->numsyms_vcd_recoder_c_3, vcd_distance, GLOBALS->vcd_hash_kill); */
708
709 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
710 while(v)
711 {
712 if(!GLOBALS->indexed_vcd_recoder_c_3[v->nid - GLOBALS->vcd_minid_vcd_recoder_c_3]) GLOBALS->indexed_vcd_recoder_c_3[v->nid - GLOBALS->vcd_minid_vcd_recoder_c_3] = v;
713 v=v->next;
714 }
715 }
716 else
717 {
718 pnt=GLOBALS->sorted_vcd_recoder_c_3=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *));
719 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
720 while(v)
721 {
722 *(pnt++)=v;
723 v=v->next;
724 }
725
726 qsort(GLOBALS->sorted_vcd_recoder_c_3, GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *), vcdsymcompare);
727 }
728 }
729 }
730
731 /******************************************************************/
732
vlist_emit_finalize(void)733 static unsigned int vlist_emit_finalize(void)
734 {
735 struct vcdsymbol *v /* , *vprime */; /* scan-build */
736 struct vlist_t *vlist;
737 char vlist_prepack = GLOBALS->vlist_prepack;
738 int cnt = 0;
739
740 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
741 while(v)
742 {
743 nptr n = v->narray[0];
744
745 set_vcd_vartype(v, n);
746
747 if(n->mv.mvlfac_vlist)
748 {
749 if(vlist_prepack)
750 {
751 vlist_packer_finalize(n->mv.mvlfac_packer_vlist);
752 vlist = n->mv.mvlfac_packer_vlist->v;
753 free_2(n->mv.mvlfac_packer_vlist);
754 n->mv.mvlfac_vlist = vlist;
755 vlist_freeze(&n->mv.mvlfac_vlist);
756 }
757 else
758 {
759 vlist_freeze(&n->mv.mvlfac_vlist);
760 }
761 }
762 else
763 {
764 n->mv.mvlfac_vlist = vlist_prepack ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char));
765
766 if((/* vprime= */ bsearch_vcd(v->id, strlen(v->id)))==v) /* hash mish means dup net */ /* scan-build */
767 {
768 switch(v->vartype)
769 {
770 case V_REAL:
771 vlist_emit_uv32(&n->mv.mvlfac_vlist, 'R');
772 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
773 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
774 vlist_emit_uv32(&n->mv.mvlfac_vlist, 0);
775 vlist_emit_string(&n->mv.mvlfac_vlist, "NaN");
776 break;
777
778 case V_STRINGTYPE:
779 vlist_emit_uv32(&n->mv.mvlfac_vlist, 'S');
780 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
781 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
782 vlist_emit_uv32(&n->mv.mvlfac_vlist, 0);
783 vlist_emit_string(&n->mv.mvlfac_vlist, "UNDEF");
784 break;
785
786 default:
787 if(v->size==1)
788 {
789 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)'0');
790 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
791 vlist_emit_uv32(&n->mv.mvlfac_vlist, RCV_X);
792 }
793 else
794 {
795 vlist_emit_uv32(&n->mv.mvlfac_vlist, 'B');
796 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
797 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
798 vlist_emit_uv32(&n->mv.mvlfac_vlist, 0);
799 vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, "x");
800 }
801 break;
802 }
803 }
804
805 if(vlist_prepack)
806 {
807 vlist_packer_finalize(n->mv.mvlfac_packer_vlist);
808 vlist = n->mv.mvlfac_packer_vlist->v;
809 free_2(n->mv.mvlfac_packer_vlist);
810 n->mv.mvlfac_vlist = vlist;
811 vlist_freeze(&n->mv.mvlfac_vlist);
812 }
813 else
814 {
815 vlist_freeze(&n->mv.mvlfac_vlist);
816 }
817 }
818 v=v->next;
819 cnt++;
820 }
821
822 return(cnt);
823 }
824
825 /******************************************************************/
826
827 /*
828 * single char get inlined/optimized
829 */
getch_alloc(void)830 static void getch_alloc(void)
831 {
832 GLOBALS->vend_vcd_recoder_c_3=GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vcdbuf_vcd_recoder_c_3=(char *)calloc_2(1,VCD_BSIZ);
833 }
834
getch_free(void)835 static void getch_free(void)
836 {
837 free_2(GLOBALS->vcdbuf_vcd_recoder_c_3);
838 GLOBALS->vcdbuf_vcd_recoder_c_3=GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vend_vcd_recoder_c_3=NULL;
839 }
840
841
842
getch_fetch(void)843 static int getch_fetch(void)
844 {
845 size_t rd;
846
847 errno = 0;
848 if(feof(GLOBALS->vcd_handle_vcd_recoder_c_2)) return(-1);
849
850 GLOBALS->vcdbyteno_vcd_recoder_c_3+=(GLOBALS->vend_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3);
851 rd=fread(GLOBALS->vcdbuf_vcd_recoder_c_3, sizeof(char), VCD_BSIZ, GLOBALS->vcd_handle_vcd_recoder_c_2);
852 GLOBALS->vend_vcd_recoder_c_3=(GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vcdbuf_vcd_recoder_c_3)+rd;
853
854 if((!rd)||(errno)) return(-1);
855
856 if(GLOBALS->vcd_fsiz_vcd_recoder_c_2)
857 {
858 splash_sync(GLOBALS->vcdbyteno_vcd_recoder_c_3, GLOBALS->vcd_fsiz_vcd_recoder_c_2); /* gnome 2.18 seems to set errno so splash moved here... */
859 }
860
861 return((int)(*GLOBALS->vst_vcd_recoder_c_3));
862 }
863
getch(void)864 static inline signed char getch(void) {
865 signed char ch = (GLOBALS->vst_vcd_recoder_c_3!=GLOBALS->vend_vcd_recoder_c_3)?((int)(*GLOBALS->vst_vcd_recoder_c_3)):(getch_fetch());
866 GLOBALS->vst_vcd_recoder_c_3++;
867 return(ch);
868 }
869
getch_peek(void)870 static inline signed char getch_peek(void) {
871 signed char ch = (GLOBALS->vst_vcd_recoder_c_3!=GLOBALS->vend_vcd_recoder_c_3)?((int)(*GLOBALS->vst_vcd_recoder_c_3)):(getch_fetch());
872 /* no increment */
873 return(ch);
874 }
875
getch_patched(void)876 static int getch_patched(void)
877 {
878 char ch;
879
880 ch=*GLOBALS->vsplitcurr_vcd_recoder_c_3;
881 if(!ch)
882 {
883 return(-1);
884 }
885 else
886 {
887 GLOBALS->vsplitcurr_vcd_recoder_c_3++;
888 return((int)ch);
889 }
890 }
891
892 /*
893 * simple tokenizer
894 */
get_token(void)895 static int get_token(void)
896 {
897 int ch;
898 int i, len=0;
899 int is_string=0;
900 char *yyshadow;
901
902 for(;;)
903 {
904 ch=getch();
905 if(ch<0) return(T_EOF);
906 if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */
907 break; /* (take advantage of fact that vcd is text) */
908 }
909 if(ch=='$')
910 {
911 GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;
912 for(;;)
913 {
914 ch=getch();
915 if(ch<0) return(T_EOF);
916 if(ch<=' ') continue;
917 break;
918 }
919 }
920 else
921 {
922 is_string=1;
923 }
924
925 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
926 {
927 if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
928 {
929 GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
930 }
931 ch=getch();
932 if(ch<=' ') break;
933 }
934 GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* terminator */
935
936 if(is_string)
937 {
938 GLOBALS->yylen_vcd_recoder_c_3=len;
939 return(T_STRING);
940 }
941
942 yyshadow=GLOBALS->yytext_vcd_recoder_c_3;
943 do
944 {
945 yyshadow++;
946 for(i=0;i<NUM_TOKENS;i++)
947 {
948 if(!strcmp(yyshadow,tokens[i]))
949 {
950 return(i);
951 }
952 }
953
954 } while(*yyshadow=='$'); /* fix for RCS ids in version strings */
955
956 return(T_UNKNOWN_KEY);
957 }
958
959
get_vartoken_patched(int match_kw)960 static int get_vartoken_patched(int match_kw)
961 {
962 int ch;
963 int len=0;
964
965 if(!GLOBALS->var_prevch_vcd_recoder_c_3)
966 {
967 for(;;)
968 {
969 ch=getch_patched();
970 if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; return(V_END); }
971 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
972 break;
973 }
974 }
975 else
976 {
977 ch=GLOBALS->var_prevch_vcd_recoder_c_3;
978 GLOBALS->var_prevch_vcd_recoder_c_3=0;
979 }
980
981 if(ch=='[') return(V_LB);
982 if(ch==':') return(V_COLON);
983 if(ch==']') return(V_RB);
984
985 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
986 {
987 if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
988 {
989 GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
990 }
991 ch=getch_patched();
992 if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; break; }
993 if((ch==':')||(ch==']'))
994 {
995 GLOBALS->var_prevch_vcd_recoder_c_3=ch;
996 break;
997 }
998 }
999 GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* terminator */
1000
1001 if(match_kw)
1002 {
1003 int vr = vcd_keyword_code(GLOBALS->yytext_vcd_recoder_c_3, len);
1004 if(vr != V_STRING)
1005 {
1006 if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; }
1007 return(vr);
1008 }
1009 }
1010
1011 GLOBALS->yylen_vcd_recoder_c_3=len;
1012 if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; }
1013 return(V_STRING);
1014 }
1015
get_vartoken(int match_kw)1016 static int get_vartoken(int match_kw)
1017 {
1018 int ch;
1019 int len=0;
1020
1021 if(GLOBALS->varsplit_vcd_recoder_c_3)
1022 {
1023 int rc=get_vartoken_patched(match_kw);
1024 if(rc!=V_END) return(rc);
1025 GLOBALS->var_prevch_vcd_recoder_c_3=0;
1026 }
1027
1028 if(!GLOBALS->var_prevch_vcd_recoder_c_3)
1029 {
1030 for(;;)
1031 {
1032 ch=getch();
1033 if(ch<0) return(V_END);
1034 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
1035 break;
1036 }
1037 }
1038 else
1039 {
1040 ch=GLOBALS->var_prevch_vcd_recoder_c_3;
1041 GLOBALS->var_prevch_vcd_recoder_c_3=0;
1042 }
1043
1044 if(ch=='[') return(V_LB);
1045 if(ch==':') return(V_COLON);
1046 if(ch==']') return(V_RB);
1047
1048 if(ch=='#') /* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */
1049 { /* debussy simply escapes until the space */
1050 GLOBALS->yytext_vcd_recoder_c_3[len++]= '\\';
1051 }
1052
1053 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
1054 {
1055 if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
1056 {
1057 GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
1058 }
1059
1060 ch=getch();
1061 if(ch==' ')
1062 {
1063 if(match_kw) break;
1064 if(getch_peek() == '[')
1065 {
1066 ch = getch();
1067 GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->yytext_vcd_recoder_c_3+len; /* keep looping so we get the *last* one */
1068 continue;
1069 }
1070 }
1071
1072 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
1073 if((ch=='[')&&(GLOBALS->yytext_vcd_recoder_c_3[0]!='\\'))
1074 {
1075 GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->yytext_vcd_recoder_c_3+len; /* keep looping so we get the *last* one */
1076 }
1077 else
1078 if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_recoder_c_3)&&(GLOBALS->yytext_vcd_recoder_c_3[0]!='\\'))
1079 {
1080 GLOBALS->var_prevch_vcd_recoder_c_3=ch;
1081 break;
1082 }
1083 }
1084
1085 GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* absolute terminator */
1086 if((GLOBALS->varsplit_vcd_recoder_c_3)&&(GLOBALS->yytext_vcd_recoder_c_3[len-1]==']'))
1087 {
1088 char *vst;
1089 vst=malloc_2(strlen(GLOBALS->varsplit_vcd_recoder_c_3)+1);
1090 strcpy(vst, GLOBALS->varsplit_vcd_recoder_c_3);
1091
1092 *GLOBALS->varsplit_vcd_recoder_c_3=0x00; /* zero out var name at the left bracket */
1093 len=GLOBALS->varsplit_vcd_recoder_c_3-GLOBALS->yytext_vcd_recoder_c_3;
1094
1095 GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->vsplitcurr_vcd_recoder_c_3=vst;
1096 GLOBALS->var_prevch_vcd_recoder_c_3=0;
1097 }
1098 else
1099 {
1100 GLOBALS->varsplit_vcd_recoder_c_3=NULL;
1101 }
1102
1103 if(match_kw)
1104 {
1105 int vr = vcd_keyword_code(GLOBALS->yytext_vcd_recoder_c_3, len);
1106 if(vr != V_STRING)
1107 {
1108 return(vr);
1109 }
1110 }
1111
1112 GLOBALS->yylen_vcd_recoder_c_3=len;
1113 return(V_STRING);
1114 }
1115
get_strtoken(void)1116 static int get_strtoken(void)
1117 {
1118 int ch;
1119 int len=0;
1120
1121 if(!GLOBALS->var_prevch_vcd_recoder_c_3)
1122 {
1123 for(;;)
1124 {
1125 ch=getch();
1126 if(ch<0) return(V_END);
1127 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
1128 break;
1129 }
1130 }
1131 else
1132 {
1133 ch=GLOBALS->var_prevch_vcd_recoder_c_3;
1134 GLOBALS->var_prevch_vcd_recoder_c_3=0;
1135 }
1136
1137 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
1138 {
1139 if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
1140 {
1141 GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
1142 }
1143 ch=getch();
1144 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
1145 }
1146 GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* terminator */
1147
1148 GLOBALS->yylen_vcd_recoder_c_3=len;
1149 return(V_STRING);
1150 }
1151
sync_end(char * hdr)1152 static void sync_end(char *hdr)
1153 {
1154 int tok;
1155
1156 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
1157 for(;;)
1158 {
1159 tok=get_token();
1160 if((tok==T_END)||(tok==T_EOF)) break;
1161 if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_recoder_c_3)); }
1162 }
1163 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
1164 }
1165
version_sync_end(char * hdr)1166 static int version_sync_end(char *hdr)
1167 {
1168 int tok;
1169 int rc = 0;
1170
1171 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
1172 for(;;)
1173 {
1174 tok=get_token();
1175 if((tok==T_END)||(tok==T_EOF)) break;
1176 if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_recoder_c_3)); }
1177 if(strstr(GLOBALS->yytext_vcd_recoder_c_3, "Icarus")) /* turn off autocoalesce for Icarus */
1178 {
1179 GLOBALS->autocoalesce = 0;
1180 rc = 1;
1181 }
1182 }
1183 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
1184 return(rc);
1185 }
1186
parse_valuechange(void)1187 static void parse_valuechange(void)
1188 {
1189 struct vcdsymbol *v;
1190 char *vector;
1191 int vlen;
1192 unsigned char typ;
1193
1194 switch((typ = GLOBALS->yytext_vcd_recoder_c_3[0]))
1195 {
1196 /* encode bits as (time delta<<4) + (enum AnalyzerBits value) */
1197 case '0':
1198 case '1':
1199 case 'x': case 'X':
1200 case 'z': case 'Z':
1201 case 'h': case 'H':
1202 case 'u': case 'U':
1203 case 'w': case 'W':
1204 case 'l': case 'L':
1205 case '-':
1206 if(GLOBALS->yylen_vcd_recoder_c_3>1)
1207 {
1208 v=bsearch_vcd(GLOBALS->yytext_vcd_recoder_c_3+1, GLOBALS->yylen_vcd_recoder_c_3-1);
1209 if(!v)
1210 {
1211 fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)),GLOBALS->yytext_vcd_recoder_c_3+1);
1212 malform_eof_fix();
1213 }
1214 else
1215 {
1216 nptr n = v->narray[0];
1217 unsigned int time_delta;
1218 unsigned int rcv;
1219
1220 if(!n->mv.mvlfac_vlist) /* overloaded for vlist, numhist = last position used */
1221 {
1222 n->mv.mvlfac_vlist = (GLOBALS->vlist_prepack) ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char));
1223 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)'0'); /* represents single bit routine for decompression */
1224 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
1225 }
1226
1227 time_delta = GLOBALS->time_vlist_count_vcd_recoder_c_1 - (unsigned int)n->numhist;
1228 n->numhist = GLOBALS->time_vlist_count_vcd_recoder_c_1;
1229
1230 switch(GLOBALS->yytext_vcd_recoder_c_3[0])
1231 {
1232 case '0':
1233 case '1': rcv = ((GLOBALS->yytext_vcd_recoder_c_3[0]&1)<<1) | (time_delta<<2);
1234 break; /* pack more delta bits in for 0/1 vchs */
1235
1236 case 'x': case 'X': rcv = RCV_X | (time_delta<<4); break;
1237 case 'z': case 'Z': rcv = RCV_Z | (time_delta<<4); break;
1238 case 'h': case 'H': rcv = RCV_H | (time_delta<<4); break;
1239 case 'u': case 'U': rcv = RCV_U | (time_delta<<4); break;
1240 case 'w': case 'W': rcv = RCV_W | (time_delta<<4); break;
1241 case 'l': case 'L': rcv = RCV_L | (time_delta<<4); break;
1242 default: rcv = RCV_D | (time_delta<<4); break;
1243 }
1244
1245 vlist_emit_uv32(&n->mv.mvlfac_vlist, rcv);
1246 }
1247 }
1248 else
1249 {
1250 fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
1251 malform_eof_fix();
1252 }
1253 break;
1254
1255 /* encode everything else literally as a time delta + a string */
1256 #ifndef STRICT_VCD_ONLY
1257 case 's':
1258 case 'S':
1259 vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3);
1260 vlen = fstUtilityEscToBin((unsigned char *)vector, (unsigned char *)(GLOBALS->yytext_vcd_recoder_c_3+1), GLOBALS->yylen_vcd_recoder_c_3-1);
1261 vector[vlen] = 0;
1262
1263 get_strtoken();
1264 goto process_binary;
1265 #endif
1266 case 'b':
1267 case 'B':
1268 case 'r':
1269 case 'R':
1270 vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3);
1271 strcpy(vector,GLOBALS->yytext_vcd_recoder_c_3+1);
1272 vlen=GLOBALS->yylen_vcd_recoder_c_3-1;
1273
1274 get_strtoken();
1275 process_binary:
1276 v=bsearch_vcd(GLOBALS->yytext_vcd_recoder_c_3, GLOBALS->yylen_vcd_recoder_c_3);
1277 if(!v)
1278 {
1279 fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)),GLOBALS->yytext_vcd_recoder_c_3+1);
1280 malform_eof_fix();
1281 }
1282 else
1283 {
1284 nptr n = v->narray[0];
1285 unsigned int time_delta;
1286
1287 if(!n->mv.mvlfac_vlist) /* overloaded for vlist, numhist = last position used */
1288 {
1289 unsigned char typ2 = toupper(typ);
1290 n->mv.mvlfac_vlist = (GLOBALS->vlist_prepack) ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char));
1291
1292 if((v->vartype!=V_REAL) && (v->vartype!=V_STRINGTYPE))
1293 {
1294 if((typ2=='R')||(typ2=='S'))
1295 {
1296 typ2 = 'B'; /* ok, typical case...fix as 'r' on bits variable causes recoder crash during trace extraction */
1297 }
1298 }
1299 else
1300 {
1301 if(typ2=='B')
1302 {
1303 typ2 = 'S'; /* should never be necessary...this is defensive */
1304 }
1305 }
1306
1307
1308 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)toupper(typ2)); /* B/R/P/S for decompress */
1309 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
1310 vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
1311 }
1312
1313 time_delta = GLOBALS->time_vlist_count_vcd_recoder_c_1 - (unsigned int)n->numhist;
1314 n->numhist = GLOBALS->time_vlist_count_vcd_recoder_c_1;
1315
1316 vlist_emit_uv32(&n->mv.mvlfac_vlist, time_delta);
1317
1318 if((typ=='b')||(typ=='B'))
1319 {
1320 if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE))
1321 {
1322 vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, vector);
1323 }
1324 else
1325 {
1326 vlist_emit_string(&n->mv.mvlfac_vlist, vector);
1327 }
1328 }
1329 else
1330 {
1331 if((v->vartype == V_REAL)||(v->vartype == V_STRINGTYPE)||(typ=='s')||(typ=='S'))
1332 {
1333 vlist_emit_string(&n->mv.mvlfac_vlist, vector);
1334 }
1335 else
1336 {
1337 char *bits = wave_alloca(v->size + 1);
1338 int i, j, k=0;
1339
1340 memset(bits, 0x0, v->size + 1);
1341
1342 for(i=0;i<vlen;i++)
1343 {
1344 for(j=0;j<8;j++)
1345 {
1346 bits[k++] = ((vector[i] >> (7-j)) & 1) | '0';
1347 if(k >= v->size) goto bit_term;
1348 }
1349 }
1350
1351 bit_term:
1352 vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, bits);
1353 }
1354 }
1355 }
1356 break;
1357
1358 case 'p':
1359 case 'P':
1360 /* extract port dump value.. */
1361 vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3);
1362 evcd_strcpy(vector,GLOBALS->yytext_vcd_recoder_c_3+1); /* convert to regular vcd */
1363 vlen=GLOBALS->yylen_vcd_recoder_c_3-1;
1364
1365 get_strtoken(); /* throw away 0_strength_component */
1366 get_strtoken(); /* throw away 0_strength_component */
1367 get_strtoken(); /* this is the id */
1368
1369 typ = 'b'; /* convert to regular vcd */
1370 goto process_binary; /* store string literally */
1371
1372 default:
1373 break;
1374 }
1375 }
1376
1377
evcd_strcpy(char * dst,char * src)1378 static void evcd_strcpy(char *dst, char *src)
1379 {
1380 static const char *evcd="DUNZduLHXTlh01?FAaBbCcf";
1381 static const char *vcd="01xz0101xz0101xzxxxxxxz";
1382
1383 char ch;
1384 int i;
1385
1386 while((ch=*src))
1387 {
1388 for(i=0;i<23;i++)
1389 {
1390 if(evcd[i]==ch)
1391 {
1392 *dst=vcd[i];
1393 break;
1394 }
1395 }
1396 if(i==23) *dst='x';
1397
1398 src++;
1399 dst++;
1400 }
1401
1402 *dst=0; /* null terminate destination */
1403 }
1404
1405
vcd_parse(void)1406 static void vcd_parse(void)
1407 {
1408 int tok;
1409 unsigned char ttype;
1410 int disable_autocoalesce = 0;
1411
1412 for(;;)
1413 {
1414 switch(get_token())
1415 {
1416 case T_COMMENT:
1417 sync_end("COMMENT:");
1418 break;
1419 case T_DATE:
1420 sync_end("DATE:");
1421 break;
1422 case T_VERSION:
1423 disable_autocoalesce = version_sync_end("VERSION:");
1424 break;
1425 case T_TIMEZERO:
1426 {
1427 int vtok=get_token();
1428 if((vtok==T_END)||(vtok==T_EOF)) break;
1429 GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1430
1431 DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset));
1432 sync_end(NULL);
1433 }
1434 break;
1435 case T_TIMESCALE:
1436 {
1437 int vtok;
1438 int i;
1439 char prefix=' ';
1440
1441 vtok=get_token();
1442 if((vtok==T_END)||(vtok==T_EOF)) break;
1443 fractional_timescale_fix(GLOBALS->yytext_vcd_recoder_c_3);
1444 GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1445 if(!GLOBALS->time_scale) GLOBALS->time_scale=1;
1446 for(i=0;i<GLOBALS->yylen_vcd_recoder_c_3;i++)
1447 {
1448 if((GLOBALS->yytext_vcd_recoder_c_3[i]<'0')||(GLOBALS->yytext_vcd_recoder_c_3[i]>'9'))
1449 {
1450 prefix=GLOBALS->yytext_vcd_recoder_c_3[i];
1451 break;
1452 }
1453 }
1454 if(prefix==' ')
1455 {
1456 vtok=get_token();
1457 if((vtok==T_END)||(vtok==T_EOF)) break;
1458 prefix=GLOBALS->yytext_vcd_recoder_c_3[0];
1459 }
1460 switch(prefix)
1461 {
1462 case ' ':
1463 case 'm':
1464 case 'u':
1465 case 'n':
1466 case 'p':
1467 case 'f':
1468 case 'a':
1469 case 'z':
1470 GLOBALS->time_dimension=prefix;
1471 break;
1472 case 's':
1473 GLOBALS->time_dimension=' ';
1474 break;
1475 default: /* unknown */
1476 GLOBALS->time_dimension='n';
1477 break;
1478 }
1479
1480 DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension));
1481 sync_end(NULL);
1482 }
1483 break;
1484 case T_SCOPE:
1485 T_GET;
1486 {
1487 switch(GLOBALS->yytext_vcd_recoder_c_3[0])
1488 {
1489 case 'm': ttype = TREE_VCD_ST_MODULE; break;
1490 case 't': ttype = TREE_VCD_ST_TASK; break;
1491 case 'f': ttype = (GLOBALS->yytext_vcd_recoder_c_3[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break;
1492 case 'b': ttype = TREE_VCD_ST_BEGIN; break;
1493 case 'g': ttype = TREE_VCD_ST_GENERATE; break;
1494 case 's': ttype = TREE_VCD_ST_STRUCT; break;
1495 case 'u': ttype = TREE_VCD_ST_UNION; break;
1496 case 'c': ttype = TREE_VCD_ST_CLASS; break;
1497 case 'i': ttype = TREE_VCD_ST_INTERFACE; break;
1498 case 'p': ttype = (GLOBALS->yytext_vcd_recoder_c_3[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break;
1499
1500 case 'v': {
1501 char *vht = GLOBALS->yytext_vcd_recoder_c_3;
1502 if(!strncmp(vht, "vhdl_", 5))
1503 {
1504 switch(vht[5])
1505 {
1506 case 'a': ttype = TREE_VHDL_ST_ARCHITECTURE; break;
1507 case 'r': ttype = TREE_VHDL_ST_RECORD; break;
1508 case 'b': ttype = TREE_VHDL_ST_BLOCK; break;
1509 case 'g': ttype = TREE_VHDL_ST_GENERATE; break;
1510 case 'i': ttype = TREE_VHDL_ST_GENIF; break;
1511 case 'f': ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break;
1512 case 'p': ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break;
1513 default: ttype = TREE_UNKNOWN; break;
1514 }
1515 }
1516 else
1517 {
1518 ttype = TREE_UNKNOWN;
1519 }
1520 }
1521 break;
1522
1523 default: ttype = TREE_UNKNOWN;
1524 break;
1525 }
1526 }
1527 T_GET;
1528 if(tok==T_STRING)
1529 {
1530 struct slist *s;
1531 s=(struct slist *)calloc_2(1,sizeof(struct slist));
1532 s->len=GLOBALS->yylen_vcd_recoder_c_3;
1533 s->str=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1534 strcpy(s->str, GLOBALS->yytext_vcd_recoder_c_3);
1535 s->mod_tree_parent = GLOBALS->mod_tree_parent;
1536
1537 allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_recoder_c_3, NULL, GLOBALS->yylen_vcd_recoder_c_3, 0, 0, 0);
1538
1539 if(GLOBALS->slistcurr)
1540 {
1541 GLOBALS->slistcurr->next=s;
1542 GLOBALS->slistcurr=s;
1543 }
1544 else
1545 {
1546 GLOBALS->slistcurr=GLOBALS->slistroot=s;
1547 }
1548
1549 build_slisthier();
1550 DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1551 }
1552 sync_end(NULL);
1553 break;
1554 case T_UPSCOPE:
1555 if(GLOBALS->slistroot)
1556 {
1557 struct slist *s;
1558
1559 GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent;
1560 s=GLOBALS->slistroot;
1561 if(!s->next)
1562 {
1563 free_2(s->str);
1564 free_2(s);
1565 GLOBALS->slistroot=GLOBALS->slistcurr=NULL;
1566 }
1567 else
1568 for(;;)
1569 {
1570 if(!s->next->next)
1571 {
1572 free_2(s->next->str);
1573 free_2(s->next);
1574 s->next=NULL;
1575 GLOBALS->slistcurr=s;
1576 break;
1577 }
1578 s=s->next;
1579 }
1580 build_slisthier();
1581 DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1582 }
1583 else
1584 {
1585 GLOBALS->mod_tree_parent = NULL;
1586 }
1587 sync_end(NULL);
1588 break;
1589 case T_VAR:
1590 if((GLOBALS->header_over_vcd_recoder_c_3)&&(0))
1591 {
1592 fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d. VCD is malformed, exiting.\n",
1593 (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
1594 vcd_exit(255);
1595 }
1596 else
1597 {
1598 int vtok;
1599 struct vcdsymbol *v=NULL;
1600
1601 GLOBALS->var_prevch_vcd_recoder_c_3=0;
1602 if(GLOBALS->varsplit_vcd_recoder_c_3)
1603 {
1604 free_2(GLOBALS->varsplit_vcd_recoder_c_3);
1605 GLOBALS->varsplit_vcd_recoder_c_3=NULL;
1606 }
1607 vtok=get_vartoken(1);
1608 if(vtok>V_STRINGTYPE) goto bail;
1609
1610 v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol));
1611 v->vartype=vtok;
1612 v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */
1613
1614 if(vtok==V_PORT)
1615 {
1616 vtok=get_vartoken(1);
1617 if(vtok==V_STRING)
1618 {
1619 v->size=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1620 if(!v->size) v->size=1;
1621 }
1622 else
1623 if(vtok==V_LB)
1624 {
1625 vtok=get_vartoken(1);
1626 if(vtok==V_END) goto err;
1627 if(vtok!=V_STRING) goto err;
1628 v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1629 vtok=get_vartoken(0);
1630 if(vtok==V_RB)
1631 {
1632 v->lsi=v->msi;
1633 v->size=1;
1634 }
1635 else
1636 {
1637 if(vtok!=V_COLON) goto err;
1638 vtok=get_vartoken(0);
1639 if(vtok!=V_STRING) goto err;
1640 v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1641 vtok=get_vartoken(0);
1642 if(vtok!=V_RB) goto err;
1643
1644 if(v->msi>v->lsi)
1645 {
1646 v->size=v->msi-v->lsi+1;
1647 }
1648 else
1649 {
1650 v->size=v->lsi-v->msi+1;
1651 }
1652 }
1653 }
1654 else goto err;
1655
1656 vtok=get_strtoken();
1657 if(vtok==V_END) goto err;
1658 v->id=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1659 strcpy(v->id, GLOBALS->yytext_vcd_recoder_c_3);
1660 v->nid=vcdid_hash(GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->yylen_vcd_recoder_c_3);
1661
1662 if(v->nid == (GLOBALS->vcd_hash_max+1))
1663 {
1664 GLOBALS->vcd_hash_max = v->nid;
1665 }
1666 else
1667 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1668 {
1669 /* general case with aliases */
1670 }
1671 else
1672 {
1673 GLOBALS->vcd_hash_kill = 1;
1674 }
1675
1676 if(v->nid < GLOBALS->vcd_minid_vcd_recoder_c_3) GLOBALS->vcd_minid_vcd_recoder_c_3 = v->nid;
1677 if(v->nid > GLOBALS->vcd_maxid_vcd_recoder_c_3) GLOBALS->vcd_maxid_vcd_recoder_c_3 = v->nid;
1678
1679 vtok=get_vartoken(0);
1680 if(vtok!=V_STRING) goto err;
1681 if(GLOBALS->slisthier_len)
1682 {
1683 v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+1);
1684 strcpy(v->name,GLOBALS->slisthier);
1685 strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1686 if(GLOBALS->alt_hier_delimeter)
1687 {
1688 strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1689 }
1690 else
1691 {
1692 if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1693 {
1694 char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+2);
1695 strcpy(sd,GLOBALS->slisthier);
1696 strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1697 sd[GLOBALS->slisthier_len+1] = '\\';
1698 strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1699 free_2(v->name);
1700 v->name = sd;
1701 }
1702 }
1703 }
1704 else
1705 {
1706 v->name=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1707 if(GLOBALS->alt_hier_delimeter)
1708 {
1709 strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1710 }
1711 else
1712 {
1713 if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1714 {
1715 char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+2);
1716 sd[0] = '\\';
1717 strcpy(sd+1,v->name);
1718 free_2(v->name);
1719 v->name = sd;
1720 }
1721 }
1722 }
1723
1724 if(GLOBALS->pv_vcd_recoder_c_3)
1725 {
1726 if(!strcmp(GLOBALS->prev_hier_uncompressed_name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\')))
1727 {
1728 GLOBALS->pv_vcd_recoder_c_3->chain=v;
1729 v->root=GLOBALS->rootv_vcd_recoder_c_3;
1730 if(GLOBALS->pv_vcd_recoder_c_3==GLOBALS->rootv_vcd_recoder_c_3) GLOBALS->pv_vcd_recoder_c_3->root=GLOBALS->rootv_vcd_recoder_c_3;
1731 }
1732 else
1733 {
1734 GLOBALS->rootv_vcd_recoder_c_3=v;
1735 }
1736
1737 free_2(GLOBALS->prev_hier_uncompressed_name);
1738 }
1739 else
1740 {
1741 GLOBALS->rootv_vcd_recoder_c_3=v;
1742 }
1743
1744 GLOBALS->pv_vcd_recoder_c_3=v;
1745 GLOBALS->prev_hier_uncompressed_name = strdup_2(v->name);
1746 }
1747 else /* regular vcd var, not an evcd port var */
1748 {
1749 vtok=get_vartoken(1);
1750 if(vtok==V_END) goto err;
1751 v->size=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1752 vtok=get_strtoken();
1753 if(vtok==V_END) goto err;
1754 v->id=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1755 strcpy(v->id, GLOBALS->yytext_vcd_recoder_c_3);
1756 v->nid=vcdid_hash(GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->yylen_vcd_recoder_c_3);
1757
1758 if(v->nid == (GLOBALS->vcd_hash_max+1))
1759 {
1760 GLOBALS->vcd_hash_max = v->nid;
1761 }
1762 else
1763 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1764 {
1765 /* general case with aliases */
1766 }
1767 else
1768 {
1769 GLOBALS->vcd_hash_kill = 1;
1770 }
1771
1772 if(v->nid < GLOBALS->vcd_minid_vcd_recoder_c_3) GLOBALS->vcd_minid_vcd_recoder_c_3 = v->nid;
1773 if(v->nid > GLOBALS->vcd_maxid_vcd_recoder_c_3) GLOBALS->vcd_maxid_vcd_recoder_c_3 = v->nid;
1774
1775 vtok=get_vartoken(0);
1776 if(vtok!=V_STRING) goto err;
1777
1778 if(GLOBALS->slisthier_len)
1779 {
1780 v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+1);
1781 strcpy(v->name,GLOBALS->slisthier);
1782 strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1783 if(GLOBALS->alt_hier_delimeter)
1784 {
1785 strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1786 }
1787 else
1788 {
1789 if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1790 {
1791 char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+2);
1792 strcpy(sd,GLOBALS->slisthier);
1793 strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1794 sd[GLOBALS->slisthier_len+1] = '\\';
1795 strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1796 free_2(v->name);
1797 v->name = sd;
1798 }
1799 }
1800 }
1801 else
1802 {
1803 v->name=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1804 if(GLOBALS->alt_hier_delimeter)
1805 {
1806 strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1807 }
1808 else
1809 {
1810 if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1811 {
1812 char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+2);
1813 sd[0] = '\\';
1814 strcpy(sd+1,v->name);
1815 free_2(v->name);
1816 v->name = sd;
1817 }
1818 }
1819 }
1820
1821 if(GLOBALS->pv_vcd_recoder_c_3)
1822 {
1823 if(!strcmp(GLOBALS->prev_hier_uncompressed_name,v->name))
1824 {
1825 GLOBALS->pv_vcd_recoder_c_3->chain=v;
1826 v->root=GLOBALS->rootv_vcd_recoder_c_3;
1827 if(GLOBALS->pv_vcd_recoder_c_3==GLOBALS->rootv_vcd_recoder_c_3) GLOBALS->pv_vcd_recoder_c_3->root=GLOBALS->rootv_vcd_recoder_c_3;
1828 }
1829 else
1830 {
1831 GLOBALS->rootv_vcd_recoder_c_3=v;
1832 }
1833
1834 free_2(GLOBALS->prev_hier_uncompressed_name);
1835 }
1836 else
1837 {
1838 GLOBALS->rootv_vcd_recoder_c_3=v;
1839 }
1840 GLOBALS->pv_vcd_recoder_c_3=v;
1841 GLOBALS->prev_hier_uncompressed_name = strdup_2(v->name);
1842
1843 vtok=get_vartoken(1);
1844 if(vtok==V_END) goto dumpv;
1845 if(vtok!=V_LB) goto err;
1846 vtok=get_vartoken(0);
1847 if(vtok!=V_STRING) goto err;
1848 v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1849 vtok=get_vartoken(0);
1850 if(vtok==V_RB)
1851 {
1852 v->lsi=v->msi;
1853 goto dumpv;
1854 }
1855 if(vtok!=V_COLON) goto err;
1856 vtok=get_vartoken(0);
1857 if(vtok!=V_STRING) goto err;
1858 v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1859 vtok=get_vartoken(0);
1860 if(vtok!=V_RB) goto err;
1861 }
1862
1863 dumpv:
1864 if(v->size == 0)
1865 {
1866 if(v->vartype != V_EVENT)
1867 {
1868 if(v->vartype != V_STRINGTYPE)
1869 {
1870 v->vartype = V_REAL;
1871 }
1872 }
1873 else
1874 {
1875 v->size = 1;
1876 }
1877
1878 } /* MTI fix */
1879
1880
1881 if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
1882 {
1883 v->size=1; /* override any data we parsed in */
1884 v->msi=v->lsi=0;
1885 }
1886 else
1887 if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0))
1888 {
1889 if(v->vartype==V_EVENT)
1890 {
1891 v->size=1;
1892 }
1893 else
1894 {
1895 /* any criteria for the direction here? */
1896 v->msi=v->size-1;
1897 v->lsi=0;
1898 }
1899 }
1900 else
1901 if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
1902 {
1903 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1904 {
1905 if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */
1906 {
1907 v->msi = v->size-1; v->lsi = 0;
1908 }
1909 /* all this formerly was goto err; */
1910 }
1911 else
1912 {
1913 v->size=v->msi-v->lsi+1;
1914 }
1915 }
1916 else
1917 if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
1918 {
1919 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1920 {
1921 if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */
1922 {
1923 v->lsi = v->size-1; v->msi = 0;
1924 }
1925 /* all this formerly was goto err; */
1926 }
1927 else
1928 {
1929 v->size=v->lsi-v->msi+1;
1930 }
1931 }
1932
1933 /* initial conditions */
1934 v->narray=(struct Node **)calloc_2(1,sizeof(struct Node *));
1935 v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node));
1936 v->narray[0]->head.time=-1;
1937 v->narray[0]->head.v.h_val=AN_X;
1938
1939 if(!GLOBALS->vcdsymroot_vcd_recoder_c_3)
1940 {
1941 GLOBALS->vcdsymroot_vcd_recoder_c_3=GLOBALS->vcdsymcurr_vcd_recoder_c_3=v;
1942 }
1943 else
1944 {
1945 GLOBALS->vcdsymcurr_vcd_recoder_c_3->next=v;
1946 GLOBALS->vcdsymcurr_vcd_recoder_c_3=v;
1947 }
1948 GLOBALS->numsyms_vcd_recoder_c_3++;
1949
1950 if(GLOBALS->vcd_save_handle)
1951 {
1952 if(v->msi==v->lsi)
1953 {
1954 if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
1955 {
1956 fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name);
1957 }
1958 else
1959 {
1960 if(v->msi>=0)
1961 {
1962 if(!GLOBALS->vcd_explicit_zero_subscripts)
1963 fprintf(GLOBALS->vcd_save_handle,"%s%c%d\n",v->name,GLOBALS->hier_delimeter,v->msi);
1964 else
1965 fprintf(GLOBALS->vcd_save_handle,"%s[%d]\n",v->name,v->msi);
1966 }
1967 else
1968 {
1969 fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name);
1970 }
1971 }
1972 }
1973 else
1974 {
1975 fprintf(GLOBALS->vcd_save_handle,"%s[%d:%d]\n",v->name,v->msi,v->lsi);
1976 }
1977 }
1978
1979 goto bail;
1980 err:
1981 if(v)
1982 {
1983 GLOBALS->error_count_vcd_recoder_c_3++;
1984 if(v->name)
1985 {
1986 fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)), v->name);
1987 free_2(v->name);
1988 }
1989 else
1990 {
1991 fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
1992 }
1993 if(v->id) free_2(v->id);
1994 free_2(v); v=NULL;
1995 GLOBALS->pv_vcd_recoder_c_3 = NULL;
1996 }
1997
1998 bail:
1999 if(vtok!=V_END) sync_end(NULL);
2000 break;
2001 }
2002 case T_ENDDEFINITIONS:
2003 GLOBALS->header_over_vcd_recoder_c_3=1; /* do symbol table management here */
2004 create_sorted_table();
2005 if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3))
2006 {
2007 fprintf(stderr, "No symbols in VCD file..nothing to do!\n");
2008 vcd_exit(255);
2009 }
2010 if(GLOBALS->error_count_vcd_recoder_c_3)
2011 {
2012 fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_recoder_c_3);
2013 vcd_exit(255);
2014 }
2015
2016 if(GLOBALS->use_fastload == VCD_FSL_READ)
2017 {
2018 read_fastload_body();
2019 fprintf(stderr, "VCDLOAD | Using fastload file.\n");
2020 return;
2021 }
2022
2023 break;
2024 case T_STRING:
2025 if(!GLOBALS->header_over_vcd_recoder_c_3)
2026 {
2027 GLOBALS->header_over_vcd_recoder_c_3=1; /* do symbol table management here */
2028 create_sorted_table();
2029 if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3)) break;
2030 }
2031 {
2032 /* catchall for events when header over */
2033 if(GLOBALS->yytext_vcd_recoder_c_3[0]=='#')
2034 {
2035 TimeType tim;
2036 TimeType *tt;
2037
2038 tim=atoi_64(GLOBALS->yytext_vcd_recoder_c_3+1);
2039
2040 if(GLOBALS->start_time_vcd_recoder_c_3<0)
2041 {
2042 GLOBALS->start_time_vcd_recoder_c_3=tim;
2043
2044 if(GLOBALS->time_vlist_vcd_recoder_write)
2045 {
2046 vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim);
2047 }
2048 }
2049 else
2050 {
2051 /* backtracking fix */
2052 if(tim < GLOBALS->current_time_vcd_recoder_c_3)
2053 {
2054 if(!GLOBALS->vcd_already_backtracked)
2055 {
2056 GLOBALS->vcd_already_backtracked = 1;
2057 fprintf(stderr, "VCDLOAD | Time backtracking detected in VCD file!\n");
2058 }
2059 }
2060 #if 0
2061 if(tim < GLOBALS->current_time_vcd_recoder_c_3) /* avoid backtracking time counts which can happen on malformed files */
2062 {
2063 tim = GLOBALS->current_time_vcd_recoder_c_3;
2064 }
2065 #endif
2066
2067 if(GLOBALS->time_vlist_vcd_recoder_write)
2068 {
2069 vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim - GLOBALS->current_time_vcd_recoder_c_3);
2070 }
2071 }
2072
2073 GLOBALS->current_time_vcd_recoder_c_3=tim;
2074 if(GLOBALS->end_time_vcd_recoder_c_3<tim) GLOBALS->end_time_vcd_recoder_c_3=tim; /* in case of malformed vcd files */
2075 DEBUG(fprintf(stderr,"#"TTFormat"\n",tim));
2076
2077 tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0);
2078 *tt = tim;
2079 GLOBALS->time_vlist_count_vcd_recoder_c_1++;
2080 }
2081 else
2082 {
2083 if(GLOBALS->time_vlist_count_vcd_recoder_c_1)
2084 {
2085 /* OK, otherwise fix for System C which doesn't emit time zero... */
2086 }
2087 else
2088 {
2089 TimeType tim = LLDescriptor(0);
2090 TimeType *tt;
2091
2092 GLOBALS->start_time_vcd_recoder_c_3=GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=tim;
2093
2094 if(GLOBALS->time_vlist_vcd_recoder_write)
2095 {
2096 vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim);
2097 }
2098
2099 tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0);
2100 *tt = tim;
2101 GLOBALS->time_vlist_count_vcd_recoder_c_1=1;
2102 }
2103 parse_valuechange();
2104 }
2105 }
2106 break;
2107 case T_DUMPALL: /* dump commands modify vals anyway so */
2108 case T_DUMPPORTSALL:
2109 break; /* just loop through.. */
2110 case T_DUMPOFF:
2111 case T_DUMPPORTSOFF:
2112 GLOBALS->dumping_off_vcd_recoder_c_3=1;
2113 /* if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) : remove redundant condition */
2114 if((!GLOBALS->blackout_regions)||(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))
2115 {
2116 struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t));
2117
2118 bt->bstart = GLOBALS->current_time_vcd_recoder_c_3;
2119 bt->next = GLOBALS->blackout_regions;
2120 GLOBALS->blackout_regions = bt;
2121 }
2122 break;
2123 case T_DUMPON:
2124 case T_DUMPPORTSON:
2125 GLOBALS->dumping_off_vcd_recoder_c_3=0;
2126 if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
2127 {
2128 GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_recoder_c_3;
2129 }
2130 break;
2131 case T_DUMPVARS:
2132 case T_DUMPPORTS:
2133 if(GLOBALS->current_time_vcd_recoder_c_3<0)
2134 { GLOBALS->start_time_vcd_recoder_c_3=GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=0; }
2135 break;
2136 case T_VCDCLOSE:
2137 sync_end("VCDCLOSE:");
2138 break; /* next token will be '#' time related followed by $end */
2139 case T_END: /* either closure for dump commands or */
2140 break; /* it's spurious */
2141 case T_UNKNOWN_KEY:
2142 sync_end(NULL); /* skip over unknown keywords */
2143 break;
2144 case T_EOF:
2145 if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
2146 {
2147 GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_recoder_c_3;
2148 }
2149
2150 GLOBALS->pv_vcd_recoder_c_3 = NULL;
2151 if(GLOBALS->prev_hier_uncompressed_name) { free_2(GLOBALS->prev_hier_uncompressed_name); GLOBALS->prev_hier_uncompressed_name = NULL; }
2152
2153 return;
2154 default:
2155 DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n"));
2156 }
2157 }
2158 }
2159
2160
2161 /*******************************************************************************/
2162
add_histent(TimeType tim,struct Node * n,char ch,int regadd,char * vector)2163 void add_histent(TimeType tim, struct Node *n, char ch, int regadd, char *vector)
2164 {
2165 struct HistEnt *he;
2166 char heval;
2167
2168 if(!vector)
2169 {
2170 if(!n->curr)
2171 {
2172 he=histent_calloc();
2173 he->time=-1;
2174 he->v.h_val=AN_X;
2175
2176 n->curr=he;
2177 n->head.next=he;
2178
2179 add_histent(tim,n,ch,regadd, vector);
2180 }
2181 else
2182 {
2183 if(regadd) { tim*=(GLOBALS->time_scale); }
2184
2185 if(ch=='0') heval=AN_0; else
2186 if(ch=='1') heval=AN_1; else
2187 if((ch=='x')||(ch=='X')) heval=AN_X; else
2188 if((ch=='z')||(ch=='Z')) heval=AN_Z; else
2189 if((ch=='h')||(ch=='H')) heval=AN_H; else
2190 if((ch=='u')||(ch=='U')) heval=AN_U; else
2191 if((ch=='w')||(ch=='W')) heval=AN_W; else
2192 if((ch=='l')||(ch=='L')) heval=AN_L; else
2193 /* if(ch=='-') */ heval=AN_DASH; /* default */
2194
2195 if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_recoder_c_3)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */
2196 {
2197 if(n->curr->time==tim)
2198 {
2199 DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
2200 tim, n, AN_STR[n->curr->v.h_val], ch));
2201 n->curr->v.h_val=heval; /* we have a glitch! */
2202
2203 GLOBALS->num_glitches_vcd_recoder_c_4++;
2204 if(!(n->curr->flags&HIST_GLITCH))
2205 {
2206 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
2207 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2208 }
2209 }
2210 else
2211 {
2212 he=histent_calloc();
2213 he->time=tim;
2214 he->v.h_val=heval;
2215
2216 n->curr->next=he;
2217 if(n->curr->v.h_val==heval)
2218 {
2219 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
2220 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2221 }
2222 n->curr=he;
2223 GLOBALS->regions+=regadd;
2224 }
2225 }
2226 }
2227 }
2228 else
2229 {
2230 switch(ch)
2231 {
2232 case 's': /* string */
2233 {
2234 if(!n->curr)
2235 {
2236 he=histent_calloc();
2237 he->flags=(HIST_STRING|HIST_REAL);
2238 he->time=-1;
2239 he->v.h_vector=NULL;
2240
2241 n->curr=he;
2242 n->head.next=he;
2243
2244 add_histent(tim,n,ch,regadd, vector);
2245 }
2246 else
2247 {
2248 if(regadd) { tim*=(GLOBALS->time_scale); }
2249
2250 if(n->curr->time==tim)
2251 {
2252 DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n",
2253 tim, n));
2254 if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
2255 n->curr->v.h_vector=vector; /* we have a glitch! */
2256
2257 GLOBALS->num_glitches_vcd_recoder_c_4++;
2258 if(!(n->curr->flags&HIST_GLITCH))
2259 {
2260 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
2261 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2262 }
2263 }
2264 else
2265 {
2266 he=histent_calloc();
2267 he->flags=(HIST_STRING|HIST_REAL);
2268 he->time=tim;
2269 he->v.h_vector=vector;
2270
2271 n->curr->next=he;
2272 n->curr=he;
2273 GLOBALS->regions+=regadd;
2274 }
2275 }
2276 break;
2277 }
2278 case 'g': /* real number */
2279 {
2280 if(!n->curr)
2281 {
2282 he=histent_calloc();
2283 he->flags=HIST_REAL;
2284 he->time=-1;
2285 #ifdef WAVE_HAS_H_DOUBLE
2286 he->v.h_double = strtod("NaN", NULL);
2287 #else
2288 he->v.h_vector=NULL;
2289 #endif
2290
2291 n->curr=he;
2292 n->head.next=he;
2293
2294 add_histent(tim,n,ch,regadd, vector);
2295 }
2296 else
2297 {
2298 if(regadd) { tim*=(GLOBALS->time_scale); }
2299
2300 if(
2301 #ifdef WAVE_HAS_H_DOUBLE
2302 (vector&&(n->curr->v.h_double!=*(double *)vector))
2303 #else
2304 (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector))
2305 #endif
2306 ||(tim==GLOBALS->start_time_vcd_recoder_c_3)
2307 #ifndef WAVE_HAS_H_DOUBLE
2308 ||(!n->curr->v.h_vector)
2309 #endif
2310 ||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real)
2311 ) /* same region == go skip */
2312 {
2313 if(n->curr->time==tim)
2314 {
2315 DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n",
2316 tim, n));
2317 #ifdef WAVE_HAS_H_DOUBLE
2318 n->curr->v.h_double = *((double *)vector);
2319 #else
2320 if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
2321 n->curr->v.h_vector=vector; /* we have a glitch! */
2322 #endif
2323 GLOBALS->num_glitches_vcd_recoder_c_4++;
2324 if(!(n->curr->flags&HIST_GLITCH))
2325 {
2326 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
2327 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2328 }
2329 }
2330 else
2331 {
2332 he=histent_calloc();
2333 he->flags=HIST_REAL;
2334 he->time=tim;
2335 #ifdef WAVE_HAS_H_DOUBLE
2336 he->v.h_double = *((double *)vector);
2337 #else
2338 he->v.h_vector=vector;
2339 #endif
2340 n->curr->next=he;
2341 n->curr=he;
2342 GLOBALS->regions+=regadd;
2343 }
2344 }
2345 else
2346 {
2347 #ifndef WAVE_HAS_H_DOUBLE
2348 free_2(vector);
2349 #endif
2350 }
2351 #ifdef WAVE_HAS_H_DOUBLE
2352 free_2(vector);
2353 #endif
2354 }
2355 break;
2356 }
2357 default:
2358 {
2359 if(!n->curr)
2360 {
2361 he=histent_calloc();
2362 he->time=-1;
2363 he->v.h_vector=NULL;
2364
2365 n->curr=he;
2366 n->head.next=he;
2367
2368 add_histent(tim,n,ch,regadd, vector);
2369 }
2370 else
2371 {
2372 if(regadd) { tim*=(GLOBALS->time_scale); }
2373
2374 if(
2375 (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector)))
2376 ||(tim==GLOBALS->start_time_vcd_recoder_c_3)
2377 ||(!n->curr->v.h_vector)
2378 ||(GLOBALS->vcd_preserve_glitches)
2379 ) /* same region == go skip */
2380 {
2381 if(n->curr->time==tim)
2382 {
2383 DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
2384 tim, n, AN_STR[n->curr->v.h_val], ch));
2385 if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
2386 n->curr->v.h_vector=vector; /* we have a glitch! */
2387
2388 GLOBALS->num_glitches_vcd_recoder_c_4++;
2389 if(!(n->curr->flags&HIST_GLITCH))
2390 {
2391 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
2392 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2393 }
2394 }
2395 else
2396 {
2397 he=histent_calloc();
2398 he->time=tim;
2399 he->v.h_vector=vector;
2400
2401 n->curr->next=he;
2402 n->curr=he;
2403 GLOBALS->regions+=regadd;
2404 }
2405 }
2406 else
2407 {
2408 free_2(vector);
2409 }
2410 }
2411 break;
2412 }
2413 }
2414 }
2415
2416 }
2417
2418 /*******************************************************************************/
2419
vcd_build_symbols(void)2420 static void vcd_build_symbols(void)
2421 {
2422 int j;
2423 int max_slen=-1;
2424 struct sym_chain *sym_chain=NULL, *sym_curr=NULL;
2425 int duphier=0;
2426 char hashdirty;
2427 struct vcdsymbol *v, *vprime;
2428 char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */
2429 #ifdef _WAVE_HAVE_JUDY
2430 int ss_len, longest = 0;
2431 #endif
2432
2433 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
2434 while(v)
2435 {
2436 int msi;
2437 int delta;
2438
2439 {
2440 int slen;
2441 int substnode;
2442
2443 msi=v->msi;
2444 delta=((v->lsi-v->msi)<0)?-1:1;
2445 substnode=0;
2446
2447 slen=strlen(v->name);
2448 str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
2449 strcpy(str,v->name);
2450
2451 if((v->msi>=0)||(v->msi != v->lsi))
2452 {
2453 strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
2454 slen++;
2455 }
2456
2457 if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */
2458 {
2459 if(v->size!=vprime->size)
2460 {
2461 fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name);
2462 }
2463 else
2464 {
2465 substnode=1;
2466 }
2467 }
2468
2469 if((v->size==1)&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE))
2470 {
2471 struct symbol *s = NULL;
2472
2473 for(j=0;j<v->size;j++)
2474 {
2475 if(v->msi>=0)
2476 {
2477 if(!GLOBALS->vcd_explicit_zero_subscripts)
2478 sprintf(str+slen,"%d",msi);
2479 else
2480 sprintf(str+slen-1,"[%d]",msi);
2481 }
2482
2483 hashdirty=0;
2484 if(symfind(str, NULL))
2485 {
2486 char *dupfix=(char *)malloc_2(max_slen+32);
2487 #ifndef _WAVE_HAVE_JUDY
2488 hashdirty=1;
2489 #endif
2490 DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2491
2492 do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2493 while(symfind(dupfix, NULL));
2494
2495 strcpy(str, dupfix);
2496 free_2(dupfix);
2497 duphier=0; /* reset for next duplicate resolution */
2498 }
2499 /* fallthrough */
2500 {
2501 s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache);
2502 #ifdef _WAVE_HAVE_JUDY
2503 ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2504 #endif
2505 s->n=v->narray[j];
2506 if(substnode)
2507 {
2508 struct Node *n, *n2;
2509
2510 n=s->n;
2511 n2=vprime->narray[j];
2512 /* nname stays same */
2513 /* n->head=n2->head; */
2514 /* n->curr=n2->curr; */
2515 n->curr=(hptr)n2;
2516 /* harray calculated later */
2517 n->numhist=n2->numhist;
2518 }
2519
2520 #ifndef _WAVE_HAVE_JUDY
2521 s->n->nname=s->name;
2522 #endif
2523 if(!GLOBALS->firstnode)
2524 {
2525 GLOBALS->firstnode=
2526 GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2527 }
2528 else
2529 {
2530 GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2531 GLOBALS->curnode=GLOBALS->curnode->next;
2532 }
2533 GLOBALS->curnode->symbol=s;
2534
2535 GLOBALS->numfacs++;
2536 DEBUG(fprintf(stderr,"Added: %s\n",str));
2537 }
2538 msi+=delta;
2539 }
2540
2541 if((j==1)&&(v->root))
2542 {
2543 s->vec_root=(struct symbol *)v->root; /* these will get patched over */
2544 s->vec_chain=(struct symbol *)v->chain; /* these will get patched over */
2545 v->sym_chain=s;
2546
2547 if(!sym_chain)
2548 {
2549 sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2550 sym_chain=sym_curr;
2551 }
2552 else
2553 {
2554 sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2555 sym_curr=sym_curr->next;
2556 }
2557 sym_curr->val=s;
2558 }
2559 }
2560 else /* atomic vector */
2561 {
2562 if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER))
2563 /* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */
2564 {
2565 sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi);
2566 /* 2d add */
2567 if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
2568 {
2569 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2570 {
2571 v->msi = v->size-1; v->lsi = 0;
2572 }
2573 }
2574 else
2575 if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
2576 {
2577 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2578 {
2579 v->lsi = v->size-1; v->msi = 0;
2580 }
2581 }
2582 }
2583 else
2584 {
2585 *(str+slen-1)=0;
2586 }
2587
2588
2589 hashdirty=0;
2590 if(symfind(str, NULL))
2591 {
2592 char *dupfix=(char *)malloc_2(max_slen+32);
2593 #ifndef _WAVE_HAVE_JUDY
2594 hashdirty=1;
2595 #endif
2596 DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2597
2598 do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2599 while(symfind(dupfix, NULL));
2600
2601 strcpy(str, dupfix);
2602 free_2(dupfix);
2603 duphier=0; /* reset for next duplicate resolution */
2604 }
2605 /* fallthrough */
2606 {
2607 struct symbol *s;
2608
2609 s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); /* cut down on double lookups.. */
2610 #ifdef _WAVE_HAVE_JUDY
2611 ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2612 #endif
2613 s->n=v->narray[0];
2614 if(substnode)
2615 {
2616 struct Node *n, *n2;
2617
2618 n=s->n;
2619 n2=vprime->narray[0];
2620 /* nname stays same */
2621 /* n->head=n2->head; */
2622 /* n->curr=n2->curr; */
2623 n->curr=(hptr)n2;
2624 /* harray calculated later */
2625 n->numhist=n2->numhist;
2626 n->extvals=n2->extvals;
2627 n->msi=n2->msi;
2628 n->lsi=n2->lsi;
2629 }
2630 else
2631 {
2632 s->n->msi=v->msi;
2633 s->n->lsi=v->lsi;
2634
2635 s->n->extvals=1;
2636 }
2637
2638 #ifndef _WAVE_HAVE_JUDY
2639 s->n->nname=s->name;
2640 #endif
2641 if(!GLOBALS->firstnode)
2642 {
2643 GLOBALS->firstnode=
2644 GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2645 }
2646 else
2647 {
2648 GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2649 GLOBALS->curnode=GLOBALS->curnode->next;
2650 }
2651 GLOBALS->curnode->symbol=s;
2652
2653 GLOBALS->numfacs++;
2654 DEBUG(fprintf(stderr,"Added: %s\n",str));
2655 }
2656 }
2657 }
2658
2659 v=v->next;
2660 }
2661
2662 #ifdef _WAVE_HAVE_JUDY
2663 {
2664 Pvoid_t PJArray = GLOBALS->sym_judy;
2665 PPvoid_t PPValue;
2666 char *Index = calloc_2(1, longest);
2667
2668 for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0);
2669 PPValue != (PPvoid_t) NULL;
2670 PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0))
2671 {
2672 struct symbol *s = *(struct symbol **)PPValue;
2673 s->name = strdup_2(Index);
2674 s->n->nname = s->name;
2675 }
2676
2677 free_2(Index);
2678 }
2679 #endif
2680
2681 if(sym_chain)
2682 {
2683 sym_curr=sym_chain;
2684 while(sym_curr)
2685 {
2686 sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain;
2687
2688 if ((struct vcdsymbol *)sym_curr->val->vec_chain)
2689 sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain;
2690
2691 DEBUG(printf("Link: ('%s') '%s' -> '%s'\n",sym_curr->val->vec_root->name, sym_curr->val->name, sym_curr->val->vec_chain?sym_curr->val->vec_chain->name:"(END)"));
2692
2693 sym_chain=sym_curr;
2694 sym_curr=sym_curr->next;
2695 free_2(sym_chain);
2696 }
2697 }
2698 }
2699
2700 /*******************************************************************************/
2701
vcd_cleanup(void)2702 static void vcd_cleanup(void)
2703 {
2704 struct slist *s, *s2;
2705 struct vcdsymbol *v, *vt;
2706
2707 if(GLOBALS->indexed_vcd_recoder_c_3)
2708 {
2709 free_2(GLOBALS->indexed_vcd_recoder_c_3); GLOBALS->indexed_vcd_recoder_c_3=NULL;
2710 }
2711
2712 if(GLOBALS->sorted_vcd_recoder_c_3)
2713 {
2714 free_2(GLOBALS->sorted_vcd_recoder_c_3); GLOBALS->sorted_vcd_recoder_c_3=NULL;
2715 }
2716
2717 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
2718 while(v)
2719 {
2720 if(v->name) free_2(v->name);
2721 if(v->id) free_2(v->id);
2722 if(v->narray) free_2(v->narray);
2723 vt=v;
2724 v=v->next;
2725 free_2(vt);
2726 }
2727 GLOBALS->vcdsymroot_vcd_recoder_c_3=GLOBALS->vcdsymcurr_vcd_recoder_c_3=NULL;
2728
2729 if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; }
2730 s=GLOBALS->slistroot;
2731 while(s)
2732 {
2733 s2=s->next;
2734 if(s->str)free_2(s->str);
2735 free_2(s);
2736 s=s2;
2737 }
2738
2739 GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0;
2740
2741 if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2)
2742 {
2743 pclose(GLOBALS->vcd_handle_vcd_recoder_c_2);
2744 GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL;
2745 }
2746 else
2747 {
2748 fclose(GLOBALS->vcd_handle_vcd_recoder_c_2);
2749 GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL;
2750 }
2751
2752 if(GLOBALS->yytext_vcd_recoder_c_3)
2753 {
2754 free_2(GLOBALS->yytext_vcd_recoder_c_3);
2755 GLOBALS->yytext_vcd_recoder_c_3=NULL;
2756 }
2757 }
2758
2759 /*******************************************************************************/
2760
vcd_recoder_main(char * fname)2761 TimeType vcd_recoder_main(char *fname)
2762 {
2763 unsigned int finalize_cnt = 0;
2764 #ifdef HAVE_SYS_STAT_H
2765 struct stat mystat;
2766 int stat_rc = stat(fname, &mystat);
2767 #endif
2768
2769 GLOBALS->pv_vcd_recoder_c_3=GLOBALS->rootv_vcd_recoder_c_3=NULL;
2770 GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter;
2771
2772 if(GLOBALS->use_fastload)
2773 {
2774 char *ffname = malloc_2(strlen(fname) + 4 + 1);
2775 sprintf(ffname, "%s.idx", fname);
2776
2777 GLOBALS->vlist_handle = fopen(ffname, "rb");
2778 if(GLOBALS->vlist_handle)
2779 {
2780 GLOBALS->use_fastload = VCD_FSL_READ;
2781
2782 /* need to do a sanity check looking for time of vcd file vs recoder file, etc. */
2783 #ifdef HAVE_SYS_STAT_H
2784 if( (stat_rc) || (!read_fastload_header(&mystat)) )
2785 #else
2786 if(!read_fastload_header())
2787 #endif
2788 {
2789 GLOBALS->use_fastload = VCD_FSL_WRITE;
2790 fclose(GLOBALS->vlist_handle);
2791 GLOBALS->vlist_handle = NULL;
2792 }
2793 }
2794 else
2795 {
2796 GLOBALS->use_fastload = VCD_FSL_WRITE;
2797 }
2798
2799 free_2(ffname);
2800 }
2801
2802 errno=0; /* reset in case it's set for some reason */
2803
2804 GLOBALS->yytext_vcd_recoder_c_3=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_recoder_c_3+1);
2805
2806 if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */
2807 {
2808 GLOBALS->hier_delimeter='.';
2809 }
2810
2811 if(suffix_check(fname, ".gz") || suffix_check(fname, ".zip"))
2812 {
2813 char *str;
2814 int dlen;
2815 dlen=strlen(WAVE_DECOMPRESSOR);
2816 str=wave_alloca(strlen(fname)+dlen+1);
2817 strcpy(str,WAVE_DECOMPRESSOR);
2818 strcpy(str+dlen,fname);
2819 GLOBALS->vcd_handle_vcd_recoder_c_2=popen(str,"r");
2820 GLOBALS->vcd_is_compressed_vcd_recoder_c_2=~0;
2821 }
2822 else
2823 {
2824 if(strcmp("-vcd",fname))
2825 {
2826 GLOBALS->vcd_handle_vcd_recoder_c_2=fopen(fname,"rb");
2827
2828 if(GLOBALS->vcd_handle_vcd_recoder_c_2)
2829 {
2830 fseeko(GLOBALS->vcd_handle_vcd_recoder_c_2, 0, SEEK_END); /* do status bar for vcd load */
2831 GLOBALS->vcd_fsiz_vcd_recoder_c_2 = ftello(GLOBALS->vcd_handle_vcd_recoder_c_2);
2832 fseeko(GLOBALS->vcd_handle_vcd_recoder_c_2, 0, SEEK_SET);
2833 }
2834
2835 if(GLOBALS->vcd_warning_filesize < 0) GLOBALS->vcd_warning_filesize = VCD_SIZE_WARN;
2836
2837 if(GLOBALS->vcd_warning_filesize)
2838 if(GLOBALS->vcd_fsiz_vcd_recoder_c_2 > (GLOBALS->vcd_warning_filesize * (1024 * 1024)))
2839 {
2840 if(!GLOBALS->vlist_prepack)
2841 {
2842 fprintf(stderr, "Warning! File size is %d MB. This might fail in recoding.\n"
2843 "Consider converting it to the FST database format instead. (See the\n"
2844 "vcd2fst(1) manpage for more information.)\n"
2845 "To disable this warning, set rc variable vcd_warning_filesize to zero.\n"
2846 "Alternatively, use the -o, --optimize command line option to convert to FST\n"
2847 "or the -g, --giga command line option to use dynamically compressed memory.\n\n",
2848 (int)(GLOBALS->vcd_fsiz_vcd_recoder_c_2/(1024*1024)));
2849 }
2850 else
2851 {
2852 fprintf(stderr, "VCDLOAD | File size is %d MB, using vlist prepacking%s.\n\n",
2853 (int)(GLOBALS->vcd_fsiz_vcd_recoder_c_2/(1024*1024)),
2854 GLOBALS->vlist_spill_to_disk ? " and spill file" : "");
2855 }
2856 }
2857 }
2858 else
2859 {
2860 GLOBALS->splash_disable = 1;
2861 GLOBALS->vcd_handle_vcd_recoder_c_2=stdin;
2862 }
2863 GLOBALS->vcd_is_compressed_vcd_recoder_c_2=0;
2864 }
2865
2866 if(!GLOBALS->vcd_handle_vcd_recoder_c_2)
2867 {
2868 fprintf(stderr, "Error opening %s .vcd file '%s'.\n",
2869 GLOBALS->vcd_is_compressed_vcd_recoder_c_2?"compressed":"", fname);
2870 perror("Why");
2871 vcd_exit(255);
2872 }
2873
2874 /* SPLASH */ splash_create();
2875
2876 sym_hash_initialize(GLOBALS);
2877 getch_alloc(); /* alloc membuff for vcd getch buffer */
2878
2879 build_slisthier();
2880
2881 GLOBALS->time_vlist_vcd_recoder_c_1 = vlist_create(sizeof(TimeType));
2882
2883 if(GLOBALS->use_fastload == VCD_FSL_WRITE)
2884 {
2885 GLOBALS->time_vlist_vcd_recoder_write = ((struct vlist_t *)vlist_packer_create());
2886 }
2887
2888 if((GLOBALS->vlist_spill_to_disk) && (GLOBALS->use_fastload != VCD_FSL_READ))
2889 {
2890 vlist_init_spillfile();
2891 }
2892
2893 vcd_parse();
2894 if(GLOBALS->varsplit_vcd_recoder_c_3)
2895 {
2896 free_2(GLOBALS->varsplit_vcd_recoder_c_3);
2897 GLOBALS->varsplit_vcd_recoder_c_3=NULL;
2898 }
2899
2900 if(GLOBALS->vlist_handle)
2901 {
2902 FILE *vh = GLOBALS->vlist_handle;
2903 GLOBALS->vlist_handle = NULL;
2904 vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_c_1);
2905 GLOBALS->vlist_handle = vh;
2906 }
2907 else
2908 {
2909 vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_c_1);
2910 }
2911
2912 if(GLOBALS->time_vlist_vcd_recoder_write)
2913 {
2914 write_fastload_time_section();
2915 }
2916
2917 if(GLOBALS->use_fastload != VCD_FSL_READ)
2918 {
2919 finalize_cnt = vlist_emit_finalize();
2920 }
2921
2922 if(GLOBALS->time_vlist_vcd_recoder_write)
2923 {
2924 #ifdef HAVE_SYS_STAT_H
2925 write_fastload_header(&mystat, finalize_cnt);
2926 #else
2927 write_fastload_header(finalize_cnt);
2928 #endif
2929 }
2930
2931
2932 if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3))
2933 {
2934 fprintf(stderr, "No symbols in VCD file..is it malformed? Exiting!\n");
2935 vcd_exit(255);
2936 }
2937
2938 if(GLOBALS->vcd_save_handle) { fclose(GLOBALS->vcd_save_handle); GLOBALS->vcd_save_handle = NULL; }
2939
2940 fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->start_time_vcd_recoder_c_3*GLOBALS->time_scale, GLOBALS->end_time_vcd_recoder_c_3*GLOBALS->time_scale);
2941
2942 if(GLOBALS->vcd_fsiz_vcd_recoder_c_2)
2943 {
2944 splash_sync(GLOBALS->vcd_fsiz_vcd_recoder_c_2, GLOBALS->vcd_fsiz_vcd_recoder_c_2);
2945 GLOBALS->vcd_fsiz_vcd_recoder_c_2 = 0;
2946 }
2947 else
2948 if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2)
2949 {
2950 splash_sync(1,1);
2951 GLOBALS->vcd_fsiz_vcd_recoder_c_2 = 0;
2952 }
2953
2954 GLOBALS->min_time=GLOBALS->start_time_vcd_recoder_c_3*GLOBALS->time_scale;
2955 GLOBALS->max_time=GLOBALS->end_time_vcd_recoder_c_3*GLOBALS->time_scale;
2956 GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale;
2957
2958 if((GLOBALS->min_time==GLOBALS->max_time)&&(GLOBALS->max_time==LLDescriptor(-1)))
2959 {
2960 fprintf(stderr, "VCD times range is equal to zero. Exiting.\n");
2961 vcd_exit(255);
2962 }
2963
2964 vcd_build_symbols();
2965 vcd_sortfacs();
2966 vcd_cleanup();
2967
2968 getch_free(); /* free membuff for vcd getch buffer */
2969
2970
2971 if(GLOBALS->blackout_regions)
2972 {
2973 struct blackout_region_t *bt = GLOBALS->blackout_regions;
2974 while(bt)
2975 {
2976 bt->bstart *= GLOBALS->time_scale;
2977 bt->bend *= GLOBALS->time_scale;
2978 bt = bt->next;
2979 }
2980 }
2981
2982 /* is_vcd=~0; */
2983 GLOBALS->is_lx2 = LXT2_IS_VLIST;
2984
2985 /* SPLASH */ splash_finalize();
2986 return(GLOBALS->max_time);
2987 }
2988
2989 /*******************************************************************************/
2990
vcd_import_masked(void)2991 void vcd_import_masked(void)
2992 {
2993 /* nothing */
2994 }
2995
vcd_set_fac_process_mask(nptr np)2996 void vcd_set_fac_process_mask(nptr np)
2997 {
2998 if(np && np->mv.mvlfac_vlist)
2999 {
3000 import_vcd_trace(np);
3001 }
3002 }
3003
3004
3005 #define vlist_locate_import(x,y) ((GLOBALS->vlist_prepack) ? ((depacked) + (y)) : vlist_locate((x),(y)))
3006
import_vcd_trace(nptr np)3007 void import_vcd_trace(nptr np)
3008 {
3009 struct vlist_t *v = np->mv.mvlfac_vlist;
3010 int len = 1;
3011 unsigned int list_size;
3012 unsigned char vlist_type;
3013 /* unsigned int vartype = 0; */ /* scan-build */
3014 unsigned int vlist_pos = 0;
3015 unsigned char *chp;
3016 unsigned int time_idx = 0;
3017 TimeType *curtime_pnt;
3018 unsigned char arr[5];
3019 int arr_pos;
3020 unsigned int accum;
3021 unsigned char ch;
3022 double *d;
3023 unsigned char *depacked = NULL;
3024
3025 if(!v) return;
3026 vlist_uncompress(&v);
3027
3028 if(GLOBALS->vlist_prepack)
3029 {
3030 depacked = vlist_packer_decompress(v, &list_size);
3031 vlist_destroy(v);
3032 }
3033 else
3034 {
3035 list_size=vlist_size(v);
3036 }
3037
3038 if(!list_size)
3039 {
3040 len = 1;
3041 vlist_type = '!'; /* possible alias */
3042 }
3043 else
3044 {
3045 chp = vlist_locate_import(v, vlist_pos++);
3046 if(chp)
3047 {
3048 switch((vlist_type = (*chp & 0x7f)))
3049 {
3050 case '0':
3051 len = 1;
3052 chp = vlist_locate_import(v, vlist_pos++);
3053 if(!chp)
3054 {
3055 fprintf(stderr, "Internal error file '%s' line %d, exiting.\n", __FILE__, __LINE__);
3056 exit(255);
3057 }
3058 /* vartype = (unsigned int)(*chp & 0x7f); */ /*scan-build */
3059 break;
3060
3061 case 'B':
3062 case 'R':
3063 case 'S':
3064 chp = vlist_locate_import(v, vlist_pos++);
3065 if(!chp)
3066 {
3067 fprintf(stderr, "Internal error file '%s' line %d, exiting.\n", __FILE__, __LINE__);
3068 exit(255);
3069 }
3070 /* vartype = (unsigned int)(*chp & 0x7f); */ /* scan-build */
3071
3072 arr_pos = accum = 0;
3073
3074 do {
3075 chp = vlist_locate_import(v, vlist_pos++);
3076 if(!chp) break;
3077 ch = *chp;
3078 arr[arr_pos++] = ch;
3079 } while (!(ch & 0x80));
3080
3081 for(--arr_pos; arr_pos>=0; arr_pos--)
3082 {
3083 ch = arr[arr_pos];
3084 accum <<= 7;
3085 accum |= (unsigned int)(ch & 0x7f);
3086 }
3087
3088 len = accum;
3089
3090 break;
3091
3092 default:
3093 fprintf(stderr, "Unsupported vlist type '%c', exiting.", vlist_type);
3094 vcd_exit(255);
3095 break;
3096 }
3097 }
3098 else
3099 {
3100 len = 1;
3101 vlist_type = '!'; /* possible alias */
3102 }
3103 }
3104
3105
3106 if(vlist_type == '0') /* single bit */
3107 {
3108 while(vlist_pos < list_size)
3109 {
3110 unsigned int delta, bitval;
3111 char ascval;
3112
3113 arr_pos = accum = 0;
3114
3115 do {
3116 chp = vlist_locate_import(v, vlist_pos++);
3117 if(!chp) break;
3118 ch = *chp;
3119 arr[arr_pos++] = ch;
3120 } while (!(ch & 0x80));
3121
3122 for(--arr_pos; arr_pos>=0; arr_pos--)
3123 {
3124 ch = arr[arr_pos];
3125 accum <<= 7;
3126 accum |= (unsigned int)(ch & 0x7f);
3127 }
3128
3129 if(!(accum&1))
3130 {
3131 delta = accum >> 2;
3132 bitval = (accum >> 1) & 1;
3133 ascval = '0' + bitval;
3134 }
3135 else
3136 {
3137 delta = accum >> 4;
3138 bitval = (accum >> 1) & 7;
3139 ascval = RCV_STR[bitval];
3140 }
3141 time_idx += delta;
3142
3143 curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0);
3144 if(!curtime_pnt)
3145 {
3146 fprintf(stderr, "GTKWAVE | malformed bitwise signal data for '%s' after time_idx = %d\n",
3147 np->nname, time_idx - delta);
3148 exit(255);
3149 }
3150
3151 add_histent(*curtime_pnt,np,ascval,1, NULL);
3152 }
3153
3154 add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, NULL);
3155 add_histent(MAX_HISTENT_TIME, np, 'z', 0, NULL);
3156 }
3157 else if(vlist_type == 'B') /* bit vector, port type was converted to bit vector already */
3158 {
3159 char *sbuf = malloc_2(len+1);
3160 int dst_len;
3161 char *vector;
3162
3163 while(vlist_pos < list_size)
3164 {
3165 unsigned int delta;
3166
3167 arr_pos = accum = 0;
3168
3169 do {
3170 chp = vlist_locate_import(v, vlist_pos++);
3171 if(!chp) break;
3172 ch = *chp;
3173 arr[arr_pos++] = ch;
3174 } while (!(ch & 0x80));
3175
3176 for(--arr_pos; arr_pos>=0; arr_pos--)
3177 {
3178 ch = arr[arr_pos];
3179 accum <<= 7;
3180 accum |= (unsigned int)(ch & 0x7f);
3181 }
3182
3183 delta = accum;
3184 time_idx += delta;
3185
3186 curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0);
3187 if(!curtime_pnt)
3188 {
3189 fprintf(stderr, "GTKWAVE | malformed 'b' signal data for '%s' after time_idx = %d\n",
3190 np->nname, time_idx - delta);
3191 exit(255);
3192 }
3193
3194 dst_len = 0;
3195 for(;;)
3196 {
3197 chp = vlist_locate_import(v, vlist_pos++);
3198 if(!chp) break;
3199 ch = *chp;
3200 if((ch >> 4) == AN_MSK) break;
3201 if(dst_len == len) { if(len != 1) memmove(sbuf, sbuf+1, dst_len - 1); dst_len--; }
3202 sbuf[dst_len++] = AN_STR[ch >> 4];
3203 if((ch & AN_MSK) == AN_MSK) break;
3204 if(dst_len == len) { if(len != 1) memmove(sbuf, sbuf+1, dst_len - 1); dst_len--; }
3205 sbuf[dst_len++] = AN_STR[ch & AN_MSK];
3206 }
3207
3208 if(len == 1)
3209 {
3210 add_histent(*curtime_pnt, np,sbuf[0],1, NULL);
3211 }
3212 else
3213 {
3214 vector = malloc_2(len+1);
3215 if(dst_len < len)
3216 {
3217 unsigned char extend=(sbuf[0]=='1')?'0':sbuf[0];
3218 memset(vector, extend, len - dst_len);
3219 memcpy(vector + (len - dst_len), sbuf, dst_len);
3220 }
3221 else
3222 {
3223 memcpy(vector, sbuf, len);
3224 }
3225
3226 vector[len] = 0;
3227 add_histent(*curtime_pnt, np,0,1,vector);
3228 }
3229 }
3230
3231 if(len==1)
3232 {
3233 add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, NULL);
3234 add_histent(MAX_HISTENT_TIME, np, 'z', 0, NULL);
3235 }
3236 else
3237 {
3238 add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, (char *)calloc_2(1,sizeof(char)));
3239 add_histent(MAX_HISTENT_TIME, np, 'z', 0, (char *)calloc_2(1,sizeof(char)));
3240 }
3241
3242 free_2(sbuf);
3243 }
3244 else if(vlist_type == 'R') /* real */
3245 {
3246 char *sbuf = malloc_2(64);
3247 int dst_len;
3248 char *vector;
3249
3250 while(vlist_pos < list_size)
3251 {
3252 unsigned int delta;
3253
3254 arr_pos = accum = 0;
3255
3256 do {
3257 chp = vlist_locate_import(v, vlist_pos++);
3258 if(!chp) break;
3259 ch = *chp;
3260 arr[arr_pos++] = ch;
3261 } while (!(ch & 0x80));
3262
3263 for(--arr_pos; arr_pos>=0; arr_pos--)
3264 {
3265 ch = arr[arr_pos];
3266 accum <<= 7;
3267 accum |= (unsigned int)(ch & 0x7f);
3268 }
3269
3270 delta = accum;
3271 time_idx += delta;
3272
3273 curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0);
3274 if(!curtime_pnt)
3275 {
3276 fprintf(stderr, "GTKWAVE | malformed 'r' signal data for '%s' after time_idx = %d\n",
3277 np->nname, time_idx - delta);
3278 exit(255);
3279 }
3280
3281 dst_len = 0;
3282 do
3283 {
3284 chp = vlist_locate_import(v, vlist_pos++);
3285 if(!chp) break;
3286 ch = *chp;
3287 sbuf[dst_len++] = ch;
3288 } while(ch);
3289
3290 vector=malloc_2(sizeof(double));
3291 sscanf(sbuf,"%lg",(double *)vector);
3292 add_histent(*curtime_pnt, np,'g',1,(char *)vector);
3293 }
3294
3295 d=malloc_2(sizeof(double));
3296 *d=1.0;
3297 add_histent(MAX_HISTENT_TIME-1, np, 'g', 0, (char *)d);
3298
3299 d=malloc_2(sizeof(double));
3300 *d=0.0;
3301 add_histent(MAX_HISTENT_TIME, np, 'g', 0, (char *)d);
3302
3303 free_2(sbuf);
3304 }
3305 else if(vlist_type == 'S') /* string */
3306 {
3307 char *sbuf = malloc_2(list_size); /* being conservative */
3308 int dst_len;
3309 char *vector;
3310
3311 while(vlist_pos < list_size)
3312 {
3313 unsigned int delta;
3314
3315 arr_pos = accum = 0;
3316
3317 do {
3318 chp = vlist_locate_import(v, vlist_pos++);
3319 if(!chp) break;
3320 ch = *chp;
3321 arr[arr_pos++] = ch;
3322 } while (!(ch & 0x80));
3323
3324 for(--arr_pos; arr_pos>=0; arr_pos--)
3325 {
3326 ch = arr[arr_pos];
3327 accum <<= 7;
3328 accum |= (unsigned int)(ch & 0x7f);
3329 }
3330
3331 delta = accum;
3332 time_idx += delta;
3333
3334 curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0);
3335 if(!curtime_pnt)
3336 {
3337 fprintf(stderr, "GTKWAVE | malformed 's' signal data for '%s' after time_idx = %d\n",
3338 np->nname, time_idx - delta);
3339 exit(255);
3340 }
3341
3342 dst_len = 0;
3343 do
3344 {
3345 chp = vlist_locate_import(v, vlist_pos++);
3346 if(!chp) break;
3347 ch = *chp;
3348 sbuf[dst_len++] = ch;
3349 } while(ch);
3350
3351 vector=malloc_2(dst_len + 1);
3352 strcpy(vector, sbuf);
3353 add_histent(*curtime_pnt, np,'s',1,(char *)vector);
3354 }
3355
3356 d=malloc_2(sizeof(double));
3357 *d=1.0;
3358 add_histent(MAX_HISTENT_TIME-1, np, 'g', 0, (char *)d);
3359
3360 d=malloc_2(sizeof(double));
3361 *d=0.0;
3362 add_histent(MAX_HISTENT_TIME, np, 'g', 0, (char *)d);
3363
3364 free_2(sbuf);
3365 }
3366 else if(vlist_type == '!') /* error in loading */
3367 {
3368 nptr n2 = (nptr)np->curr;
3369
3370 if((n2)&&(n2 != np)) /* keep out any possible infinite recursion from corrupt pointer bugs */
3371 {
3372 import_vcd_trace(n2);
3373
3374 if(GLOBALS->vlist_prepack)
3375 {
3376 vlist_packer_decompress_destroy((char *)depacked);
3377 }
3378 else
3379 {
3380 vlist_destroy(v);
3381 }
3382 np->mv.mvlfac_vlist = NULL;
3383
3384 np->head = n2->head;
3385 np->curr = n2->curr;
3386 return;
3387 }
3388
3389 fprintf(stderr, "Error in decompressing vlist for '%s', exiting.\n", np->nname);
3390 vcd_exit(255);
3391 }
3392
3393 if(GLOBALS->vlist_prepack)
3394 {
3395 vlist_packer_decompress_destroy((char *)depacked);
3396 }
3397 else
3398 {
3399 vlist_destroy(v);
3400 }
3401 np->mv.mvlfac_vlist = NULL;
3402 }
3403
3404