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 partial loader support 04aug06ajb
27 * added real_parameter vartype 04aug06ajb
28 * added in/out port vartype 31jan07ajb
29 * use gperf for port vartypes 19feb07ajb
30 * MTI SV implicit-var fix 05apr07ajb
31 * MTI SV len=0 is real var 05apr07ajb
32 */
33 #include <config.h>
34 #include "globals.h"
35 #include "vcd.h"
36 #include "hierpack.h"
37
38 #if !defined _MSC_VER && !defined __MINGW32__
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #endif
43
44 #ifdef __MINGW32__
45 #include <windows.h>
46 #endif
47
48 #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */
49
50 static hptr add_histent_p(TimeType time, struct Node *n, char ch, int regadd, char *vector);
51 static void add_tail_histents(void);
52 static void vcd_build_symbols(void);
53 static void vcd_cleanup(void);
54 static void evcd_strcpy(char *dst, char *src);
55
56
57
58
59
60 /*******************************************************************************/
61
62 #define WAVE_PARTIAL_VCD_RING_BUFFER_SIZE (1024*1024)
63
64
get_8(char * p)65 unsigned int get_8(char *p)
66 {
67 if(p >= (GLOBALS->buf_vcd_partial_c_2 + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE))
68 {
69 p-= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE;
70 }
71
72 return((unsigned int)((unsigned char)*p));
73 }
74
get_32(char * p)75 unsigned int get_32(char *p)
76 {
77 unsigned int rc;
78 rc = (get_8(p++) << 24) ;
79 rc|= (get_8(p++) << 16) ;
80 rc|= (get_8(p++) << 8) ;
81 rc|= (get_8(p) << 0) ;
82
83 return(rc);
84 }
85
86
consume(void)87 int consume(void) /* for testing only */
88 {
89 int len;
90
91 GLOBALS->consume_countdown_vcd_partial_c_1--;
92 if(!GLOBALS->consume_countdown_vcd_partial_c_1)
93 {
94 GLOBALS->consume_countdown_vcd_partial_c_1 = 100000;
95 return(0);
96 }
97
98 if((len = *GLOBALS->consume_ptr_vcd_partial_c_1))
99 {
100 int i;
101
102 len = get_32(GLOBALS->consume_ptr_vcd_partial_c_1+1);
103 for(i=0;i<len;i++)
104 {
105 GLOBALS->vcdbuf_vcd_partial_c_2[i] = get_8(GLOBALS->consume_ptr_vcd_partial_c_1+i+5);
106 }
107 GLOBALS->vcdbuf_vcd_partial_c_2[i] = 0;
108
109 *GLOBALS->consume_ptr_vcd_partial_c_1 = 0;
110 GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->consume_ptr_vcd_partial_c_1+i+5;
111 if(GLOBALS->consume_ptr_vcd_partial_c_1 >= (GLOBALS->buf_vcd_partial_c_2 + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE))
112 {
113 GLOBALS->consume_ptr_vcd_partial_c_1 -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE;
114 }
115 }
116
117 return(len);
118 }
119
120
121 /******************************************************************/
122
123 enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE,
124 T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON,
125 T_DUMPVARS, T_ENDDEFINITIONS,
126 T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL,
127 T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO,
128 T_EOF, T_STRING, T_UNKNOWN_KEY };
129
130 static char *tokens[]={ "var", "end", "scope", "upscope",
131 "comment", "date", "dumpall", "dumpoff", "dumpon",
132 "dumpvars", "enddefinitions",
133 "dumpports", "dumpportsoff", "dumpportson", "dumpportsall",
134 "timescale", "version", "vcdclose", "timezero",
135 "", "", "" };
136
137
138 #define NUM_TOKENS 19
139
140
141 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break;
142
143 /******************************************************************/
144
145 #define NUM_VTOKENS 23
146
147 /******************************************************************/
148
149
vcdid_hash(char * s,int len)150 static unsigned int vcdid_hash(char *s, int len)
151 {
152 unsigned int val=0;
153 int i;
154
155 s+=(len-1);
156
157 for(i=0;i<len;i++)
158 {
159 val *= 94;
160 val += (((unsigned char)*s) - 32);
161 s--;
162 }
163
164 return(val);
165 }
166
167 /******************************************************************/
168
169 /*
170 * bsearch compare
171 */
vcdsymbsearchcompare(const void * s1,const void * s2)172 static int vcdsymbsearchcompare(const void *s1, const void *s2)
173 {
174 char *v1;
175 struct vcdsymbol *v2;
176
177 v1=(char *)s1;
178 v2=*((struct vcdsymbol **)s2);
179
180 return(strcmp(v1, v2->id));
181 }
182
183
184 /*
185 * actual bsearch
186 */
bsearch_vcd(char * key,int len)187 static struct vcdsymbol *bsearch_vcd(char *key, int len)
188 {
189 struct vcdsymbol **v;
190 struct vcdsymbol *t;
191
192 if(GLOBALS->indexed_vcd_partial_c_2)
193 {
194 unsigned int hsh = vcdid_hash(key, len);
195 if((hsh>=GLOBALS->vcd_minid_vcd_partial_c_2)&&(hsh<=GLOBALS->vcd_maxid_vcd_partial_c_2))
196 {
197 return(GLOBALS->indexed_vcd_partial_c_2[hsh-GLOBALS->vcd_minid_vcd_partial_c_2]);
198 }
199
200 return(NULL);
201 }
202
203 if(GLOBALS->sorted_vcd_partial_c_2)
204 {
205 v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_partial_c_2, GLOBALS->numsyms_vcd_partial_c_2,
206 sizeof(struct vcdsymbol *), vcdsymbsearchcompare);
207
208 if(v)
209 {
210 #ifndef VCD_BSEARCH_IS_PERFECT
211 for(;;)
212 {
213 t=*v;
214
215 if((v==GLOBALS->sorted_vcd_partial_c_2)||(strcmp((*(--v))->id, key)))
216 {
217 return(t);
218 }
219 }
220 #else
221 return(*v);
222 #endif
223 }
224 else
225 {
226 return(NULL);
227 }
228 }
229 else
230 {
231 if(!GLOBALS->err_vcd_partial_c_2)
232 {
233 fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
234 GLOBALS->err_vcd_partial_c_2=1;
235 }
236 return(NULL);
237 }
238 }
239
240
241 /*
242 * sort on vcdsymbol pointers
243 */
vcdsymcompare(const void * s1,const void * s2)244 static int vcdsymcompare(const void *s1, const void *s2)
245 {
246 struct vcdsymbol *v1, *v2;
247
248 v1=*((struct vcdsymbol **)s1);
249 v2=*((struct vcdsymbol **)s2);
250
251 return(strcmp(v1->id, v2->id));
252 }
253
254
255 /*
256 * create sorted (by id) table
257 */
create_sorted_table(void)258 static void create_sorted_table(void)
259 {
260 struct vcdsymbol *v;
261 struct vcdsymbol **pnt;
262 unsigned int vcd_distance;
263
264 if(GLOBALS->sorted_vcd_partial_c_2)
265 {
266 free_2(GLOBALS->sorted_vcd_partial_c_2); /* this means we saw a 2nd enddefinition chunk! */
267 GLOBALS->sorted_vcd_partial_c_2=NULL;
268 }
269
270 if(GLOBALS->indexed_vcd_partial_c_2)
271 {
272 free_2(GLOBALS->indexed_vcd_partial_c_2);
273 GLOBALS->indexed_vcd_partial_c_2=NULL;
274 }
275
276 if(GLOBALS->numsyms_vcd_partial_c_2)
277 {
278 vcd_distance = GLOBALS->vcd_maxid_vcd_partial_c_2 - GLOBALS->vcd_minid_vcd_partial_c_2 + 1;
279
280 if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill))
281 {
282 GLOBALS->indexed_vcd_partial_c_2 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *));
283
284 /* printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); */
285
286 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
287 while(v)
288 {
289 if(!GLOBALS->indexed_vcd_partial_c_2[v->nid - GLOBALS->vcd_minid_vcd_partial_c_2]) GLOBALS->indexed_vcd_partial_c_2[v->nid - GLOBALS->vcd_minid_vcd_partial_c_2] = v;
290 v=v->next;
291 }
292 }
293 else
294 {
295 pnt=GLOBALS->sorted_vcd_partial_c_2=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *));
296 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
297 while(v)
298 {
299 *(pnt++)=v;
300 v=v->next;
301 }
302
303 qsort(GLOBALS->sorted_vcd_partial_c_2, GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *), vcdsymcompare);
304 }
305 }
306 }
307
308 /******************************************************************/
309
310 /*
311 * single char get inlined/optimized
312 */
getch_alloc(void)313 static void getch_alloc(void)
314 {
315 GLOBALS->vend_vcd_partial_c_2=GLOBALS->vst_vcd_partial_c_2=GLOBALS->vcdbuf_vcd_partial_c_2=(char *)calloc_2(1,VCD_BSIZ);
316 }
317
318
getch_fetch(void)319 static int getch_fetch(void)
320 {
321 size_t rd;
322
323 errno = 0;
324
325 GLOBALS->vcdbyteno_vcd_partial_c_2+=(GLOBALS->vend_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2);
326 rd=consume();
327 GLOBALS->vend_vcd_partial_c_2=(GLOBALS->vst_vcd_partial_c_2=GLOBALS->vcdbuf_vcd_partial_c_2)+rd;
328
329 if(!rd) return(-1);
330
331 return((int)(*GLOBALS->vst_vcd_partial_c_2));
332 }
333
getch(void)334 static inline signed char getch(void) {
335 signed char ch = ((GLOBALS->vst_vcd_partial_c_2!=GLOBALS->vend_vcd_partial_c_2)?((int)(*GLOBALS->vst_vcd_partial_c_2)):(getch_fetch()));
336 if(ch>=0) { GLOBALS->vst_vcd_partial_c_2++; };
337 return(ch);
338 }
339
getch_peek(void)340 static inline signed char getch_peek(void) {
341 signed char ch = ((GLOBALS->vst_vcd_partial_c_2!=GLOBALS->vend_vcd_partial_c_2)?((int)(*GLOBALS->vst_vcd_partial_c_2)):(getch_fetch()));
342 /* no increment */
343 return(ch);
344 }
345
346
getch_patched(void)347 static int getch_patched(void)
348 {
349 char ch;
350
351 ch=*GLOBALS->vsplitcurr_vcd_partial_c_2;
352 if(!ch)
353 {
354 return(-1);
355 }
356 else
357 {
358 GLOBALS->vsplitcurr_vcd_partial_c_2++;
359 return((int)ch);
360 }
361 }
362
363 /*
364 * simple tokenizer
365 */
get_token(void)366 static int get_token(void)
367 {
368 int ch;
369 int i, len=0;
370 int is_string=0;
371 char *yyshadow;
372
373 for(;;)
374 {
375 ch=getch();
376 if(ch<0) return(T_EOF);
377 if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */
378 break; /* (take advantage of fact that vcd is text) */
379 }
380 if(ch=='$')
381 {
382 GLOBALS->yytext_vcd_partial_c_2[len++]=ch;
383 for(;;)
384 {
385 ch=getch();
386 if(ch<0) return(T_EOF);
387 if(ch<=' ') continue;
388 break;
389 }
390 }
391 else
392 {
393 is_string=1;
394 }
395
396 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
397 {
398 if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
399 {
400 GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
401 }
402 ch=getch();
403 if(ch<=' ') break;
404 }
405 GLOBALS->yytext_vcd_partial_c_2[len]=0; /* terminator */
406
407 if(is_string)
408 {
409 GLOBALS->yylen_vcd_partial_c_2=len;
410 return(T_STRING);
411 }
412
413 yyshadow=GLOBALS->yytext_vcd_partial_c_2;
414 do
415 {
416 yyshadow++;
417 for(i=0;i<NUM_TOKENS;i++)
418 {
419 if(!strcmp(yyshadow,tokens[i]))
420 {
421 return(i);
422 }
423 }
424
425 } while(*yyshadow=='$'); /* fix for RCS ids in version strings */
426
427 return(T_UNKNOWN_KEY);
428 }
429
430
get_vartoken_patched(int match_kw)431 static int get_vartoken_patched(int match_kw)
432 {
433 int ch;
434 int len=0;
435
436 if(!GLOBALS->var_prevch_vcd_partial_c_2)
437 {
438 for(;;)
439 {
440 ch=getch_patched();
441 if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; return(V_END); }
442 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
443 break;
444 }
445 }
446 else
447 {
448 ch=GLOBALS->var_prevch_vcd_partial_c_2;
449 GLOBALS->var_prevch_vcd_partial_c_2=0;
450 }
451
452 if(ch=='[') return(V_LB);
453 if(ch==':') return(V_COLON);
454 if(ch==']') return(V_RB);
455
456 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
457 {
458 if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
459 {
460 GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
461 }
462 ch=getch_patched();
463 if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; break; }
464 if((ch==':')||(ch==']'))
465 {
466 GLOBALS->var_prevch_vcd_partial_c_2=ch;
467 break;
468 }
469 }
470 GLOBALS->yytext_vcd_partial_c_2[len]=0; /* terminator */
471
472 if(match_kw)
473 {
474 int vt = vcd_keyword_code(GLOBALS->yytext_vcd_partial_c_2, len);
475 if(vt != V_STRING)
476 {
477 if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; }
478 return(vt);
479 }
480 }
481
482 GLOBALS->yylen_vcd_partial_c_2=len;
483 if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; }
484 return(V_STRING);
485 }
486
get_vartoken(int match_kw)487 static int get_vartoken(int match_kw)
488 {
489 int ch;
490 int len=0;
491
492 if(GLOBALS->varsplit_vcd_partial_c_2)
493 {
494 int rc=get_vartoken_patched(match_kw);
495 if(rc!=V_END) return(rc);
496 GLOBALS->var_prevch_vcd_partial_c_2=0;
497 }
498
499 if(!GLOBALS->var_prevch_vcd_partial_c_2)
500 {
501 for(;;)
502 {
503 ch=getch();
504 if(ch<0) return(V_END);
505 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
506 break;
507 }
508 }
509 else
510 {
511 ch=GLOBALS->var_prevch_vcd_partial_c_2;
512 GLOBALS->var_prevch_vcd_partial_c_2=0;
513 }
514
515 if(ch=='[') return(V_LB);
516 if(ch==':') return(V_COLON);
517 if(ch==']') return(V_RB);
518
519 if(ch=='#') /* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */
520 { /* debussy simply escapes until the space */
521 GLOBALS->yytext_vcd_partial_c_2[len++]= '\\';
522 }
523
524 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
525 {
526 if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
527 {
528 GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
529 }
530
531 ch=getch();
532 if(ch==' ')
533 {
534 if(match_kw) break;
535 if(getch_peek() == '[')
536 {
537 ch = getch();
538 GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->yytext_vcd_partial_c_2+len; /* keep looping so we get the *last* one */
539 continue;
540 }
541 }
542
543 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
544 if((ch=='[')&&(GLOBALS->yytext_vcd_partial_c_2[0]!='\\'))
545 {
546 GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->yytext_vcd_partial_c_2+len; /* keep looping so we get the *last* one */
547 }
548 else
549 if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_partial_c_2)&&(GLOBALS->yytext_vcd_partial_c_2[0]!='\\'))
550 {
551 GLOBALS->var_prevch_vcd_partial_c_2=ch;
552 break;
553 }
554 }
555 GLOBALS->yytext_vcd_partial_c_2[len]=0; /* absolute terminator */
556 if((GLOBALS->varsplit_vcd_partial_c_2)&&(GLOBALS->yytext_vcd_partial_c_2[len-1]==']'))
557 {
558 char *vst;
559 vst=malloc_2(strlen(GLOBALS->varsplit_vcd_partial_c_2)+1);
560 strcpy(vst, GLOBALS->varsplit_vcd_partial_c_2);
561
562 *GLOBALS->varsplit_vcd_partial_c_2=0x00; /* zero out var name at the left bracket */
563 len=GLOBALS->varsplit_vcd_partial_c_2-GLOBALS->yytext_vcd_partial_c_2;
564
565 GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->vsplitcurr_vcd_partial_c_2=vst;
566 GLOBALS->var_prevch_vcd_partial_c_2=0;
567 }
568 else
569 {
570 GLOBALS->varsplit_vcd_partial_c_2=NULL;
571 }
572
573 if(match_kw)
574 {
575 int vt = vcd_keyword_code(GLOBALS->yytext_vcd_partial_c_2, len);
576 if(vt != V_STRING)
577 {
578 return(vt);
579 }
580 }
581
582 GLOBALS->yylen_vcd_partial_c_2=len;
583 return(V_STRING);
584 }
585
get_strtoken(void)586 static int get_strtoken(void)
587 {
588 int ch;
589 int len=0;
590
591 if(!GLOBALS->var_prevch_vcd_partial_c_2)
592 {
593 for(;;)
594 {
595 ch=getch();
596 if(ch<0) return(V_END);
597 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
598 break;
599 }
600 }
601 else
602 {
603 ch=GLOBALS->var_prevch_vcd_partial_c_2;
604 GLOBALS->var_prevch_vcd_partial_c_2=0;
605 }
606
607 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
608 {
609 if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
610 {
611 GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
612 }
613 ch=getch();
614 if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
615 }
616 GLOBALS->yytext_vcd_partial_c_2[len]=0; /* terminator */
617
618 GLOBALS->yylen_vcd_partial_c_2=len;
619 return(V_STRING);
620 }
621
sync_end(char * hdr)622 static void sync_end(char *hdr)
623 {
624 int tok;
625
626 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
627 for(;;)
628 {
629 tok=get_token();
630 if((tok==T_END)||(tok==T_EOF)) break;
631 if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_partial_c_2)); }
632 }
633 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
634 }
635
version_sync_end(char * hdr)636 static int version_sync_end(char *hdr)
637 {
638 int tok;
639 int rc = 0;
640
641 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
642 for(;;)
643 {
644 tok=get_token();
645 if((tok==T_END)||(tok==T_EOF)) break;
646 if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_partial_c_2)); }
647 if(strstr(GLOBALS->yytext_vcd_partial_c_2, "Icarus")) /* turn off autocoalesce for Icarus */
648 {
649 GLOBALS->autocoalesce = 0;
650 rc = 1;
651 }
652 }
653 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
654 return(rc);
655 }
656
657
parse_valuechange(void)658 static void parse_valuechange(void)
659 {
660 struct vcdsymbol *v;
661 char *vector;
662 int vlen;
663 /* hptr hsuf; */ /* scan-build */
664
665 switch(GLOBALS->yytext_vcd_partial_c_2[0])
666 {
667 case '0':
668 case '1':
669 case 'x': case 'X':
670 case 'z': case 'Z':
671 case 'h': case 'H':
672 case 'u': case 'U':
673 case 'w': case 'W':
674 case 'l': case 'L':
675 case '-':
676 if(GLOBALS->yylen_vcd_partial_c_2>1)
677 {
678 v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2+1, GLOBALS->yylen_vcd_partial_c_2-1);
679 if(!v)
680 {
681 fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)),GLOBALS->yytext_vcd_partial_c_2+1);
682 }
683 else
684 {
685 v->value[0]=GLOBALS->yytext_vcd_partial_c_2[0];
686 DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0]));
687
688 v->narray[0]->curr = v->app_array[0];
689 /* hsuf = */ add_histent_p(GLOBALS->current_time_vcd_partial_c_2,v->narray[0],v->value[0],1, NULL); /* scan-build */
690 v->app_array[0] = v->narray[0]->curr;
691 v->narray[0]->curr->next = v->tr_array[0];
692 if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
693 }
694 }
695 else
696 {
697 fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
698 }
699 break;
700
701 case 'b':
702 case 'B':
703 {
704 /* extract binary number then.. */
705 vector=malloc_2(GLOBALS->yylen_cache_vcd_partial_c_2=GLOBALS->yylen_vcd_partial_c_2);
706 strcpy(vector,GLOBALS->yytext_vcd_partial_c_2+1);
707 vlen=GLOBALS->yylen_vcd_partial_c_2-1;
708
709 get_strtoken();
710 v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
711 if(!v)
712 {
713 fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
714 free_2(vector);
715 }
716 else
717 {
718 if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER))))
719 {
720 double *d;
721 char *pnt;
722 char ch;
723 TimeType k=0;
724
725 pnt=vector;
726 while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); }
727 free_2(vector);
728
729 d=malloc_2(sizeof(double));
730 *d=(double)k;
731
732 if(!v)
733 {
734 fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
735 free_2(d);
736 }
737 else
738 {
739 v->narray[0]->curr = v->app_array[0];
740 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d);
741 v->app_array[0] = v->narray[0]->curr;
742 v->narray[0]->curr->next = v->tr_array[0];
743 if(v->narray[0]->harray)
744 { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
745 }
746 break;
747 }
748
749 if(vlen<v->size) /* fill in left part */
750 {
751 char extend;
752 int i, fill;
753
754 extend=(vector[0]=='1')?'0':vector[0];
755
756 fill=v->size-vlen;
757 for(i=0;i<fill;i++)
758 {
759 v->value[i]=extend;
760 }
761 strcpy(v->value+fill,vector);
762 }
763 else if(vlen==v->size) /* straight copy */
764 {
765 strcpy(v->value,vector);
766 }
767 else /* too big, so copy only right half */
768 {
769 int skip;
770
771 skip=vlen-v->size;
772 strcpy(v->value,vector+skip);
773 }
774 DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value));
775
776 if((v->size==1)||(!GLOBALS->atomic_vectors))
777 {
778 int i;
779 for(i=0;i<v->size;i++)
780 {
781 v->narray[i]->curr = v->app_array[i];
782 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[i],v->value[i],1, NULL);
783 v->app_array[i] = v->narray[i]->curr;
784 v->narray[i]->curr->next = v->tr_array[i];
785 if(v->narray[i]->harray)
786 { free_2(v->narray[i]->harray); v->narray[i]->harray = NULL; }
787 }
788 free_2(vector);
789 }
790 else
791 {
792 if(GLOBALS->yylen_cache_vcd_partial_c_2!=(v->size+1))
793 {
794 free_2(vector);
795 vector=malloc_2(v->size+1);
796 }
797 strcpy(vector,v->value);
798 v->narray[0]->curr = v->app_array[0];
799 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],0,1,vector);
800 v->app_array[0] = v->narray[0]->curr;
801 v->narray[0]->curr->next = v->tr_array[0];
802 if(v->narray[0]->harray)
803 { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
804 }
805
806 }
807 break;
808 }
809
810 case 'p':
811 /* extract port dump value.. */
812 vector=malloc_2(GLOBALS->yylen_cache_vcd_partial_c_2=GLOBALS->yylen_vcd_partial_c_2);
813 strcpy(vector,GLOBALS->yytext_vcd_partial_c_2+1);
814 vlen=GLOBALS->yylen_vcd_partial_c_2-1;
815
816 get_strtoken(); /* throw away 0_strength_component */
817 get_strtoken(); /* throw away 0_strength_component */
818 get_strtoken(); /* this is the id */
819 v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
820 if(!v)
821 {
822 fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
823 free_2(vector);
824 }
825 else
826 {
827 if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER))))
828 {
829 double *d;
830 char *pnt;
831 char ch;
832 TimeType k=0;
833
834 pnt=vector;
835 while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); }
836 free_2(vector);
837
838 d=malloc_2(sizeof(double));
839 *d=(double)k;
840
841 if(!v)
842 {
843 fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
844 free_2(d);
845 }
846 else
847 {
848 v->narray[0]->curr = v->app_array[0];
849 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d);
850 v->app_array[0] = v->narray[0]->curr;
851 v->narray[0]->curr->next = v->tr_array[0];
852 if(v->narray[0]->harray)
853 { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
854 }
855 break;
856 }
857
858 if(vlen<v->size) /* fill in left part */
859 {
860 char extend;
861 int i, fill;
862
863 extend='0';
864
865 fill=v->size-vlen;
866 for(i=0;i<fill;i++)
867 {
868 v->value[i]=extend;
869 }
870 evcd_strcpy(v->value+fill,vector);
871 }
872 else if(vlen==v->size) /* straight copy */
873 {
874 evcd_strcpy(v->value,vector);
875 }
876 else /* too big, so copy only right half */
877 {
878 int skip;
879
880 skip=vlen-v->size;
881 evcd_strcpy(v->value,vector+skip);
882 }
883 DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value));
884
885 if((v->size==1)||(!GLOBALS->atomic_vectors))
886 {
887 int i;
888 for(i=0;i<v->size;i++)
889 {
890 v->narray[i]->curr = v->app_array[i];
891 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[i],v->value[i],1, NULL);
892 v->app_array[i] = v->narray[i]->curr;
893 v->narray[i]->curr->next = v->tr_array[i];
894 if(v->narray[i]->harray)
895 { free_2(v->narray[i]->harray); v->narray[i]->harray = NULL; }
896 }
897 free_2(vector);
898 }
899 else
900 {
901 if(GLOBALS->yylen_cache_vcd_partial_c_2<v->size)
902 {
903 free_2(vector);
904 vector=malloc_2(v->size+1);
905 }
906 strcpy(vector,v->value);
907 v->narray[0]->curr = v->app_array[0];
908 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],0,1,vector);
909 v->app_array[0] = v->narray[0]->curr;
910 v->narray[0]->curr->next = v->tr_array[0];
911 if(v->narray[0]->harray)
912 { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
913 }
914 }
915 break;
916
917
918 case 'r':
919 case 'R':
920 {
921 double *d;
922
923 d=malloc_2(sizeof(double));
924 sscanf(GLOBALS->yytext_vcd_partial_c_2+1,"%lg",d);
925
926 get_strtoken();
927 v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
928 if(!v)
929 {
930 fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
931 free_2(d);
932 }
933 else
934 {
935 v->narray[0]->curr = v->app_array[0];
936 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d);
937 v->app_array[0] = v->narray[0]->curr;
938 v->narray[0]->curr->next = v->tr_array[0];
939 if(v->narray[0]->harray)
940 { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
941 }
942
943 break;
944 }
945
946 #ifndef STRICT_VCD_ONLY
947 case 's':
948 case 'S':
949 {
950 char *d;
951
952 d=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2);
953 vlen = fstUtilityEscToBin((unsigned char *)d, (unsigned char *)(GLOBALS->yytext_vcd_partial_c_2+1), GLOBALS->yylen_vcd_partial_c_2); /* includes 0 term */
954 if(vlen != GLOBALS->yylen_vcd_partial_c_2)
955 {
956 d = realloc_2(d, vlen);
957 }
958
959 get_strtoken();
960 v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
961 if(!v)
962 {
963 fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
964 free_2(d);
965 }
966 else
967 {
968 v->narray[0]->curr = v->app_array[0];
969 add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'s',1,(char *)d);
970 v->app_array[0] = v->narray[0]->curr;
971 v->narray[0]->curr->next = v->tr_array[0];
972 if(v->narray[0]->harray)
973 { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
974 }
975
976 break;
977 }
978 #endif
979 }
980
981 }
982
983
evcd_strcpy(char * dst,char * src)984 static void evcd_strcpy(char *dst, char *src)
985 {
986 static const char *evcd="DUNZduLHXTlh01?FAaBbCcf";
987 static const char *vcd="01xz0101xz0101xzxxxxxxz";
988
989 char ch;
990 int i;
991
992 while((ch=*src))
993 {
994 for(i=0;i<23;i++)
995 {
996 if(evcd[i]==ch)
997 {
998 *dst=vcd[i];
999 break;
1000 }
1001 }
1002 if(i==23) *dst='x';
1003
1004 src++;
1005 dst++;
1006 }
1007
1008 *dst=0; /* null terminate destination */
1009 }
1010
1011
vcd_parse(void)1012 static void vcd_parse(void)
1013 {
1014 int tok;
1015 unsigned char ttype;
1016 int disable_autocoalesce = 0;
1017
1018 for(;;)
1019 {
1020 switch(get_token())
1021 {
1022 case T_COMMENT:
1023 sync_end("COMMENT:");
1024 break;
1025 case T_DATE:
1026 sync_end("DATE:");
1027 break;
1028 case T_VERSION:
1029 disable_autocoalesce = version_sync_end("VERSION:");
1030 break;
1031 case T_TIMEZERO:
1032 {
1033 int vtok=get_token();
1034 if((vtok==T_END)||(vtok==T_EOF)) break;
1035 GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1036
1037 DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset));
1038 sync_end(NULL);
1039 }
1040 break;
1041 case T_TIMESCALE:
1042 {
1043 int vtok;
1044 int i;
1045 char prefix=' ';
1046
1047 vtok=get_token();
1048 if((vtok==T_END)||(vtok==T_EOF)) break;
1049 fractional_timescale_fix(GLOBALS->yytext_vcd_partial_c_2);
1050 GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1051 if(!GLOBALS->time_scale) GLOBALS->time_scale=1;
1052 for(i=0;i<GLOBALS->yylen_vcd_partial_c_2;i++)
1053 {
1054 if((GLOBALS->yytext_vcd_partial_c_2[i]<'0')||(GLOBALS->yytext_vcd_partial_c_2[i]>'9'))
1055 {
1056 prefix=GLOBALS->yytext_vcd_partial_c_2[i];
1057 break;
1058 }
1059 }
1060 if(prefix==' ')
1061 {
1062 vtok=get_token();
1063 if((vtok==T_END)||(vtok==T_EOF)) break;
1064 prefix=GLOBALS->yytext_vcd_partial_c_2[0];
1065 }
1066 switch(prefix)
1067 {
1068 case ' ':
1069 case 'm':
1070 case 'u':
1071 case 'n':
1072 case 'p':
1073 case 'f':
1074 case 'a':
1075 case 'z':
1076 GLOBALS->time_dimension=prefix;
1077 break;
1078 case 's':
1079 GLOBALS->time_dimension=' ';
1080 break;
1081 default: /* unknown */
1082 GLOBALS->time_dimension='n';
1083 break;
1084 }
1085
1086 DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension));
1087 sync_end(NULL);
1088 }
1089 break;
1090 case T_SCOPE:
1091 T_GET;
1092 {
1093 switch(GLOBALS->yytext_vcd_partial_c_2[0])
1094 {
1095 case 'm': ttype = TREE_VCD_ST_MODULE; break;
1096 case 't': ttype = TREE_VCD_ST_TASK; break;
1097 case 'f': ttype = (GLOBALS->yytext_vcd_partial_c_2[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break;
1098 case 'b': ttype = TREE_VCD_ST_BEGIN; break;
1099 case 'g': ttype = TREE_VCD_ST_GENERATE; break;
1100 case 's': ttype = TREE_VCD_ST_STRUCT; break;
1101 case 'u': ttype = TREE_VCD_ST_UNION; break;
1102 case 'c': ttype = TREE_VCD_ST_CLASS; break;
1103 case 'i': ttype = TREE_VCD_ST_INTERFACE; break;
1104 case 'p': ttype = (GLOBALS->yytext_vcd_partial_c_2[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break;
1105
1106 case 'v': {
1107 char *vht = GLOBALS->yytext_vcd_partial_c_2;
1108 if(!strncmp(vht, "vhdl_", 5))
1109 {
1110 switch(vht[5])
1111 {
1112 case 'a': ttype = TREE_VHDL_ST_ARCHITECTURE; break;
1113 case 'r': ttype = TREE_VHDL_ST_RECORD; break;
1114 case 'b': ttype = TREE_VHDL_ST_BLOCK; break;
1115 case 'g': ttype = TREE_VHDL_ST_GENERATE; break;
1116 case 'i': ttype = TREE_VHDL_ST_GENIF; break;
1117 case 'f': ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break;
1118 case 'p': ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break;
1119 default: ttype = TREE_UNKNOWN; break;
1120 }
1121 }
1122 else
1123 {
1124 ttype = TREE_UNKNOWN;
1125 }
1126 }
1127 break;
1128
1129 default: ttype = TREE_UNKNOWN;
1130 break;
1131 }
1132 }
1133 T_GET;
1134 if(tok==T_STRING)
1135 {
1136 struct slist *s;
1137 s=(struct slist *)calloc_2(1,sizeof(struct slist));
1138 s->len=GLOBALS->yylen_vcd_partial_c_2;
1139 s->str=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1140 strcpy(s->str, GLOBALS->yytext_vcd_partial_c_2);
1141 s->mod_tree_parent = GLOBALS->mod_tree_parent;
1142
1143 allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_partial_c_2, NULL, GLOBALS->yylen_vcd_partial_c_2, 0, 0, 0);
1144
1145 if(GLOBALS->slistcurr)
1146 {
1147 GLOBALS->slistcurr->next=s;
1148 GLOBALS->slistcurr=s;
1149 }
1150 else
1151 {
1152 GLOBALS->slistcurr=GLOBALS->slistroot=s;
1153 }
1154
1155 build_slisthier();
1156 DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1157 }
1158 sync_end(NULL);
1159 break;
1160 case T_UPSCOPE:
1161 if(GLOBALS->slistroot)
1162 {
1163 struct slist *s;
1164
1165 GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent;
1166 s=GLOBALS->slistroot;
1167 if(!s->next)
1168 {
1169 free_2(s->str);
1170 free_2(s);
1171 GLOBALS->slistroot=GLOBALS->slistcurr=NULL;
1172 }
1173 else
1174 for(;;)
1175 {
1176 if(!s->next->next)
1177 {
1178 free_2(s->next->str);
1179 free_2(s->next);
1180 s->next=NULL;
1181 GLOBALS->slistcurr=s;
1182 break;
1183 }
1184 s=s->next;
1185 }
1186 build_slisthier();
1187 DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1188 }
1189 else
1190 {
1191 GLOBALS->mod_tree_parent = NULL;
1192 }
1193 sync_end(NULL);
1194 break;
1195 case T_VAR:
1196 if((GLOBALS->header_over_vcd_partial_c_2)&&(0))
1197 {
1198 fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d. VCD is malformed, exiting.\n",
1199 (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
1200 exit(0);
1201 }
1202 else
1203 {
1204 int vtok;
1205 struct vcdsymbol *v=NULL;
1206
1207 GLOBALS->var_prevch_vcd_partial_c_2=0;
1208 if(GLOBALS->varsplit_vcd_partial_c_2)
1209 {
1210 free_2(GLOBALS->varsplit_vcd_partial_c_2);
1211 GLOBALS->varsplit_vcd_partial_c_2=NULL;
1212 }
1213 vtok=get_vartoken(1);
1214 if(vtok>V_STRINGTYPE) goto bail;
1215
1216 v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol));
1217 v->vartype=vtok;
1218 v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */
1219
1220 if(vtok==V_PORT)
1221 {
1222 vtok=get_vartoken(1);
1223 if(vtok==V_STRING)
1224 {
1225 v->size=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1226 if(!v->size) v->size=1;
1227 }
1228 else
1229 if(vtok==V_LB)
1230 {
1231 vtok=get_vartoken(1);
1232 if(vtok==V_END) goto err;
1233 if(vtok!=V_STRING) goto err;
1234 v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1235 vtok=get_vartoken(0);
1236 if(vtok==V_RB)
1237 {
1238 v->lsi=v->msi;
1239 v->size=1;
1240 }
1241 else
1242 {
1243 if(vtok!=V_COLON) goto err;
1244 vtok=get_vartoken(0);
1245 if(vtok!=V_STRING) goto err;
1246 v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1247 vtok=get_vartoken(0);
1248 if(vtok!=V_RB) goto err;
1249
1250 if(v->msi>v->lsi)
1251 {
1252 v->size=v->msi-v->lsi+1;
1253 }
1254 else
1255 {
1256 v->size=v->lsi-v->msi+1;
1257 }
1258 }
1259 }
1260 else goto err;
1261
1262 vtok=get_strtoken();
1263 if(vtok==V_END) goto err;
1264 v->id=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1265 strcpy(v->id, GLOBALS->yytext_vcd_partial_c_2);
1266 v->nid=vcdid_hash(GLOBALS->yytext_vcd_partial_c_2,GLOBALS->yylen_vcd_partial_c_2);
1267
1268 if(v->nid == (GLOBALS->vcd_hash_max+1))
1269 {
1270 GLOBALS->vcd_hash_max = v->nid;
1271 }
1272 else
1273 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1274 {
1275 /* general case with aliases */
1276 }
1277 else
1278 {
1279 GLOBALS->vcd_hash_kill = 1;
1280 }
1281
1282 if(v->nid < GLOBALS->vcd_minid_vcd_partial_c_2) GLOBALS->vcd_minid_vcd_partial_c_2 = v->nid;
1283 if(v->nid > GLOBALS->vcd_maxid_vcd_partial_c_2) GLOBALS->vcd_maxid_vcd_partial_c_2 = v->nid;
1284
1285 vtok=get_vartoken(0);
1286 if(vtok!=V_STRING) goto err;
1287 if(GLOBALS->slisthier_len)
1288 {
1289 v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+1);
1290 strcpy(v->name,GLOBALS->slisthier);
1291 strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1292 if(GLOBALS->alt_hier_delimeter)
1293 {
1294 strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1295 }
1296 else
1297 {
1298 if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1299 {
1300 char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+2);
1301 strcpy(sd,GLOBALS->slisthier);
1302 strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1303 sd[GLOBALS->slisthier_len+1] = '\\';
1304 strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1305 free_2(v->name);
1306 v->name = sd;
1307 }
1308 }
1309 }
1310 else
1311 {
1312 v->name=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1313 if(GLOBALS->alt_hier_delimeter)
1314 {
1315 strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1316 }
1317 else
1318 {
1319 if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1320 {
1321 char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+2);
1322 sd[0] = '\\';
1323 strcpy(sd+1,v->name);
1324 free_2(v->name);
1325 v->name = sd;
1326 }
1327 }
1328 }
1329
1330 if(GLOBALS->pv_vcd_partial_c_2)
1331 {
1332 if(!strcmp(GLOBALS->pv_vcd_partial_c_2->name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\')))
1333 {
1334 GLOBALS->pv_vcd_partial_c_2->chain=v;
1335 v->root=GLOBALS->rootv_vcd_partial_c_2;
1336 if(GLOBALS->pv_vcd_partial_c_2==GLOBALS->rootv_vcd_partial_c_2) GLOBALS->pv_vcd_partial_c_2->root=GLOBALS->rootv_vcd_partial_c_2;
1337 }
1338 else
1339 {
1340 GLOBALS->rootv_vcd_partial_c_2=v;
1341 }
1342 }
1343 else
1344 {
1345 GLOBALS->rootv_vcd_partial_c_2=v;
1346 }
1347 GLOBALS->pv_vcd_partial_c_2=v;
1348 }
1349 else /* regular vcd var, not an evcd port var */
1350 {
1351 vtok=get_vartoken(1);
1352 if(vtok==V_END) goto err;
1353 v->size=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1354 vtok=get_strtoken();
1355 if(vtok==V_END) goto err;
1356 v->id=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1357 strcpy(v->id, GLOBALS->yytext_vcd_partial_c_2);
1358 v->nid=vcdid_hash(GLOBALS->yytext_vcd_partial_c_2,GLOBALS->yylen_vcd_partial_c_2);
1359
1360 if(v->nid == (GLOBALS->vcd_hash_max+1))
1361 {
1362 GLOBALS->vcd_hash_max = v->nid;
1363 }
1364 else
1365 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1366 {
1367 /* general case with aliases */
1368 }
1369 else
1370 {
1371 GLOBALS->vcd_hash_kill = 1;
1372 }
1373
1374 if(v->nid < GLOBALS->vcd_minid_vcd_partial_c_2) GLOBALS->vcd_minid_vcd_partial_c_2 = v->nid;
1375 if(v->nid > GLOBALS->vcd_maxid_vcd_partial_c_2) GLOBALS->vcd_maxid_vcd_partial_c_2 = v->nid;
1376
1377 vtok=get_vartoken(0);
1378 if(vtok!=V_STRING) goto err;
1379 if(GLOBALS->slisthier_len)
1380 {
1381 v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+1);
1382 strcpy(v->name,GLOBALS->slisthier);
1383 strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1384 if(GLOBALS->alt_hier_delimeter)
1385 {
1386 strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1387 }
1388 else
1389 {
1390 if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1391 {
1392 char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+2);
1393 strcpy(sd,GLOBALS->slisthier);
1394 strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1395 sd[GLOBALS->slisthier_len+1] = '\\';
1396 strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1397 free_2(v->name);
1398 v->name = sd;
1399 }
1400 }
1401 }
1402 else
1403 {
1404 v->name=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1405 if(GLOBALS->alt_hier_delimeter)
1406 {
1407 strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1408 }
1409 else
1410 {
1411 if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1412 {
1413 char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+2);
1414 sd[0] = '\\';
1415 strcpy(sd+1,v->name);
1416 free_2(v->name);
1417 v->name = sd;
1418 }
1419 }
1420 }
1421
1422 if(GLOBALS->pv_vcd_partial_c_2)
1423 {
1424 if(!strcmp(GLOBALS->pv_vcd_partial_c_2->name,v->name))
1425 {
1426 GLOBALS->pv_vcd_partial_c_2->chain=v;
1427 v->root=GLOBALS->rootv_vcd_partial_c_2;
1428 if(GLOBALS->pv_vcd_partial_c_2==GLOBALS->rootv_vcd_partial_c_2) GLOBALS->pv_vcd_partial_c_2->root=GLOBALS->rootv_vcd_partial_c_2;
1429 }
1430 else
1431 {
1432 GLOBALS->rootv_vcd_partial_c_2=v;
1433 }
1434 }
1435 else
1436 {
1437 GLOBALS->rootv_vcd_partial_c_2=v;
1438 }
1439 GLOBALS->pv_vcd_partial_c_2=v;
1440
1441 vtok=get_vartoken(1);
1442 if(vtok==V_END) goto dumpv;
1443 if(vtok!=V_LB) goto err;
1444 vtok=get_vartoken(0);
1445 if(vtok!=V_STRING) goto err;
1446 v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1447 vtok=get_vartoken(0);
1448 if(vtok==V_RB)
1449 {
1450 v->lsi=v->msi;
1451 goto dumpv;
1452 }
1453 if(vtok!=V_COLON) goto err;
1454 vtok=get_vartoken(0);
1455 if(vtok!=V_STRING) goto err;
1456 v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1457 vtok=get_vartoken(0);
1458 if(vtok!=V_RB) goto err;
1459 }
1460
1461 dumpv:
1462 if(v->size == 0)
1463 {
1464 if(v->vartype != V_EVENT)
1465 {
1466 if(v->vartype != V_STRINGTYPE)
1467 {
1468 v->vartype = V_REAL;
1469 }
1470 }
1471 else
1472 {
1473 v->size = 1;
1474 }
1475
1476 } /* MTI fix */
1477
1478 if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER))))
1479 {
1480 if(v->vartype != V_STRINGTYPE)
1481 {
1482 v->vartype=V_REAL;
1483 }
1484 v->size=1; /* override any data we parsed in */
1485 v->msi=v->lsi=0;
1486 }
1487 else
1488 if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0))
1489 {
1490 if(v->vartype==V_EVENT)
1491 {
1492 v->size=1;
1493 }
1494 else
1495 {
1496 /* any criteria for the direction here? */
1497 v->msi=v->size-1;
1498 v->lsi=0;
1499 }
1500 }
1501 else
1502 if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
1503 {
1504 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1505 {
1506 if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */
1507 {
1508 v->msi = v->size-1; v->lsi = 0;
1509 }
1510 /* all this formerly was goto err; */
1511 }
1512 else
1513 {
1514 v->size=v->msi-v->lsi+1;
1515 }
1516 }
1517 else
1518 if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
1519 {
1520 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1521 {
1522 if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */
1523 {
1524 v->lsi = v->size-1; v->msi = 0;
1525 }
1526 /* all this formerly was goto err; */
1527 }
1528 else
1529 {
1530 v->size=v->lsi-v->msi+1;
1531 }
1532 }
1533
1534 /* initial conditions */
1535 v->value=(char *)malloc_2(v->size+1);
1536 v->value[v->size]=0;
1537 v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *));
1538 v->tr_array=(hptr *)calloc_2(v->size,sizeof(hptr));
1539 v->app_array=(hptr *)calloc_2(v->size,sizeof(hptr));
1540 {
1541 int i;
1542 if(GLOBALS->atomic_vectors)
1543 {
1544 for(i=0;i<v->size;i++)
1545 {
1546 v->value[i]='x';
1547 }
1548 v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node));
1549 v->narray[0]->head.time=-1;
1550 v->narray[0]->head.v.h_val=AN_X;
1551 }
1552 else
1553 {
1554 for(i=0;i<v->size;i++)
1555 {
1556 v->value[i]='x';
1557
1558 v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node));
1559 v->narray[i]->head.time=-1;
1560 v->narray[i]->head.v.h_val=AN_X;
1561 }
1562 }
1563 }
1564
1565 if(!GLOBALS->vcdsymroot_vcd_partial_c_2)
1566 {
1567 GLOBALS->vcdsymroot_vcd_partial_c_2=GLOBALS->vcdsymcurr_vcd_partial_c_2=v;
1568 }
1569 else
1570 {
1571 GLOBALS->vcdsymcurr_vcd_partial_c_2->next=v;
1572 GLOBALS->vcdsymcurr_vcd_partial_c_2=v;
1573 }
1574 GLOBALS->numsyms_vcd_partial_c_2++;
1575
1576 goto bail;
1577 err:
1578 if(v)
1579 {
1580 GLOBALS->error_count_vcd_partial_c_2++;
1581 if(v->name)
1582 {
1583 fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), v->name);
1584 free_2(v->name);
1585 }
1586 else
1587 {
1588 fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
1589 }
1590 if(v->id) free_2(v->id);
1591 if(v->value) free_2(v->value);
1592 free_2(v);
1593 GLOBALS->pv_vcd_partial_c_2 = NULL;
1594 }
1595
1596 bail:
1597 if(vtok!=V_END) sync_end(NULL);
1598 break;
1599 }
1600 case T_ENDDEFINITIONS:
1601 GLOBALS->header_over_vcd_partial_c_2=1; /* do symbol table management here */
1602 create_sorted_table();
1603 if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2))
1604 {
1605 fprintf(stderr, "No symbols in VCD file..nothing to do!\n");
1606 exit(1);
1607 }
1608 if(GLOBALS->error_count_vcd_partial_c_2)
1609 {
1610 fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_partial_c_2);
1611 exit(1);
1612 }
1613 return;
1614 break;
1615 case T_STRING:
1616 if(!GLOBALS->header_over_vcd_partial_c_2)
1617 {
1618 GLOBALS->header_over_vcd_partial_c_2=1; /* do symbol table management here */
1619 create_sorted_table();
1620 if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2)) break;
1621 }
1622 {
1623 /* catchall for events when header over */
1624 if(GLOBALS->yytext_vcd_partial_c_2[0]=='#')
1625 {
1626 TimeType tim;
1627 tim=atoi_64(GLOBALS->yytext_vcd_partial_c_2+1);
1628
1629 if(GLOBALS->start_time_vcd_partial_c_2<0)
1630 {
1631 GLOBALS->start_time_vcd_partial_c_2=tim;
1632 }
1633
1634 GLOBALS->current_time_vcd_partial_c_2=tim;
1635 if(GLOBALS->end_time_vcd_partial_c_2<tim) GLOBALS->end_time_vcd_partial_c_2=tim; /* in case of malformed vcd files */
1636 DEBUG(fprintf(stderr,"#"TTFormat"\n",tim));
1637 }
1638 else
1639 {
1640 parse_valuechange();
1641 }
1642 }
1643 break;
1644 case T_DUMPALL: /* dump commands modify vals anyway so */
1645 case T_DUMPPORTSALL:
1646 break; /* just loop through.. */
1647 case T_DUMPOFF:
1648 case T_DUMPPORTSOFF:
1649 GLOBALS->dumping_off_vcd_partial_c_2=1;
1650 /* if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) : remove redundant condition */
1651 if((!GLOBALS->blackout_regions)||(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))
1652 {
1653 struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t));
1654
1655 bt->bstart = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale;
1656 bt->next = GLOBALS->blackout_regions;
1657 GLOBALS->blackout_regions = bt;
1658 }
1659 break;
1660 case T_DUMPON:
1661 case T_DUMPPORTSON:
1662 GLOBALS->dumping_off_vcd_partial_c_2=0;
1663 if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
1664 {
1665 GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale;
1666 }
1667 break;
1668 case T_DUMPVARS:
1669 case T_DUMPPORTS:
1670 if(GLOBALS->current_time_vcd_partial_c_2<0)
1671 { GLOBALS->start_time_vcd_partial_c_2=GLOBALS->current_time_vcd_partial_c_2=GLOBALS->end_time_vcd_partial_c_2=0; }
1672 break;
1673 case T_VCDCLOSE:
1674 sync_end("VCDCLOSE:");
1675 break; /* next token will be '#' time related followed by $end */
1676 case T_END: /* either closure for dump commands or */
1677 break; /* it's spurious */
1678 case T_UNKNOWN_KEY:
1679 sync_end(NULL); /* skip over unknown keywords */
1680 break;
1681 case T_EOF:
1682 if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
1683 {
1684 GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale;
1685 }
1686 return;
1687 default:
1688 DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n"));
1689 }
1690 }
1691 }
1692
1693
1694 /*******************************************************************************/
1695
add_histent_p(TimeType tim,struct Node * n,char ch,int regadd,char * vector)1696 hptr add_histent_p(TimeType tim, struct Node *n, char ch, int regadd, char *vector)
1697 {
1698 struct HistEnt *he, *rc;
1699 char heval;
1700
1701 if(!vector)
1702 {
1703 if(!(rc=n->curr))
1704 {
1705 he=histent_calloc();
1706 he->time=-1;
1707 he->v.h_val=AN_X;
1708
1709 n->curr=he;
1710 n->head.next=he;
1711
1712 add_histent_p(tim,n,ch,regadd, vector);
1713 rc = he;
1714 }
1715 else
1716 {
1717 if(regadd) { tim*=(GLOBALS->time_scale); }
1718
1719 if(ch=='0') heval=AN_0; else
1720 if(ch=='1') heval=AN_1; else
1721 if((ch=='x')||(ch=='X')) heval=AN_X; else
1722 if((ch=='z')||(ch=='Z')) heval=AN_Z; else
1723 if((ch=='h')||(ch=='H')) heval=AN_H; else
1724 if((ch=='u')||(ch=='U')) heval=AN_U; else
1725 if((ch=='w')||(ch=='W')) heval=AN_W; else
1726 if((ch=='l')||(ch=='L')) heval=AN_L; else
1727 /* if(ch=='-') */ heval=AN_DASH; /* default */
1728
1729 if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_partial_c_2)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */
1730 {
1731 if(n->curr->time==tim)
1732 {
1733 DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
1734 tim, n, AN_STR[n->curr->v.h_val], ch));
1735 n->curr->v.h_val=heval; /* we have a glitch! */
1736
1737 GLOBALS->num_glitches_vcd_partial_c_3++;
1738 if(!(n->curr->flags&HIST_GLITCH))
1739 {
1740 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
1741 GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1742 }
1743 }
1744 else
1745 {
1746 he=histent_calloc();
1747 he->time=tim;
1748 he->v.h_val=heval;
1749
1750 n->curr->next=he;
1751 if(n->curr->v.h_val==heval)
1752 {
1753 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
1754 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
1755 }
1756 n->curr=he;
1757 GLOBALS->regions+=regadd;
1758 }
1759 }
1760 }
1761 }
1762 else
1763 {
1764 switch(ch)
1765 {
1766 case 's': /* string */
1767 {
1768 if(!(rc=n->curr))
1769 {
1770 he=histent_calloc();
1771 he->flags=(HIST_STRING|HIST_REAL);
1772 he->time=-1;
1773 he->v.h_vector=NULL;
1774
1775 n->curr=he;
1776 n->head.next=he;
1777
1778 add_histent_p(tim,n,ch,regadd, vector);
1779 rc = he;
1780 }
1781 else
1782 {
1783 if(regadd) { tim*=(GLOBALS->time_scale); }
1784
1785 if(n->curr->time==tim)
1786 {
1787 DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n",
1788 tim, n));
1789 if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
1790 n->curr->v.h_vector=vector; /* we have a glitch! */
1791
1792 GLOBALS->num_glitches_vcd_partial_c_3++;
1793 if(!(n->curr->flags&HIST_GLITCH))
1794 {
1795 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
1796 GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1797 }
1798 }
1799 else
1800 {
1801 he=histent_calloc();
1802 he->flags=(HIST_STRING|HIST_REAL);
1803 he->time=tim;
1804 he->v.h_vector=vector;
1805
1806 n->curr->next=he;
1807 n->curr=he;
1808 GLOBALS->regions+=regadd;
1809 }
1810 }
1811 break;
1812 }
1813 case 'g': /* real number */
1814 {
1815 if(!(rc=n->curr))
1816 {
1817 he=histent_calloc();
1818 he->flags=HIST_REAL;
1819 he->time=-1;
1820 #ifdef WAVE_HAS_H_DOUBLE
1821 he->v.h_double = strtod("NaN", NULL);
1822 #else
1823 he->v.h_vector=NULL;
1824 #endif
1825 n->curr=he;
1826 n->head.next=he;
1827
1828 add_histent_p(tim,n,ch,regadd, vector);
1829 rc = he;
1830 }
1831 else
1832 {
1833 if(regadd) { tim*=(GLOBALS->time_scale); }
1834
1835 if(
1836 #ifdef WAVE_HAS_H_DOUBLE
1837 (vector&&(n->curr->v.h_double!=*(double *)vector))
1838 #else
1839 (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector))
1840 #endif
1841 ||(tim==GLOBALS->start_time_vcd_partial_c_2)
1842 #ifndef WAVE_HAS_H_DOUBLE
1843 ||(!n->curr->v.h_vector)
1844 #endif
1845 ||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real)
1846 ) /* same region == go skip */
1847 {
1848 if(n->curr->time==tim)
1849 {
1850 DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n",
1851 tim, n));
1852 #ifdef WAVE_HAS_H_DOUBLE
1853 n->curr->v.h_double = *((double *)vector);
1854 #else
1855 if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
1856 n->curr->v.h_vector=vector; /* we have a glitch! */
1857 #endif
1858 GLOBALS->num_glitches_vcd_partial_c_3++;
1859 if(!(n->curr->flags&HIST_GLITCH))
1860 {
1861 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
1862 GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1863 }
1864 }
1865 else
1866 {
1867 he=histent_calloc();
1868 he->flags=HIST_REAL;
1869 he->time=tim;
1870 #ifdef WAVE_HAS_H_DOUBLE
1871 he->v.h_double = *((double *)vector);
1872 #else
1873 he->v.h_vector=vector;
1874 #endif
1875 n->curr->next=he;
1876 n->curr=he;
1877 GLOBALS->regions+=regadd;
1878 }
1879 }
1880 else
1881 {
1882 #ifndef WAVE_HAS_H_DOUBLE
1883 free_2(vector);
1884 #endif
1885 }
1886 #ifdef WAVE_HAS_H_DOUBLE
1887 free_2(vector);
1888 #endif
1889 }
1890 break;
1891 }
1892 default:
1893 {
1894 if(!(rc=n->curr))
1895 {
1896 he=histent_calloc();
1897 he->time=-1;
1898 he->v.h_vector=NULL;
1899
1900 n->curr=he;
1901 n->head.next=he;
1902
1903 add_histent_p(tim,n,ch,regadd, vector);
1904 rc = he;
1905 }
1906 else
1907 {
1908 if(regadd) { tim*=(GLOBALS->time_scale); }
1909
1910 if(
1911 (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector)))
1912 ||(tim==GLOBALS->start_time_vcd_partial_c_2)
1913 ||(!n->curr->v.h_vector)
1914 ||(GLOBALS->vcd_preserve_glitches)
1915 ) /* same region == go skip */
1916 {
1917 if(n->curr->time==tim)
1918 {
1919 DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
1920 tim, n, AN_STR[n->curr->v.h_val], ch));
1921 if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
1922 n->curr->v.h_vector=vector; /* we have a glitch! */
1923
1924 GLOBALS->num_glitches_vcd_partial_c_3++;
1925 if(!(n->curr->flags&HIST_GLITCH))
1926 {
1927 n->curr->flags|=HIST_GLITCH; /* set the glitch flag */
1928 GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1929 }
1930 }
1931 else
1932 {
1933 he=histent_calloc();
1934 he->time=tim;
1935 he->v.h_vector=vector;
1936
1937 n->curr->next=he;
1938 n->curr=he;
1939 GLOBALS->regions+=regadd;
1940 }
1941 }
1942 else
1943 {
1944 free_2(vector);
1945 }
1946 }
1947 break;
1948 }
1949 }
1950 }
1951
1952 return(rc);
1953 }
1954
1955
add_tail_histents(void)1956 static void add_tail_histents(void)
1957 {
1958 int j;
1959 struct vcdsymbol *v;
1960 hptr rc;
1961
1962
1963 /* do 'x' trailers */
1964
1965 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
1966 while(v)
1967 {
1968 if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
1969 {
1970 double *d;
1971
1972 d=malloc_2(sizeof(double));
1973 *d=1.0;
1974 rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[0], 'g', 0, (char *)d);
1975 set_vcd_vartype(v, v->narray[0]);
1976 v->app_array[0] = rc;
1977 v->tr_array[0] = v->narray[0]->curr;
1978 }
1979 else
1980 if((v->size==1)||(!GLOBALS->atomic_vectors))
1981 for(j=0;j<v->size;j++)
1982 {
1983 rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[j], 'x', 0, NULL);
1984 set_vcd_vartype(v, v->narray[j]);
1985 v->app_array[j] = rc;
1986 v->tr_array[j] = v->narray[j]->curr;
1987 }
1988 else
1989 {
1990 rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[0], 'x', 0, (char *)calloc_2(1,sizeof(char)));
1991 set_vcd_vartype(v, v->narray[0]);
1992 v->app_array[0] = rc;
1993 v->tr_array[0] = v->narray[0]->curr;
1994 }
1995
1996 v=v->next;
1997 }
1998
1999 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
2000 while(v)
2001 {
2002 if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
2003 {
2004 double *d;
2005
2006 d=malloc_2(sizeof(double));
2007 *d=0.0;
2008 add_histent_p(MAX_HISTENT_TIME, v->narray[0], 'g', 0, (char *)d);
2009 }
2010 else
2011 if((v->size==1)||(!GLOBALS->atomic_vectors))
2012 for(j=0;j<v->size;j++)
2013 {
2014 add_histent_p(MAX_HISTENT_TIME, v->narray[j], 'z', 0, NULL);
2015 }
2016 else
2017 {
2018 add_histent_p(MAX_HISTENT_TIME, v->narray[0], 'z', 0, (char *)calloc_2(1,sizeof(char)));
2019 }
2020
2021 v=v->next;
2022 }
2023 }
2024
2025 /*******************************************************************************/
2026
vcd_build_symbols(void)2027 static void vcd_build_symbols(void)
2028 {
2029 int j;
2030 int max_slen=-1;
2031 struct sym_chain *sym_chain=NULL, *sym_curr=NULL;
2032 int duphier=0;
2033 char hashdirty;
2034 struct vcdsymbol *v, *vprime;
2035 char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */
2036 #ifdef _WAVE_HAVE_JUDY
2037 int ss_len, longest = 0;
2038 #endif
2039
2040 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
2041 while(v)
2042 {
2043 int msi;
2044 int delta;
2045
2046 {
2047 int slen;
2048 int substnode;
2049
2050 msi=v->msi;
2051 delta=((v->lsi-v->msi)<0)?-1:1;
2052 substnode=0;
2053
2054 slen=strlen(v->name);
2055 str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
2056 strcpy(str,v->name);
2057
2058 if((v->msi>=0)||(v->msi != v->lsi))
2059 {
2060 strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
2061 slen++;
2062 }
2063
2064 if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */
2065 {
2066 if(v->size!=vprime->size)
2067 {
2068 fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name);
2069 }
2070 else
2071 {
2072 substnode=1;
2073 }
2074 }
2075
2076 if(((v->size==1)||(!GLOBALS->atomic_vectors))&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE))
2077 {
2078 struct symbol *s = NULL;
2079
2080 for(j=0;j<v->size;j++)
2081 {
2082 if(v->msi>=0)
2083 {
2084 if(!GLOBALS->vcd_explicit_zero_subscripts)
2085 sprintf(str+slen,"%d",msi);
2086 else
2087 sprintf(str+slen-1,"[%d]",msi);
2088 }
2089
2090 hashdirty=0;
2091 if(symfind(str, NULL))
2092 {
2093 char *dupfix=(char *)malloc_2(max_slen+32);
2094 #ifndef _WAVE_HAVE_JUDY
2095 hashdirty=1;
2096 #endif
2097 DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2098
2099 do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2100 while(symfind(dupfix, NULL));
2101
2102 strcpy(str, dupfix);
2103 free_2(dupfix);
2104 duphier=0; /* reset for next duplicate resolution */
2105 }
2106 /* fallthrough */
2107 {
2108 s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache);
2109 #ifdef _WAVE_HAVE_JUDY
2110 ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2111 #endif
2112 s->n=v->narray[j];
2113 if(substnode)
2114 {
2115 struct Node *n, *n2;
2116
2117 n=s->n;
2118 n2=vprime->narray[j];
2119 /* nname stays same */
2120 n->head=n2->head;
2121 n->curr=n2->curr;
2122 /* harray calculated later */
2123 n->numhist=n2->numhist;
2124 }
2125
2126 #ifndef _WAVE_HAVE_JUDY
2127 s->n->nname=s->name;
2128 #endif
2129 if(!GLOBALS->firstnode)
2130 {
2131 GLOBALS->firstnode=
2132 GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2133 }
2134 else
2135 {
2136 GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2137 GLOBALS->curnode=GLOBALS->curnode->next;
2138 }
2139 GLOBALS->curnode->symbol=s;
2140
2141 GLOBALS->numfacs++;
2142 DEBUG(fprintf(stderr,"Added: %s\n",str));
2143 }
2144 msi+=delta;
2145 }
2146
2147 if((j==1)&&(v->root))
2148 {
2149 s->vec_root=(struct symbol *)v->root; /* these will get patched over */
2150 s->vec_chain=(struct symbol *)v->chain; /* these will get patched over */
2151 v->sym_chain=s;
2152
2153 if(!sym_chain)
2154 {
2155 sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2156 sym_chain=sym_curr;
2157 }
2158 else
2159 {
2160 sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2161 sym_curr=sym_curr->next;
2162 }
2163 sym_curr->val=s;
2164 }
2165 }
2166 else /* atomic vector */
2167 {
2168 if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER))
2169 /* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */
2170 {
2171 sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi);
2172 /* 2d add */
2173 if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
2174 {
2175 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2176 {
2177 v->msi = v->size-1; v->lsi = 0;
2178 }
2179 }
2180 else
2181 if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
2182 {
2183 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2184 {
2185 v->lsi = v->size-1; v->msi = 0;
2186 }
2187 }
2188 }
2189 else
2190 {
2191 *(str+slen-1)=0;
2192 }
2193
2194
2195 hashdirty=0;
2196 if(symfind(str, NULL))
2197 {
2198 char *dupfix=(char *)malloc_2(max_slen+32);
2199 #ifndef _WAVE_HAVE_JUDY
2200 hashdirty=1;
2201 #endif
2202 DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2203
2204 do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2205 while(symfind(dupfix, NULL));
2206
2207 strcpy(str, dupfix);
2208 free_2(dupfix);
2209 duphier=0; /* reset for next duplicate resolution */
2210 }
2211 /* fallthrough */
2212 {
2213 struct symbol *s;
2214
2215 s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); /* cut down on double lookups.. */
2216 #ifdef _WAVE_HAVE_JUDY
2217 ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2218 #endif
2219 s->n=v->narray[0];
2220 if(substnode)
2221 {
2222 struct Node *n, *n2;
2223
2224 n=s->n;
2225 n2=vprime->narray[0];
2226 /* nname stays same */
2227 n->head=n2->head;
2228 n->curr=n2->curr;
2229 /* harray calculated later */
2230 n->numhist=n2->numhist;
2231 n->extvals=n2->extvals;
2232 n->msi=n2->msi;
2233 n->lsi=n2->lsi;
2234 }
2235 else
2236 {
2237 s->n->msi=v->msi;
2238 s->n->lsi=v->lsi;
2239
2240 s->n->extvals=1;
2241 }
2242
2243 #ifndef _WAVE_HAVE_JUDY
2244 s->n->nname=s->name;
2245 #endif
2246 if(!GLOBALS->firstnode)
2247 {
2248 GLOBALS->firstnode=
2249 GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2250 }
2251 else
2252 {
2253 GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2254 GLOBALS->curnode=GLOBALS->curnode->next;
2255 }
2256 GLOBALS->curnode->symbol=s;
2257
2258 GLOBALS->numfacs++;
2259 DEBUG(fprintf(stderr,"Added: %s\n",str));
2260 }
2261 }
2262 }
2263
2264 v=v->next;
2265 }
2266
2267 #ifdef _WAVE_HAVE_JUDY
2268 {
2269 Pvoid_t PJArray = GLOBALS->sym_judy;
2270 PPvoid_t PPValue;
2271 char *Index = calloc_2(1, longest);
2272
2273 for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0);
2274 PPValue != (PPvoid_t) NULL;
2275 PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0))
2276 {
2277 struct symbol *s = *(struct symbol **)PPValue;
2278 s->name = strdup_2(Index);
2279 s->n->nname = s->name;
2280 }
2281
2282 free_2(Index);
2283 }
2284 #endif
2285
2286 if(sym_chain)
2287 {
2288 sym_curr=sym_chain;
2289 while(sym_curr)
2290 {
2291 sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain;
2292
2293 if ((struct vcdsymbol *)sym_curr->val->vec_chain)
2294 sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain;
2295
2296 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)"));
2297
2298 sym_chain=sym_curr;
2299 sym_curr=sym_curr->next;
2300 free_2(sym_chain);
2301 }
2302 }
2303 }
2304
2305 /*******************************************************************************/
2306
vcd_cleanup(void)2307 static void vcd_cleanup(void)
2308 {
2309 struct slist *s, *s2;
2310
2311 if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; }
2312 s=GLOBALS->slistroot;
2313 while(s)
2314 {
2315 s2=s->next;
2316 if(s->str)free_2(s->str);
2317 free_2(s);
2318 s=s2;
2319 }
2320
2321 GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0;
2322 }
2323
2324 /*******************************************************************************/
2325
vcd_partial_main(char * fname)2326 TimeType vcd_partial_main(char *fname)
2327 {
2328 unsigned int shmidu = ~(0L);
2329 int shmid;
2330
2331 GLOBALS->pv_vcd_partial_c_2=GLOBALS->rootv_vcd_partial_c_2=NULL;
2332 GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter;
2333
2334 errno=0; /* reset in case it's set for some reason */
2335
2336 GLOBALS->yytext_vcd_partial_c_2=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_partial_c_2+1);
2337
2338 if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */
2339 {
2340 GLOBALS->hier_delimeter='.';
2341 }
2342
2343 #ifdef __MINGW32__
2344 if(GetEnvironmentVariable("SHMID", NULL, 0))
2345 {
2346 char sEnv[128];
2347 GetEnvironmentVariable("SHMID", sEnv, 128);
2348 sscanf(sEnv, "%x", &shmidu);
2349 }
2350 else
2351 #endif
2352 {
2353 if(!strcmp(fname, "-vcd"))
2354 {
2355 if(!fscanf(stdin, "%x", &shmidu)) shmidu = ~(0L); /* allow use of -v flag to pass straight from stdin */
2356 }
2357 else
2358 {
2359 sscanf(fname, "%x", &shmidu); /* passed as a filename */
2360 }
2361 }
2362
2363 shmid = (int)shmidu;
2364
2365 #if !defined _MSC_VER
2366 #ifdef __MINGW32__
2367 {
2368 HANDLE hMapFile;
2369 char mapName[257];
2370
2371 sprintf(mapName, "shmidcat%d", shmid);
2372 hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapName);
2373 if(hMapFile == NULL)
2374 {
2375 fprintf(stderr, "Could not attach shared memory map name '%s', exiting.\n", mapName);
2376 exit(255);
2377 }
2378 GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->buf_vcd_partial_c_2 = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE);
2379 if(GLOBALS->consume_ptr_vcd_partial_c_1 == NULL)
2380 {
2381 fprintf(stderr, "Could not map view of file '%s', exiting.\n", mapName);
2382 exit(255);
2383 }
2384 }
2385 #else
2386 errno = 0;
2387 GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->buf_vcd_partial_c_2 = shmat(shmid, NULL, 0);
2388 if(errno)
2389 {
2390 fprintf(stderr, "Could not attach shared memory ID %08x\n", shmid);
2391 perror("Why");
2392 exit(255);
2393 }
2394 #endif
2395 #else
2396 fprintf(stderr, "Interactive VCD mode does not work with Windows, exiting.\n");
2397 exit(255);
2398 #endif
2399
2400 sym_hash_initialize(GLOBALS);
2401 getch_alloc(); /* alloc membuff for vcd getch buffer */
2402 build_slisthier();
2403
2404 GLOBALS->vcd_preserve_glitches = 1; /* splicing dictates that we override */
2405 while(!GLOBALS->header_over_vcd_partial_c_2) { vcd_parse(); }
2406
2407 if(GLOBALS->varsplit_vcd_partial_c_2)
2408 {
2409 free_2(GLOBALS->varsplit_vcd_partial_c_2);
2410 GLOBALS->varsplit_vcd_partial_c_2=NULL;
2411 }
2412
2413 if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2))
2414 {
2415 fprintf(stderr, "No symbols in VCD file..is it malformed? Exiting!\n");
2416 exit(1);
2417 }
2418
2419 add_tail_histents();
2420 vcd_build_symbols();
2421 vcd_sortfacs();
2422 vcd_cleanup();
2423
2424 GLOBALS->min_time=GLOBALS->start_time_vcd_partial_c_2*GLOBALS->time_scale;
2425 GLOBALS->max_time=GLOBALS->end_time_vcd_partial_c_2*GLOBALS->time_scale;
2426 GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale;
2427
2428 if((GLOBALS->min_time==GLOBALS->max_time)||(GLOBALS->max_time==0))
2429 {
2430 GLOBALS->min_time = GLOBALS->max_time = 0;
2431 }
2432
2433 GLOBALS->is_vcd=~0;
2434 GLOBALS->partial_vcd = ~0;
2435
2436 #ifdef __linux__
2437 {
2438 struct shmid_ds ds;
2439 shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */
2440 }
2441 #endif
2442
2443 return(GLOBALS->max_time);
2444 }
2445
2446 /*******************************************************************************/
2447
regen_harray(Trptr t,nptr nd)2448 static void regen_harray(Trptr t, nptr nd)
2449 {
2450 int i, histcount;
2451 hptr histpnt;
2452 hptr *harray;
2453
2454 if(!nd->harray) /* make quick array lookup for aet display */
2455 {
2456 histpnt=&(nd->head);
2457 histcount=0;
2458
2459 while(histpnt)
2460 {
2461 histcount++;
2462 histpnt=histpnt->next;
2463 }
2464
2465 nd->numhist=histcount;
2466
2467 if(!(nd->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr))))
2468 {
2469 fprintf( stderr, "Out of memory, can't add %s to analyzer\n",
2470 nd->nname );
2471 free_2(t);
2472 return; /* scan-build : really can't do anything here */
2473 }
2474
2475 histpnt=&(nd->head);
2476 for(i=0;i<histcount;i++)
2477 {
2478 *harray=histpnt;
2479
2480 /* printf("%s, time: %d, val: %d\n", nd->nname,
2481 (*harray)->time, (*harray)->val); */
2482
2483 harray++;
2484 histpnt=histpnt->next;
2485 }
2486 }
2487 }
2488
2489 /* mark vectors that need to be regenerated */
regen_trace_mark(Trptr t,int mandclear)2490 static void regen_trace_mark(Trptr t, int mandclear)
2491 {
2492 if(t->vector)
2493 {
2494 bvptr b = t->n.vec;
2495 bptr bts = b->bits;
2496 int i;
2497
2498 if(1)
2499 {
2500 for(i=0;i<bts->nnbits;i++)
2501 {
2502 if(!bts->nodes[i]->expansion)
2503 {
2504 if(bts->nodes[i]->harray)
2505 {
2506 free_2(bts->nodes[i]->harray);
2507 bts->nodes[i]->harray = NULL;
2508 }
2509 }
2510 else
2511 {
2512 t->interactive_vector_needs_regeneration = 1;
2513 }
2514 }
2515 }
2516
2517 for(i=0;i<bts->nnbits;i++)
2518 {
2519 if(!bts->nodes[i]->harray)
2520 {
2521 t->interactive_vector_needs_regeneration = 1;
2522 return;
2523 }
2524 }
2525 }
2526 else
2527 {
2528 if(t->n.nd) /* comment and blank traces don't have a valid node */
2529 if((t->n.nd->harray) && (mandclear))
2530 {
2531 free_2(t->n.nd->harray);
2532 t->n.nd->harray = NULL;
2533 }
2534 }
2535 }
2536
2537 /* sweep through and regen nodes/dirty vectors */
regen_trace_sweep(Trptr t)2538 static void regen_trace_sweep(Trptr t)
2539 {
2540 if(!t->vector)
2541 {
2542 if(t->n.nd) /* comment and blank traces don't have a valid node */
2543 if(!t->n.nd->harray)
2544 {
2545 regen_harray(t, t->n.nd);
2546 }
2547 }
2548 else if(t->interactive_vector_needs_regeneration)
2549 {
2550 bvptr b = t->n.vec;
2551 bptr bts = b->bits;
2552 int i;
2553 bvptr b2;
2554
2555 for(i=0;i<bts->nnbits;i++)
2556 {
2557 if(bts->nodes[i]->expansion)
2558 {
2559 nptr parent = bts->nodes[i]->expansion->parent;
2560 int parentbit = bts->nodes[i]->expansion->parentbit;
2561
2562 DeleteNode(bts->nodes[i]);
2563
2564 bts->nodes[i] = ExtractNodeSingleBit(parent, parentbit);
2565 }
2566
2567 if(!bts->nodes[i]->harray)
2568 {
2569 regen_harray(t, bts->nodes[i]);
2570 }
2571 }
2572
2573 if(!bts->name)
2574 {
2575 bts->name = "";
2576 b2 = bits2vector(bts);
2577 bts->name = NULL;
2578 }
2579 else
2580 {
2581 b2 = bits2vector(bts);
2582 }
2583
2584 t->n.vec = b2;
2585 b2->bits=bts;
2586
2587 free_2(b2->bvname);
2588 b2->bvname = b->bvname;
2589
2590 for(i=0;i<b->numregions;i++)
2591 {
2592 free_2(b->vectors[i]);
2593 }
2594
2595 free_2(b);
2596 }
2597 }
2598
2599 /*******************************************************************************/
2600
kick_partial_vcd(void)2601 void kick_partial_vcd(void)
2602 {
2603 #if !defined _MSC_VER
2604
2605 if(GLOBALS->partial_vcd)
2606 {
2607 #ifdef __MINGW32__
2608 Sleep(10);
2609 #else
2610 struct timeval tv;
2611
2612 tv.tv_sec = 0;
2613 tv.tv_usec = 1000000 / 100;
2614 select(0, NULL, NULL, NULL, &tv);
2615 #endif
2616
2617 while(*GLOBALS->consume_ptr_vcd_partial_c_1)
2618 {
2619 int old_maxtime_marker_conflict = (GLOBALS->tims.marker > GLOBALS->max_time);
2620
2621 vcd_parse();
2622
2623 GLOBALS->min_time=GLOBALS->start_time_vcd_partial_c_2*GLOBALS->time_scale;
2624 GLOBALS->max_time=GLOBALS->end_time_vcd_partial_c_2*GLOBALS->time_scale;
2625
2626 GLOBALS->tims.last=GLOBALS->max_time;
2627 GLOBALS->tims.end=GLOBALS->tims.last; /* until the configure_event of wavearea */
2628
2629 if(!GLOBALS->timeset_vcd_partial_c_1)
2630 {
2631 GLOBALS->tims.first=GLOBALS->tims.start=GLOBALS->tims.laststart=GLOBALS->min_time;
2632 GLOBALS->timeset_vcd_partial_c_1 = 1;
2633 }
2634
2635 update_endcap_times_for_partial_vcd();
2636 update_maxmarker_labels();
2637
2638 if(old_maxtime_marker_conflict)
2639 {
2640 old_maxtime_marker_conflict = (GLOBALS->tims.marker<=GLOBALS->max_time); /* data is now past what was invisible marker */
2641 }
2642
2643 vcd_partial_mark_and_sweep(1);
2644
2645 if ((GLOBALS->zoom_dyn) && (!GLOBALS->helpbox_is_active))
2646 {
2647 GLOBALS->tims.marker = GLOBALS->tims.last;
2648 service_zoom_full(NULL, NULL);
2649
2650 GLOBALS->signalwindow_width_dirty=1;
2651 MaxSignalLength();
2652 signalarea_configure_event(GLOBALS->signalarea, NULL);
2653 }
2654 else if ((GLOBALS->zoom_dyne) && (!GLOBALS->helpbox_is_active))
2655 {
2656 GLOBALS->tims.marker = GLOBALS->tims.last;
2657 service_zoom_right(NULL, NULL);
2658
2659 GLOBALS->signalwindow_width_dirty=1;
2660 MaxSignalLength();
2661 signalarea_configure_event(GLOBALS->signalarea, NULL);
2662 }
2663 else if ((old_maxtime_marker_conflict) && (!GLOBALS->helpbox_is_active))
2664 {
2665 GLOBALS->signalwindow_width_dirty=1;
2666 MaxSignalLength();
2667 signalarea_configure_event(GLOBALS->signalarea, NULL);
2668 wavearea_configure_event(GLOBALS->wavearea, NULL);
2669 }
2670 else
2671 {
2672 signalarea_configure_event(GLOBALS->signalarea, NULL);
2673 wavearea_configure_event(GLOBALS->wavearea, NULL);
2674 }
2675
2676 update_maxmarker_labels();
2677
2678 gtkwave_main_iteration();
2679 }
2680 }
2681
2682 #endif
2683
2684 gtkwave_main_iteration();
2685 }
2686
2687
vcd_partial_regen_node_expansion(Trptr t)2688 static void vcd_partial_regen_node_expansion(Trptr t)
2689 {
2690 if(!t->vector)
2691 {
2692 if(t->n.nd && t->n.nd->expansion)
2693 {
2694 nptr np_ex = ExtractNodeSingleBit(t->n.nd->expansion->parent, t->n.nd->expansion->parentbit);
2695
2696 DeleteNode(t->n.nd);
2697 t->n.nd = np_ex;
2698 t->name_full = np_ex->nname;
2699 t->name = (GLOBALS->hier_max_level) ? hier_extract(t->name_full, GLOBALS->hier_max_level) : t->name_full;
2700 }
2701 }
2702
2703 }
2704
vcd_partial_mark_and_sweep(int mandclear)2705 void vcd_partial_mark_and_sweep(int mandclear)
2706 {
2707 Trptr t;
2708
2709
2710
2711 /* node */
2712 t = GLOBALS->traces.first; while(t) { if(!t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2713 t = GLOBALS->traces.buffer; while(t) { if(!t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2714
2715 t = GLOBALS->traces.first; while(t) { if(!t->vector) regen_trace_sweep(t); t = t->t_next; }
2716 t = GLOBALS->traces.buffer; while(t) { if(!t->vector) regen_trace_sweep(t); t = t->t_next; }
2717
2718 /* node that is single bit extracted */
2719 t = GLOBALS->traces.first; while(t) { vcd_partial_regen_node_expansion(t); t = t->t_next; }
2720 t = GLOBALS->traces.buffer; while(t) { vcd_partial_regen_node_expansion(t); t = t->t_next; }
2721
2722 /* vector */
2723 t = GLOBALS->traces.first; while(t) { if(t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2724 t = GLOBALS->traces.buffer; while(t) { if(t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2725
2726 t = GLOBALS->traces.first; while(t) { if(t->vector) regen_trace_sweep(t); t = t->t_next; }
2727 t = GLOBALS->traces.buffer; while(t) { if(t->vector) regen_trace_sweep(t); t = t->t_next; }
2728
2729 /* floating point */
2730 t = GLOBALS->traces.first; while(t) { if(t->minmax_valid) t->minmax_valid = 0; t = t->t_next; }
2731 t = GLOBALS->traces.buffer; while(t) { if(t->minmax_valid) t->minmax_valid = 0; t = t->t_next; }
2732 }
2733