1 /* Copyright (c) 1991-2004 Pragmatic C Software Corp. */
2
3 /*
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
17 */
18
19 #define VERS2 "0.04a"
20 #define OFDT "07/28/2004"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <fcntl.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <ctype.h>
28 #include <time.h>
29 #include <string.h>
30 #include "vcddiff.h"
31
32 static int get_token(FILE *, char *);
33 static void read_to_end(FILE *);
34 static char timescale(FILE *, int *);
35 static void add_signal(char *, char *, unsigned int, int, int);
36 static int get_var_type(char *);
37 static void variable(FILE *, char *);
38 static void alloc_sig_mem(void);
39 static int get_vkeywrd(register char *);
40 static long get_lines(FILE *, int *, int *, char *);
41 static void print_signal_info(struct signal_t *, struct signal_t *, vtime_t,
42 vtime_t, bool_t);
43 static void print_scalar_state(struct signal_t *, struct signal_t *, vtime_t,
44 vtime_t, char, char, bool_t);
45 static void print_vector_state(struct signal_t *, struct signal_t *, vtime_t,
46 vtime_t, char *, char *, bool_t);
47 static void print_scalar_edge(struct signal_t *, struct signal_t *, vtime_t,
48 vtime_t, char, char, bool_t);
49 static void print_edges(struct signal_t *, char *, int, int, char);
50 static void print_vector_edge(struct signal_t *, struct signal_t *, vtime_t,
51 vtime_t, char *, char *, bool_t);
52 static int get_nxt_chg(FILE *, char *, int *, int *, char *, vtime_t *,
53 bool_t);
54 static vtime_t get_time_diffs(FILE *, FILE *, char *, char *, long, long,
55 vtime_t, vtime_t, bool_t);
56 static void print_map(void);
57 static void compare_types(char *, char *, struct signal_t *, struct signal_t *);
58 static bool_t map(char *, char *, int **, struct signal_t *,
59 struct signal_t *, struct signal_t **, bool_t);
60 static bool_t map_var_names(char *, char *);
61 static void run_diffs(FILE *, FILE *, char *, char *, long, long);
62 static void print_header(void);
63 static void print_help(void);
64 static void edge_space(int, int , bool_t);
65
66 /* globals */
67 static int line_num1G; /* cur position of file1 */
68 static int line_num2G; /* cur position of file2 */
69 static char curmodG[1000]; /* cur mod hier name */
70 static FILE *file1G; /* to check if it is the first file */
71 static bool_t state_flagG; /* print edges or states */
72 static bool_t wrap_flagG; /* print edges or states */
73 static struct signal_t **sig_int1G; /* int codes for file 1 */
74 static struct signal_t **sig_int2G; /* int codes for file 2 */
75 static int **fd1_to_fd2_mapG; /* mappings from one file to the other*/
76 static int **fd2_to_fd1_mapG;
77 static int max_codeG; /* max code so sig_int? is large enough */
78 static char scopesG[MAXSCOPES][MAXSIG]; /* scope of mods */
79 static int quit_flagG; /* flag to quit */
80 static bool_t next_listG; /* to signal the next list of signals */
81 struct signal_t *sig1_hdG; /* the head of the first file of signals */
82 struct signal_t *sig2_hdG; /* the head of the second file of signals */
83 struct signal_t *lastsigG; /* mark the last signal of the file */
84
85 /* signal to code from dinotrace wave viewer www.veripool.com/dinotrace */
86 #define VERILOG_ID_TO_POS(_code_) \
87 (_code_[0]?((_code_[0]-32) + 94 * \
88 (_code_[1]?((_code_[1]-32) + 94 * \
89 (_code_[2]?((_code_[2]-32) + 94 * \
90 (_code_[3]?((_code_[3]-32) \
91 ):0) \
92 ):0) \
93 ):0) \
94 ):0)
95
96 #define VERILOG_POS_TO_SIG1(_pos_) \
97 (((_pos_)<max_codeG)?sig_int1G[(_pos_)]:0)
98
99 #define VERILOG_POS_TO_SIG2(_pos_) \
100 (((_pos_)<max_codeG)?sig_int2G[(_pos_)]:0)
101 /**********************************************************************/
102
103 /*get a new token from the file fp, and place in token, return the length*/
get_token(FILE * fp,char * token)104 static int get_token(FILE *fp, char *token)
105 {
106 int i, c;
107
108 i = 0;
109 while((c = fgetc(fp)) != EOF)
110 {
111 if(isspace(c))
112 {
113 if(c == '\n')
114 {
115 if(fp == file1G) line_num1G++;
116 else line_num2G++;
117 }
118 continue;
119 }
120 break;
121 }
122
123 if(c == EOF) return EOF;
124 token[i++] = c;
125
126 while(!isspace(c = fgetc(fp)))
127 {
128 if(c == EOF)
129 return EOF;
130 else
131 token[i++] = c;
132 }
133 if(c == '\n')
134 {
135 if(fp == file1G) line_num1G++;
136 else line_num2G++;
137 }
138
139 token[i]='\0';
140 return i;
141 }
142
143 /*read the file until an $end is reached*/
read_to_end(FILE * fp)144 static void read_to_end(FILE *fp)
145 {
146 char token[MAXTOKSIZE];
147
148 while(get_token(fp, token) != EOF)
149 {
150 if(!strncmp (token, "$end", 4))
151 return;
152 }
153 }
154
155 /* get the timescale information for comparison return char of units, and
156 * the number 1, 10, 100 in tnum
157 * */
timescale(FILE * fp,int * tnum)158 static char timescale(FILE *fp, int *tnum)
159 {
160 int i, toklen;
161 char token[MAXTOKSIZE];
162 char tmp[MAXTOKSIZE];
163 char *tok;
164
165 toklen = get_token(fp, token);
166 tok = token;
167 /* AIV 02/04/03 there can be a space between 1 ns, not always 1ns */
168 for(i = 0; i <toklen; i++)
169 {
170 if(!isdigit(token[i])) break;
171 }
172 if(i == toklen)
173 {
174 get_token(fp, tmp);
175 strcat(token, tmp);
176 }
177
178 *tnum = atoi(tok);
179
180 if(*tnum != 1 && *tnum != 10 && *tnum != 100)
181 {
182 printf("*** ERROR-time number(%d) in timescale on line %d is illegal - assuming 1\n", *tnum, (fp == file1G) ? line_num1G : line_num2G );
183 *tnum = 1;
184 }
185
186 while(isdigit (*tok))
187 tok++;
188 if (!*tok)
189 get_token(fp, token);
190
191 switch (*tok) {
192 case 's':
193 case 'm':
194 case 'u':
195 case 'n':
196 case 'p':
197 case 'f':
198 return(*tok);
199 default:
200 printf("*** ERROR-illegal character(%c) in timescale on line %d\n", *tok, (fp == file1G) ? line_num1G : line_num2G );
201 return(0);
202 }
203 }
204
205 /* add a new signal to the list, init values signal name, identifies
206 * the code to index the array of signals, and the number of bits, if
207 * bits is 1 it is scalar
208 * */
add_signal(char * signame,char * ident,unsigned int code,int bits,int type)209 static void add_signal(char *signame,char *ident, unsigned int code,
210 int bits, int type)
211 {
212 char *cp;
213 struct signal_t *newsig;
214
215 /*get rid of scapes before and after*/
216 while(isspace(*signame)) signame++;
217 for (cp = signame + strlen(signame) - 1;cp >= signame && isspace(*cp); cp--) *cp = '\0';
218
219 newsig = (struct signal_t *) malloc(sizeof(struct signal_t));
220 newsig->sig_code = code;
221 newsig->ident = (char *) malloc(strlen(ident)+1);
222 /* init values to x's */
223 newsig->state = '?';
224 newsig->type = type;
225 newsig->in_both = TRUE;
226 newsig->size = bits;
227 newsig->next = NULL;
228
229 if(type == REAL)
230 {
231 /*FIXME what about large reals ???*/
232 newsig->vector = (char *) malloc(REALSIZE);
233 newsig->vector[0] = '0';
234 newsig->vector[1] = '\0';
235 }
236 else if(bits > 1)
237 {
238 newsig->vector = (char *) malloc(bits + 2);
239 newsig->vector[bits] = '\0';
240 bits--;
241 for(; bits >= 0; bits--)
242 newsig->vector[bits] = '?';
243 }
244
245 /*signal not found so print first diff*/
246 newsig->found = FALSE;
247 strcpy(newsig->ident, ident);
248 /*link signals for hash setup and mapping*/
249 if(lastsigG)
250 lastsigG->next= newsig;
251
252 if(sig1_hdG == NULL)
253 sig1_hdG = newsig;
254
255 if(next_listG && sig2_hdG == NULL)
256 sig2_hdG = newsig;
257
258 lastsigG = newsig;
259 newsig->signame = (char *) malloc(strlen(signame)+1);
260 strcpy(newsig->signame, signame);
261 max_codeG = MAX(max_codeG, code+1);
262 }
263
264
265 /*dump variable types must be kept in alphabetical order */
266 static struct variable_types_t var_types[] = {
267 {"event", EVENT },
268 {"integer", INTEGER},
269 {"parameter", PARAMETER},
270 {"real", REAL},
271 {"reg", REG},
272 {"supply0", SUPPLY0},
273 {"supply1", SUPPLY1},
274 {"time", TIME},
275 {"tri", TRI},
276 {"tri0", TRI0},
277 {"tri1", TRI1},
278 {"triand", TRIAND},
279 {"trior", TRIOR},
280 {"trireg", TRIREG},
281 {"wand", WAND},
282 {"wire", WIRE},
283 {"wor", WOR}
284 };
285
286
287 #define VARTYPE (sizeof(var_types) / sizeof(struct variable_types_t))
288
get_var_type(char * tstr)289 static int get_var_type(char *tstr)
290 {
291 int l, h;
292 register int m, cv;
293
294
295 l = 0; h = VARTYPE - 1;
296 for (;;)
297 {
298 m = (l + h)/2;
299 if((cv = strcmp(var_types[m].vnam, tstr)) == 0)
300 return(var_types[m].vnum);
301 if(cv < 0) l = m + 1; else h = m - 1;
302 if(h < l) break;
303 }
304 return(-1);
305
306 }
307
308 /*var line so add a new signal with its identifier*/
variable(FILE * fp,char * file_name)309 static void variable(FILE *fp, char *file_name)
310 {
311 char signame[MAXSIG];
312 char ident[10];
313 char token[MAXTOKSIZE];
314 int bits;
315 char type;
316
317 /*type, size*/
318 get_token(fp, token);
319 /*most ofter a reg otherwise do a search */
320 if(strncmp(token, "reg", 3) == 0)
321 type = REG;
322 else
323 type = get_var_type(token);
324
325 if(type < 0)
326 {
327 type = UNDEFINED;
328 printf("Error- Unknown variable type %s\n", token);
329 }
330
331 /* get number of bits */
332 /* AIV FIXME error recovery should be used here for invalid tokens
333 * if a $var line is short vars (starts with a '$') rewind, print
334 * message and return */
335 get_token(fp, token);
336 bits = atoi(token);
337
338 if(bits < 0)
339 {
340 printf ("Negative size illegal on line %d of %s\n", (fp == file1G) ? line_num1G : line_num2G, file_name);
341 return;
342 }
343
344 /*identifier*/
345 get_token(fp, token);
346 strcpy(ident, token);
347
348 /*variable name*/
349 get_token(fp, token);
350 strcpy (signame, curmodG);
351 strcat (signame, token);
352
353
354 get_token(fp, token);
355 /*if there is a space between the var name and the range concat it
356 * to the name */
357 if (token[0] != '$')
358 strcat (signame, token);
359
360 add_signal(signame, ident, VERILOG_ID_TO_POS(ident), bits, type);
361 }
362
363
364 /* setup memory for the hash of signals, which is the max of all signals,
365 * then setup up arrays according to the signal's code index
366 */
alloc_sig_mem(void)367 static void alloc_sig_mem(void)
368 {
369 struct signal_t *sig;
370
371 sig_int1G = (struct signal_t **) calloc(sizeof(struct signal_t *), (max_codeG + 1));
372 for (sig = sig1_hdG; sig !=NULL; sig = sig->next)
373 sig_int1G[sig->sig_code] = sig;
374
375 sig_int2G = (struct signal_t **) calloc(sizeof(struct signal_t *), (max_codeG + 1));
376 for (sig = sig2_hdG; sig !=NULL; sig = sig->next)
377 sig_int2G[sig->sig_code] = sig;
378
379 }
380
381 /*dump file keywords must be kept in alphabetical order */
382 static struct variable_types_t vkeywds[] = {
383 { "comment", V_COMMENT},
384 { "date", V_DATE },
385 { "end", V_END },
386 { "enddefinitions", V_ENDDEF},
387 { "scope", V_SCOPE},
388 { "timescale", V_TIMESCALE },
389 { "upscope", V_UPSCOPE },
390 { "var", V_VAR },
391 { "version", V_VERSION }
392 };
393
394 #define VKEYWDS (sizeof(vkeywds) / sizeof(struct variable_types_t))
395
396 /*search for verilog keywords*/
get_vkeywrd(register char * tstr)397 static int get_vkeywrd(register char *tstr)
398 {
399 int l, h;
400 register int m, cv;
401
402 //start at $end
403 l = -2; h = VKEYWDS - 1;
404 for (;;)
405 {
406 m = (l + h)/2;
407 if((cv = strcmp(vkeywds[m].vnam, tstr)) == 0)
408 return(vkeywds[m].vnum);
409 if(cv < 0) l = m + 1; else h = m - 1;
410 if(h < l) break;
411 }
412 return(EOF);
413 }
414
415
416 /* process all the lines until $enddef is reached, determines all variable
417 * names, seperated by a '.' between scopes, place the timescale number
418 * and units, and return the file location to start processing diffs
419 */
get_lines(FILE * fp,int * units,int * tnum,char * file_name)420 static long get_lines(FILE *fp, int *units, int *tnum, char *file_name)
421 {
422 char sep[2];
423 int level;
424 register int i;
425 char *tok;
426 char token[MAXTOKSIZE];
427
428 sep[0] = '.';
429 sep[1] = '\0';
430 level = 0;
431 *units = 1;
432
433 while(get_token(fp, token) != EOF)
434 {
435 tok = token;
436 if(tok[0] != '$')
437 {
438 printf ("***ERROR Unknown token '%s' on line %d of %s\n",
439 tok, (fp == file1G) ? line_num1G: line_num2G, file_name);
440 continue;
441 }
442 tok++;
443
444 switch(get_vkeywrd(tok)){
445 case V_END:
446 break;
447
448 case V_VAR:
449 variable(fp, file_name);
450 break;
451
452 case V_UPSCOPE:
453 if(level > 0) level--;
454 break;
455
456 case V_SCOPE:
457 get_token(fp, tok);
458 get_token(fp, tok);
459
460 if(level < MAXSCOPES)
461 {
462 strcpy(scopesG[level], tok);
463
464 strcpy(curmodG, scopesG[0]);
465 strcat(curmodG, sep);
466 level++;
467
468 if(level)
469 {
470 for (i=1; i<level; i++) {
471 strcat(curmodG, scopesG[i]);
472 strcat(curmodG, sep);
473 }
474 }
475
476 }
477 else
478 {
479 printf("*** ERROR-exceeded max scope levels %d\n", level);
480 exit(0);
481 }
482 break;
483 case V_COMMENT:
484 case V_DATE:
485 case V_VERSION:
486 read_to_end(fp);
487 break;
488
489 case V_TIMESCALE:
490 *units = timescale(fp, tnum);
491 break;
492
493 case V_ENDDEF:
494 next_listG = TRUE;
495 lastsigG = NULL;
496 return(ftell(fp));
497
498 default:
499 printf ("Unknown command '%s' on line %d of %s\n",
500 tok, (fp == file1G) ? line_num1G: line_num2G, file_name);
501 break;
502
503 }
504 }
505 return(-1);
506 }
507
508 /* print the diff signal information */
print_signal_info(struct signal_t * sig1,struct signal_t * sig2,vtime_t time1,vtime_t time2,bool_t isone)509 static void print_signal_info(struct signal_t *sig1,
510 struct signal_t *sig2,
511 vtime_t time1, vtime_t time2, bool_t isone)
512 {
513
514 if(time1 == time2)
515 {
516
517 if(sig1->sig_code == sig2->sig_code)
518 printf("%s (%s) differs at time %lld\n", sig1->signame,sig1->ident, time1);
519 else
520 printf("%s (%s , %s) differs at time %lld\n", sig1->signame,
521 sig1->ident, sig2->ident, time1);
522 return;
523 }
524 else
525 {
526 if(sig1->sig_code == sig2->sig_code)
527 printf("%c %s (%s) at time %lld next occurence at time %lld\n", isone ? '>' : '<', sig1->signame, sig1->ident, time1, time2);
528 else
529 printf("%c %s (%s, %s) at time %lld next occurence at time %lld\n", isone ? '>' : '<', sig1->signame,sig1->ident, sig2->ident, time1, time2);
530 return;
531 }
532
533 }
534
535
536
537 /* print the scalar value */
print_scalar_state(struct signal_t * sig1,struct signal_t * sig2,vtime_t time1,vtime_t time2,char state1,char state2,bool_t isone)538 static void print_scalar_state(struct signal_t *sig1,
539 struct signal_t *sig2,
540 vtime_t time1, vtime_t time2,
541 char state1, char state2, bool_t isone)
542 {
543
544 if(time1 == time2)
545 {
546 sig1->found = TRUE;
547 sig2->found = TRUE;
548 if(state1 != state2)
549 {
550 print_signal_info(sig1, sig2, time1, time2, isone);
551 printf("\t%c\n\t%c\n",state1, state2);
552 return;
553 }
554 }
555 else
556 {
557 print_signal_info(sig1, sig2, time1, time2, isone);
558 printf("%c #%lld \t%c\n", isone ? '>' : '<', time1, state1);
559 printf("%c #%lld \t%c\n", isone ? '>' : '<', time2, state2);
560 return;
561 }
562 }
563
564
565 /* print the vector value */
print_vector_state(struct signal_t * sig1,struct signal_t * sig2,vtime_t time1,vtime_t time2,char * sval1,char * sval2,bool_t isone)566 static void print_vector_state(struct signal_t *sig1,
567 struct signal_t *sig2,
568 vtime_t time1, vtime_t time2,
569 char *sval1, char *sval2, bool_t isone)
570 {
571 int size1, size2;
572 register int i;
573
574 size1 = strlen(sval1);
575 size2 = strlen(sval2);
576 if(time1 == time2)
577 {
578 sig1->found = TRUE;
579 sig2->found = TRUE;
580 if(strcmp(sval1, sval2) != 0)
581 {
582 print_signal_info(sig1, sig2, time1, time2, isone);
583 if(size1 == size2)
584 printf("\t%s\n\t%s\n", sval1, sval2);
585 else
586 {
587 if(size1 > size2)
588 {
589 printf("\t%s\n\t", sval1);
590 for(i = 0; i < size1 - size2; i++)
591 putc(' ', stdout);
592 printf("%s\n", sval2);
593 }
594 else
595 {
596 printf("\t");
597 for(i = 0; i < size2-size1; i++)
598 putc(' ', stdout);
599 printf("%s\n\t%s\n", sval1, sval2);
600 }
601 }
602 return;
603 }
604 }
605 else
606 {
607 print_signal_info(sig1, sig2, time1, time2, isone);
608 if(size1 == size2)
609 {
610 printf("%c #%lld \t%s\n", isone ? '>' : '<', time1, sval1);
611 printf("%c #%lld \t%s\n", isone ? '>' : '<', time2, sval2);
612 }
613 else
614 {
615 if(size1 > size2)
616 {
617 printf("%c #%lld \t%s\n", isone ? '>' : '<', time1, sval1);
618 printf("%c #%lld \t", isone ? '>' : '<', time2);
619 for(i = 0; i < size1 - size2; i++)
620 putc(' ', stdout);
621 printf("%s\n", sval2);
622 }
623 else
624 {
625 printf("%c #%lld \t", isone ? '>' : '<', time1);
626 for(i = 0; i < size2-size1; i++)
627 putc(' ', stdout);
628 printf("%s\n", sval1);
629 printf("%c #%lld \t%s\n", isone ? '>' : '<', time2, sval2);
630 }
631 }
632 }
633 }
634
635
636
637 /* print scalar edge value */
print_scalar_edge(struct signal_t * sig1,struct signal_t * sig2,vtime_t time1,vtime_t time2,char state1,char state2,bool_t isone)638 static void print_scalar_edge(struct signal_t *sig1,
639 struct signal_t *sig2,
640 vtime_t time1, vtime_t time2,
641 char state1, char state2, bool_t isone)
642 {
643
644 if(time1 == time2)
645 {
646 sig1->found = TRUE;
647 sig2->found = TRUE;
648 if(state1 != state2)
649 {
650 print_signal_info(sig1, sig2, time1, time2, isone);
651
652 if(sig1->state == state1)
653 printf("\t(%c-)\n", state1);
654 else
655 printf("\t(%c%c)\n", sig1->state, state1);
656 if(sig2->state == state2)
657 printf("\t(%c-)\n", state2);
658 else
659 printf("\t(%c%c)\n", sig2->state, state2);
660 return;
661 }
662 }
663 else
664 {
665 print_signal_info(sig1, sig2, time1, time2, isone);
666
667 if(sig1->state == state1)
668 printf("%c #%lld \t(%c-)\n", isone ? '>' : '<', time1, state1);
669 else
670 printf("%c #%lld \t(%c%c)\n", isone ? '>' : '<', time1, sig1->state, state1);
671 if(sig2->state == state2)
672 printf("%c #%lld \t(%c-)\n", isone ? '>' : '<', time2, state2);
673 else
674 printf("%c #%lld \t(%c%c)\n", isone ? '>' : '<', time2, sig2->state, state2);
675 return;
676 }
677 }
678
679 /* print the edge values
680 sig - signal pointer
681 sval - sval string value
682 str_size - size of sval
683 search - '<' or '>' if a search was performed otherwise 'n' for none
684 this is needed for wrapping of the line
685 */
print_edges(struct signal_t * sig,char * sval,int str_size,int vec_size,char searchc)686 static void print_edges(struct signal_t *sig, char *sval, int str_size,
687 int vec_size, char searchc)
688 {
689 register int i;
690 int min, tprint;
691
692 /*AIV 02/06/03 the print edges were wrong for different sizes */
693 /* for example, b10 is now b101 at the next time */
694 /* vector is the old value and sval is the new */
695
696 if(str_size > vec_size)
697 min = vec_size;
698 else
699 min = str_size;
700
701 tprint = 0;
702 for(i=0; i < min; i++, tprint++)
703 {
704 if(sig->vector[i] == sval[i])
705 printf(" (%c-)", sig->vector[i]);
706 else
707 printf(" (%c%c)", sig->vector[i], sval[i]);
708
709 /* only want to print 11 edges per line */
710 if(wrap_flagG && tprint != 0 && !(tprint % EDGE_PER_LINE))
711 {
712 if(searchc != 'n')
713 printf(" \\\n%c\t", searchc);
714 else
715 printf(" \\\n\t");
716 }
717 }
718 if(str_size == vec_size) return;
719
720 if(min == vec_size)
721 {
722 for(i = min; i < str_size; i++, tprint++)
723 {
724 printf(" (?%c)", sval[i]);
725 if(wrap_flagG && tprint != 0 && !(tprint % EDGE_PER_LINE))
726 {
727 if(searchc != 'n')
728 printf(" \\\n%c\t", searchc);
729 else
730 printf(" \\\n\t");
731 }
732 }
733 }
734 else
735 {
736 /* if the first value is a '?', no need to print the rest
737 * since it can only be '?' on the first value change */
738 if(sig->vector[0] != '?')
739 {
740 for(i = min; i < vec_size; i++, tprint++)
741 {
742 printf(" (%c?)", sig->vector[i]);
743 if(wrap_flagG && tprint != 0 && !(tprint % EDGE_PER_LINE))
744 {
745 if(searchc != 'n')
746 printf(" \\\n%c\t", searchc);
747 else
748 printf(" \\\n\t");
749 }
750 }
751 }
752 }
753
754 }
755
756 /* add space so the vector edge valued line up correctly */
edge_space(int size1,int size2,bool_t is_sigone)757 static void edge_space(int size1, int size2, bool_t is_sigone)
758 {
759 register int i, r, diff;
760
761 if(size1 == size2) return;
762 if(is_sigone && size2 > size1)
763 {
764 diff = (size2 - size1) * CHAR_PER_EDGE;
765 if(wrap_flagG)
766 {
767 r = diff / EDGE_PER_LINE;
768 if(r > 0)
769 {
770 r = (r * EDGE_PER_LINE);
771 diff -= r;
772 if(diff <= CHAR_PER_EDGE) diff = 0;
773 }
774 }
775 for(i=0; i < diff; i++)
776 putc(' ', stdout);
777 }
778 if(!is_sigone && size1 > size2)
779 {
780 diff = (size1 - size2) * CHAR_PER_EDGE;
781 if(wrap_flagG)
782 {
783 r = diff / EDGE_PER_LINE;
784 if(r > 0)
785 {
786 r = (r * EDGE_PER_LINE);
787 diff -= r;
788 if(diff <= CHAR_PER_EDGE) diff = 0;
789 }
790 }
791 for(i=0; i < diff; i++)
792 putc(' ', stdout);
793 }
794
795 }
796
797
798
799
800 /* print vector edge */
print_vector_edge(struct signal_t * sig1,struct signal_t * sig2,vtime_t time1,vtime_t time2,char * sval1,char * sval2,bool_t isone)801 static void print_vector_edge(struct signal_t *sig1,
802 struct signal_t *sig2,
803 vtime_t time1, vtime_t time2,
804 char *sval1, char *sval2, bool_t isone)
805 {
806 int size1, size2;
807 int vsize1, vsize2;
808 int max1, max2;
809 char dirc;
810
811 if(time1 == time2)
812 {
813 sig1->found = TRUE;
814 sig2->found = TRUE;
815
816 if(strcmp(sval1, sval2) != 0)
817 {
818
819 if(sig1->type == REAL)
820 {
821 print_vector_state(sig1, sig2, time1, time2, sval1, sval2, isone);
822 return;
823 }
824
825 print_signal_info(sig1, sig2, time1, time2, isone);
826 printf("\t");
827
828 size1 = strlen(sval1);
829 vsize1 = strlen(sig1->vector);
830 max1 = MAX(size1, vsize1);
831
832 size2 = strlen(sval2);
833 vsize2 = strlen(sig2->vector);
834 max2 = MAX(size2, vsize2);
835
836 edge_space(max1, max2, TRUE);
837 print_edges(sig1, sval1, size1, vsize1, 'n');
838 if(wrap_flagG && sig1->size > EDGE_PER_LINE)
839 printf("\n\n\t");
840 else
841 printf("\n\t");
842 edge_space(max1, max2, FALSE);
843 print_edges(sig2, sval2, size2, vsize2, 'n');
844 printf("\n");
845 return;
846 }
847 }
848 else
849 {
850 if(sig1->type == REAL)
851 {
852 print_vector_state(sig1, sig2, time1, time2, sval1, sval2, isone);
853 return;
854 }
855 print_signal_info(sig1, sig2, time1, time2, isone);
856 dirc = isone ? '>' : '<';
857 printf("%c #%lld \t", dirc, time1);
858
859 size1 = strlen(sval1);
860 vsize1 = strlen(sig1->vector);
861 max1 = MAX(size1, vsize1);
862
863 size2 = strlen(sval2);
864 vsize2 = strlen(sig2->vector);
865 max2 = MAX(size2, vsize2);
866
867 edge_space(max1, max2, TRUE);
868 print_edges(sig1, sval1, size1, vsize1, dirc);
869 printf("\n%c #%lld \t", dirc, time2);
870 edge_space(max1, max2, FALSE);
871 print_edges(sig2, sval2, size2, vsize2, dirc);
872 printf("\n");
873 return;
874 }
875 }
876
877 /* get the next time change in the other file if there is one */
get_nxt_chg(FILE * fp,char * fname,int * sigcode,int * bit,char * value,vtime_t * time,bool_t isone)878 static int get_nxt_chg(FILE *fp, char *fname, int *sigcode, int *bit,
879 char *value, vtime_t *time, bool_t isone)
880 {
881 char *line;
882 char token[MAXTOKSIZE];
883
884 while(get_token(fp, token) != EOF)
885 {
886 line = token;
887
888 switch (*line++)
889 {
890 /* scalar cases */
891 case '0':
892 case '1':
893 case 'z':
894 case 'Z':
895 case 'x':
896 case 'X':
897 *bit = *(line-1);
898 *sigcode = VERILOG_ID_TO_POS(line);
899
900 if(isone)
901 {
902 if(VERILOG_POS_TO_SIG1(*sigcode) == NULL)
903 {
904 printf("Unknown Identifier '%s' in file %d '%s' on line %d\n",
905 line, isone ? 1 : 2, fname,
906 isone ? line_num1G : line_num2G );
907 continue;
908 }
909 }
910 else if(VERILOG_POS_TO_SIG2(*sigcode) == NULL)
911 {
912 printf("Unknown Identifier '%s' in file %d '%s' on line %d\n",
913 line, isone ? 1 : 2, fname,
914 isone ? line_num1G : line_num2G );
915 continue;
916 }
917 return(SCALAR);
918 break;
919 /* vector or real cases */
920 case 'b':
921 case 'r':
922 strcpy(value, line);
923 get_token(fp, token);
924 *sigcode = VERILOG_ID_TO_POS(token);
925 if(isone)
926 {
927 if(VERILOG_POS_TO_SIG1(*sigcode) == NULL)
928 {
929 printf("Unknown Identifier '%s' in file %d '%s' on line %d\n",
930 line, isone ? 1 : 2, fname,
931 isone ? line_num1G : line_num2G );
932 continue;
933 }
934 }
935 else if(VERILOG_POS_TO_SIG2(*sigcode) == NULL)
936 {
937 printf("Unknown Identifier '%s' in file %d '%s' on line %d\n",
938 line, isone ? 1 : 2, fname,
939 isone ? line_num1G : line_num2G );
940 continue;
941 }
942 return(VECTOR);
943
944 /* time change value */
945 case '#':
946 *time = (vtime_t) atoll(line);
947 return(TIME);
948 case '$':
949 /* AIV 02/03/03 need to read until $end for $comment */
950 if(!strcmp(line, "comment") || !strcmp(line, "dumpall"))
951 read_to_end(fp);
952 break;
953 default:
954 line--;
955 printf("***ERROR Unknown token '%s' in file %d '%s' on line %d\n",
956 line, isone ? 1 : 2, fname,
957 isone ? line_num1G : line_num2G );
958 /*FIXME shouldn't die here if possible */
959 exit(0);
960 continue;
961 break;
962 }
963 }
964 return(EOF);
965 }
966
967 /* used to place the string back on the fp to be used later */
restore(FILE * fp,char * str,int size)968 static void restore(FILE *fp, char *str, int size)
969 {
970 int i;
971 char *cp;
972
973 ungetc(' ', fp);
974 cp = &str[size-1];
975
976 for(i =0; i< size; i++, cp--)
977 ungetc(*cp, fp);
978
979 }
980
981 /* return true if the next signal isn't the same, otherwise false */
peek_nxt_sig(FILE * fp,int sigcode1,bool_t isone)982 static bool_t peek_nxt_sig(FILE *fp, int sigcode1, bool_t isone)
983 {
984 char tmp[MAXTOKSIZE], sig[MAXTOKSIZE];
985 int size1, size2, sigcode2;
986 char *cp;
987
988 size1 = get_token(fp, tmp);
989 cp = tmp;
990
991 if(tmp[0] == 'b')
992 {
993 size2 = get_token(fp, sig);
994 restore(fp, sig, size2);
995 restore(fp, tmp, size1);
996 cp = sig;
997 }
998 else if(tmp[0] == '0' || tmp[0] == '1' || tmp[0] =='x' || tmp[0] =='z')
999 {
1000 restore(fp, tmp, size1);
1001 cp++;
1002 }
1003 else
1004 {
1005 restore(fp, tmp, size1);
1006 return(TRUE);
1007 }
1008
1009 /* map signal to the right sigcode */
1010 sigcode2 = VERILOG_ID_TO_POS(cp);
1011
1012 /* LOOKATME can this ever happen ??*/
1013 if(sigcode2 > max_codeG) return(TRUE);
1014 if(isone)
1015 {
1016 if(fd2_to_fd1_mapG[sigcode2] == NULL) return(TRUE);
1017 sigcode2 = *fd2_to_fd1_mapG[sigcode2];
1018 }
1019 else
1020 {
1021 if(fd1_to_fd2_mapG[sigcode2] == NULL) return(TRUE);
1022 sigcode2 = *fd1_to_fd2_mapG[sigcode2];
1023 }
1024
1025 return(sigcode1 != sigcode2);
1026 }
1027
1028
1029 /* rewind to file and reset line count to the start of a #time */
rewind_time(FILE * fp,long seek,vtime_t * time,vtime_t treset,int * linenum,int lreset)1030 static void rewind_time(FILE *fp, long seek, vtime_t *time,
1031 vtime_t treset, int *linenum, int lreset)
1032 {
1033 *time = treset;
1034 fseek(fp, seek, SEEK_SET);
1035 /* reset the line counts */
1036 *linenum = lreset;
1037 }
1038
1039
1040 /* get the differences of a time block from #time to the next #time2 or EOF */
1041
get_time_diffs(FILE * mainfp,FILE * otherfp,char * mname,char * oname,long seek1,long seek2,vtime_t ltime1,vtime_t ltime2,bool_t isone)1042 static vtime_t get_time_diffs(FILE *mainfp, FILE *otherfp, char *mname,
1043 char *oname, long seek1, long seek2,
1044 vtime_t ltime1, vtime_t ltime2, bool_t isone)
1045 {
1046 char svalue1[MAXTOKSIZE], svalue2[MAXTOKSIZE];
1047 int retval;
1048 int sigcode1, sigcode2;
1049 int state1, state2;
1050 int tmpline1, tmpline2;
1051 vtime_t time, nxt_time;
1052 struct signal_t *sig1, *sig2;
1053 bool_t first;
1054
1055 sigcode1 = sigcode2 = 0;
1056 first = TRUE;
1057 time = ltime1;
1058 nxt_time = ltime2;
1059
1060 /* AIV 02/04/03 added temps to reset line count for unkown tokens, etc */
1061 tmpline1 = line_num1G;
1062 tmpline2 = line_num2G;
1063
1064
1065 /* LOOKATME rewind needed here because of reset ungets, and seek from
1066 the start of the file, should write own buffer */
1067 rewind(isone ? mainfp : otherfp);
1068 if(isone)
1069 fseek(mainfp, seek1, SEEK_CUR);
1070 else
1071 fseek(otherfp, seek2, SEEK_CUR);
1072
1073 while(retval != EOF)
1074 {
1075
1076 retval = get_nxt_chg(mainfp, mname, &sigcode1, &state1, svalue1, &time, isone);
1077 switch(retval)
1078 {
1079 case SCALAR:
1080 case VECTOR:
1081 /* rewind if the next sig isn't the same */
1082 /* LOOKATME could change so that if the first sig isn't*/
1083 /* get_nxt would rewind, to speed up ?? */
1084 if(!first && peek_nxt_sig(otherfp, sigcode1, isone))
1085 {
1086 rewind_time(otherfp, seek2, &nxt_time, ltime2,
1087 isone ? &line_num2G : &line_num1G,
1088 isone ? tmpline2 : tmpline1);
1089 }
1090
1091 first = FALSE;
1092 if(isone)
1093 {
1094 sig1 = VERILOG_POS_TO_SIG1(sigcode1);
1095 sigcode1 = *fd1_to_fd2_mapG[sigcode1];
1096 sig2 = VERILOG_POS_TO_SIG2(sigcode1);
1097 }
1098 else
1099 {
1100 sig1 = VERILOG_POS_TO_SIG2(sigcode1);
1101 sigcode1 = *fd2_to_fd1_mapG[sigcode1];
1102 sig2 = VERILOG_POS_TO_SIG1(sigcode1);
1103 }
1104 if(!sig1->in_both)
1105 break;
1106 if(sig1->found)
1107 {
1108 sig1->found = FALSE;
1109 sig2->found = FALSE;
1110 if(retval == SCALAR) sig1->state = state1;
1111 else strcpy(sig1->vector, svalue1);
1112 break;
1113 }
1114 /*should check to see if sig1 and sig 2 are the same type??*/
1115 for(;;)
1116 {
1117 if(get_nxt_chg(otherfp, oname, &sigcode2, &state2, svalue2, &nxt_time, !isone) == EOF)
1118 {
1119 printf("%s (%s) Never found in file %d at time %lld\n", sig1->signame,
1120 sig1->ident, isone ? 1 : 2, time);
1121 break;
1122 }
1123 else if(sigcode1 == sigcode2)
1124 break;
1125 }
1126
1127 if(retval == SCALAR)
1128 {
1129 if(state_flagG)
1130 print_scalar_state(sig1, sig2, time, nxt_time,
1131 state1, state2, isone);
1132 else
1133 print_scalar_edge(sig1, sig2, time, nxt_time,
1134 state1, state2, isone);
1135 sig1->state = state1;
1136 }
1137 else if(retval == VECTOR)
1138 {
1139 if(state_flagG)
1140 print_vector_state(sig1, sig2, time, nxt_time,
1141 svalue1, svalue2, isone);
1142 else
1143 print_vector_edge(sig1, sig2, time, nxt_time,
1144 svalue1, svalue2, isone);
1145 strcpy(sig1->vector, svalue1);
1146 }
1147 /* if isn't the same time must of scanned foward so rewind */
1148 if(nxt_time != time)
1149 {
1150 rewind_time(otherfp, seek2, &nxt_time, ltime2,
1151 isone ? &line_num2G : &line_num1G,
1152 isone ? tmpline2 : tmpline1);
1153 }
1154
1155 break;
1156 case TIME:
1157 /* rewind to the start time, to process other file*/
1158 if(isone)
1159 {
1160 rewind_time(otherfp, seek2, &nxt_time, ltime2,
1161 isone ? &line_num2G : &line_num1G,
1162 isone ? tmpline2 : tmpline1);
1163 }
1164 if(time != 0)
1165 return(time);
1166 break;
1167 case EOF:
1168 quit_flagG = EOF;
1169 return(time);
1170 default:
1171 continue;
1172 }
1173 }
1174 /*FIXME should never get here emit error */
1175 return(time);
1176 }
1177
1178
1179
1180 /* print the map of identifiers to signal name between files */
print_map(void)1181 static void print_map(void)
1182 {
1183 register int i;
1184 struct signal_t *sig;
1185
1186 for(i = 0; i< max_codeG; i++)
1187 {
1188 if(fd1_to_fd2_mapG[i] != NULL)
1189 {
1190 sig = VERILOG_POS_TO_SIG2(*fd1_to_fd2_mapG[i]);
1191 if(!sig->in_both) continue;
1192 printf("%d %d %s\n", i, *fd1_to_fd2_mapG[i], sig->signame);
1193
1194 }
1195 }
1196 printf("*********Second*********\n");
1197 for(i = 0; i< max_codeG; i++)
1198 {
1199 if(fd2_to_fd1_mapG[i] != NULL)
1200 {
1201 sig = VERILOG_POS_TO_SIG1(*fd2_to_fd1_mapG[i]);
1202 if(!sig->in_both) continue;
1203 printf("%d %d %s\n", i, *fd2_to_fd1_mapG[i], sig->signame);
1204
1205 }
1206 }
1207
1208 }
1209
1210 /* check to make sure the files are the same in type/size in both files */
compare_types(char * file_nam1,char * file_nam2,struct signal_t * sig1,struct signal_t * sig2)1211 static void compare_types(char *file_nam1, char *file_nam2,
1212 struct signal_t *sig1, struct signal_t *sig2)
1213 {
1214
1215 if(sig1->in_both)
1216 {
1217 if(sig1->type != sig2->type)
1218 {
1219 if(sig1->sig_code == sig2->sig_code)
1220 printf("WARNING - Ignoring signal %s (%s) - types don't match\n",
1221 sig1->signame, sig1->ident);
1222 else
1223 printf("WARNING - Ignoring signal %s (%s %s) - types don't match\n",
1224 sig1->signame, sig1->ident, sig2->ident);
1225
1226 printf("\t file '%s' type '%s'\n", file_nam1, var_types[sig1->type].vnam);
1227 printf("\t file '%s' type '%s'\n\n", file_nam2, var_types[sig2->type].vnam);
1228 sig1->in_both = FALSE;
1229 sig2->in_both = FALSE;
1230 return;
1231 }
1232 if(sig1->size != sig2->size)
1233 {
1234 if(sig1->sig_code == sig2->sig_code)
1235 printf("WARNING - Ignoring signal %s (%s) - sizes don't match\n",
1236 sig1->signame, sig1->ident);
1237 else
1238 printf("WARNING - Ignoring signal %s (%s %s) - sizes don't match\n",
1239 sig1->signame, sig1->ident, sig2->ident);
1240
1241 printf("\t file '%s' size '%d'\n", file_nam1, sig1->size);
1242 printf("\t file '%s' size '%d'\n\n", file_nam2, sig2->size);
1243 sig1->in_both = FALSE;
1244 sig2->in_both = FALSE;
1245 return;
1246 }
1247 }
1248 }
1249
1250 /* map the signal names to identifiers from one file to the other */
map(char * file_nam1,char * file_nam2,int ** file_map,struct signal_t * startsig,struct signal_t * otherstart,struct signal_t ** sig_arr,bool_t isone)1251 static bool_t map(char *file_nam1, char *file_nam2, int **file_map,
1252 struct signal_t *startsig, struct signal_t *otherstart,
1253 struct signal_t **sig_arr, bool_t isone)
1254 {
1255 struct signal_t *sig1, *sig2;
1256 bool_t one_found;
1257
1258
1259 one_found = FALSE;
1260 for(sig1 = startsig; sig1 != NULL; sig1 = sig1->next)
1261 {
1262 if(isone)
1263 sig2 = VERILOG_POS_TO_SIG2(sig1->sig_code);
1264 else
1265 sig2 = VERILOG_POS_TO_SIG1(sig1->sig_code);
1266
1267 if(sig2 == NULL)
1268 {
1269 for(sig2 = otherstart; sig2 != NULL; sig2 = sig2->next)
1270 {
1271 if(!sig2->in_both) continue;
1272 if(strcmp(sig1->signame, sig2->signame) == 0)
1273 {
1274 file_map[sig1->sig_code] = &sig2->sig_code;
1275 compare_types(file_nam1, file_nam2, sig1, sig2);
1276 one_found = TRUE;
1277 break;
1278 }
1279 }
1280 }
1281 else if(strcmp(sig1->signame, sig2->signame) == 0)
1282 {
1283 file_map[sig1->sig_code] = &sig1->sig_code;
1284 compare_types(file_nam1, file_nam2, sig1, sig2);
1285 one_found = TRUE;
1286 }
1287 else
1288 {
1289 for(sig2 = otherstart; sig2 != NULL; sig2 = sig2->next)
1290 {
1291 if(!sig2->in_both) continue;
1292 if(strcmp(sig1->signame, sig2->signame) == 0)
1293 {
1294 file_map[sig1->sig_code] = &sig2->sig_code;
1295 compare_types(file_nam1, file_nam2, sig1, sig2);
1296 one_found = TRUE;
1297 break;
1298 }
1299 }
1300 }
1301 if(sig2 == NULL)
1302 {
1303 printf("WARNING - Ignoring signal %s (%s) - not defined in both files\n", sig1->signame, sig1->ident);
1304 printf("\t Defined in file '%s' and not file '%s'\n\n", file_nam1, file_nam2);
1305 file_map[sig1->sig_code] = &sig1->sig_code;
1306 sig1->in_both = FALSE;
1307 }
1308 }
1309
1310 return(one_found);
1311 }
1312
1313 /* map both files */
map_var_names(char * file_nam1,char * file_nam2)1314 static bool_t map_var_names(char *file_nam1, char *file_nam2)
1315 {
1316 fd1_to_fd2_mapG = (int**) malloc(sizeof(int) * max_codeG);
1317 fd2_to_fd1_mapG = (int**) malloc(sizeof(int) * max_codeG);
1318
1319 map(file_nam1, file_nam2, fd1_to_fd2_mapG, sig1_hdG, sig2_hdG, sig_int1G, TRUE);
1320
1321 return(map(file_nam2, file_nam1, fd2_to_fd1_mapG, sig2_hdG, sig1_hdG, sig_int2G, FALSE));
1322
1323 //print_map();
1324
1325 }
1326
1327 /* acutally run the files to diff the two */
run_diffs(FILE * fp1,FILE * fp2,char * fnam1,char * fnam2,long start1,long start2)1328 static void run_diffs(FILE *fp1, FILE *fp2, char *fnam1, char *fnam2,
1329 long start1, long start2)
1330 {
1331 vtime_t time1, time2, temp_time1;
1332 long temp1_chars;
1333 char token[MAXTOKSIZE];;
1334
1335 time1 = time2 = temp_time1 = 0;
1336
1337 while(quit_flagG != EOF)
1338 {
1339
1340 /* while the times are the same */
1341 while(time1 == time2)
1342 {
1343 temp_time1 = time1;
1344 time1 = get_time_diffs(fp1, fp2, fnam1, fnam2, start1, start2,
1345 time1, time2, TRUE);
1346 temp1_chars = ftell(fp1);
1347
1348 time2 = get_time_diffs(fp2, fp1, fnam2, fnam1, start2, start1,
1349 time2, temp_time1, FALSE);
1350 start2=ftell(fp2);
1351 start1=temp1_chars;
1352 if(quit_flagG) break;
1353 }
1354
1355 /* time one is ahead */
1356 while(time2 < time1)
1357 {
1358 time2 = get_time_diffs(fp2, fp1, fnam2, fnam1, start2, start1,
1359 time2, temp_time1, FALSE);
1360 start2 = ftell(fp2);
1361 if(quit_flagG)
1362 {
1363 if(get_token(fp1, token) != EOF)
1364 {
1365 printf("*****End of file hit at file 2 ('%s') time %lld quiting\n", fnam2, time2);
1366 printf("WARNING - Files have different end times\n");
1367 }
1368 break;
1369 }
1370 }
1371
1372
1373 /* while time two is ahead */
1374 while(time1 < time2)
1375 {
1376 time1 = get_time_diffs(fp1, fp2, fnam1, fnam2, start1, start2, time1, time2, TRUE);
1377 start1=ftell(fp1);
1378 if(quit_flagG)
1379 {
1380 if(get_token(fp2, token) != EOF)
1381 {
1382 printf("*****End of file hit at file 1 ('%s') time %lld quiting\n", fnam1, time1);
1383 printf("WARNING - Files have different end times\n");
1384 }
1385 break;
1386 }
1387 }
1388 }
1389 }
1390
1391 /* print help information */
print_help(void)1392 static void print_help(void)
1393 {
1394 printf("Usage: [options] 'file1' 'file2'\n Compares Verilog VCD dump files.\n\n");
1395
1396 printf(" --state \n -s \n");
1397 printf("\tPrints the current state of variables, instead of\n \tthe default edge value. \n");
1398 printf(" --wrap \n -w \n");
1399 printf("\tWraps the line, only used for default edge print values\n\tnot --state print messages. \n");
1400 exit(0);
1401 }
1402
1403
1404 /* print program header info */
print_header(void)1405 static void print_header(void)
1406 {
1407 char s1[30];
1408 time_t now;
1409
1410 printf("%s_%s of %s (%s).\n", "vcddiff", VERS2, OFDT, "Linux-ELF");
1411 printf("Copyright (c) 2002-2004 Pragmatic C Software Corp.\n");
1412 printf("All Rights reserved. Licensed under the GNU General Public License (GPL).\n");
1413 printf("See the 'COPYING' file for details. NO WARRANTY provided.\n");
1414 time(&now);
1415 strcpy(s1, ctime(&now));
1416 s1[24] = '\0';
1417 printf("Today is %s.\n\n", s1);
1418
1419 }
1420
set_options(int argc,char ** argv)1421 static void set_options(int argc, char **argv)
1422 {
1423 int i;
1424
1425 for(i = 1; i < argc-2; i++)
1426 {
1427 if(!strcmp(argv[i], "--state") || !strcmp(argv[i],"-s"))
1428 {
1429 if(wrap_flagG)
1430 printf("WARNING - wrap cannot be used with --state option, wrap disabled\n\n");
1431 else
1432 state_flagG = TRUE;
1433 }
1434 else if(!strcmp(argv[i], "--wrap") || !strcmp(argv[i],"-w"))
1435 {
1436 if(state_flagG)
1437 printf("WARNING - wrap cannot be used with --state option, wrap disabled\n\n");
1438 else
1439 wrap_flagG = TRUE;
1440 }
1441 else
1442 {
1443 printf("ERROR - Unknown option %s\n", argv[i]);
1444 printf("\t Try 'vcddiff --help' for more infomation\n");
1445 exit(0);
1446 }
1447 }
1448
1449 }
1450
1451
main(int argc,char ** argv)1452 int main(int argc, char **argv)
1453 {
1454 int unit1, unit2, tnum1, tnum2;
1455 long start1, start2;
1456 char *file_nam1, *file_nam2;
1457 bool_t map_found;
1458 FILE *fp1, *fp2;
1459
1460 quit_flagG = FALSE;
1461 sig1_hdG = NULL;
1462 sig2_hdG = NULL;
1463
1464 print_header();
1465 if(argc < 2)
1466 {
1467 printf("ERROR - Usage: [options] 'file1' 'file2'\n");
1468 printf("\t Try 'vcddiff --help' for more infomation\n");
1469 exit(1);
1470 }
1471 if(!strcmp(argv[1], "--help") || !strcmp(argv[1],"-h"))
1472 print_help();
1473
1474 if(argc < 3)
1475 {
1476 printf("ERROR - Usage: [options] 'file1' 'file2'\n");
1477 printf("\t Try 'vcddiff --help' for more infomation\n");
1478 exit(1);
1479 }
1480
1481
1482 wrap_flagG = state_flagG = FALSE;
1483
1484 if((fp1 = fopen(argv[argc-2], "r")) == NULL)
1485 {
1486 printf("*** ERROR-opening file %s\n", argv[argc-2]);
1487 exit(1);
1488 }
1489
1490 /* set first file to the global pointer to check the line count */
1491 file1G = fp1;
1492
1493 if((fp2 = fopen(argv[argc-1], "r")) == NULL)
1494 {
1495 printf("*** ERROR-opening file %s\n", argv[argc-1]);
1496 exit(1);
1497 }
1498 set_options(argc, argv);
1499
1500 sig_int1G = NULL;
1501 sig_int2G = NULL;
1502
1503 /*could skip copying the filename, just pass argv*/
1504 file_nam1 = (char*) malloc(strlen(argv[argc-2])+ 1);
1505 strcpy(file_nam1, argv[argc-2]);
1506 start1 = get_lines(fp1, &unit1, &tnum1, file_nam1);
1507
1508 file_nam2 = (char *) malloc(strlen(argv[argc-1]) + 1);
1509 strcpy(file_nam2, argv[argc-1]);
1510 start2 = get_lines(fp2, &unit2, &tnum2, file_nam2);
1511 alloc_sig_mem();
1512 map_found = map_var_names(file_nam1, file_nam2);
1513
1514
1515 if(map_found)
1516 {
1517 if(tnum1 != tnum2)
1518 {
1519 printf("*** ERROR-dump files have different timescale time numbers '%d' in file 1, and '%d' in file 2\n", tnum1, tnum2);
1520 exit(1);
1521 }
1522
1523 if(unit1 != unit2)
1524 {
1525 printf("*** ERROR-dump files have different time scale units '%cs' in file 1, and '%cs' in file 2\n", unit1, unit2);
1526 exit(1);
1527 }
1528
1529 run_diffs(fp1, fp2, file_nam1, file_nam2, start1, start2);
1530 }
1531 else
1532 printf("*** ERROR-dump files have no matching variables to diff\n");
1533
1534 /* free and close */
1535 free (sig_int1G);
1536 free (sig_int2G);
1537 free(fd1_to_fd2_mapG);
1538 free(fd2_to_fd1_mapG);
1539 fclose(fp1);
1540 fclose(fp2);
1541 return(0);
1542
1543 }
1544