1 /******************************************************************************
2 * DESCRIPTION: Dinotrace source: trace file reading
3 *
4 * This file is part of Dinotrace.
5 *
6 * Author: Wilson Snyder <wsnyder@wsnyder.org>
7 *
8 * Code available from: http://www.veripool.org/dinotrace
9 *
10 ******************************************************************************
11 *
12 * Some of the code in this file was originally developed for Digital
13 * Semiconductor, a division of Digital Equipment Corporation. They
14 * gratefuly have agreed to share it, and thus the base version has been
15 * released to the public with the following provisions:
16 *
17 *
18 * This software is provided 'AS IS'.
19 *
20 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THE INFORMATION
21 * (INCLUDING ANY SOFTWARE) PROVIDED, INCLUDING ALL IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE, AND
23 * NON-INFRINGEMENT. DIGITAL NEITHER WARRANTS NOR REPRESENTS THAT THE USE
24 * OF ANY SOURCE, OR ANY DERIVATIVE WORK THEREOF, WILL BE UNINTERRUPTED OR
25 * ERROR FREE. In no event shall DIGITAL be liable for any damages
26 * whatsoever, and in particular DIGITAL shall not be liable for special,
27 * indirect, consequential, or incidental damages, or damages for lost
28 * profits, loss of revenue, or loss of use, arising out of or related to
29 * any use of this software or the information contained in it, whether
30 * such damages arise in contract, tort, negligence, under statute, in
31 * equity, at law or otherwise. This Software is made available solely for
32 * use by end users for information and non-commercial or personal use
33 * only. Any reproduction for sale of this Software is expressly
34 * prohibited. Any rights not expressly granted herein are reserved.
35 *
36 ******************************************************************************
37 *
38 * Changes made over the basic version are covered by the GNU public licence.
39 *
40 * Dinotrace is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License as published by
42 * the Free Software Foundation; either version 3, or (at your option)
43 * any later version.
44 *
45 * Dinotrace is distributed in the hope that it will be useful,
46 * but WITHOUT ANY WARRANTY; without even the implied warranty of
47 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 * GNU General Public License for more details.
49 *
50 * You should have received a copy of the GNU General Public License
51 * along with Dinotrace; see the file COPYING. If not, write to
52 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
53 * Boston, MA 02111-1307, USA.
54 *
55 *****************************************************************************/
56
57 #include "dinotrace.h"
58
59 #include "assert.h"
60 #include <Xm/Text.h>
61 #include <Xm/MessageB.h>
62 #include <Xm/SelectioB.h>
63 #include <Xm/FileSB.h>
64 #include <Xm/Form.h>
65 #include <Xm/PushB.h>
66 #include <Xm/PushBG.h>
67 #include <Xm/ToggleB.h>
68 #include <Xm/RowColumn.h>
69
70 #include "functions.h"
71
72 #if HAVE_DINODOC_H
73 #include "dinodoc.h"
74 #else
75 char dinodoc[] = "Unavailable";
76 #endif
77
78 /****************************** UTILITIES ******************************/
79
free_data(Trace_t * trace)80 void free_data (
81 /* Free trace information, also used when deleting preserved structure */
82 Trace_t *trace)
83 {
84 Trace_t *trace_ptr;
85
86 if (DTPRINT_ENTRY) printf ("In free_data - trace=%p\n",trace);
87
88 if (!trace || !trace->loaded) return;
89 trace->loaded = 0;
90 trace->numsigstart = 0;
91
92 /* free any added signals in other traces from this trace */
93 for (trace_ptr = global->deleted_trace_head; trace_ptr; trace_ptr = trace_ptr->next_trace) {
94 sig_free (trace, trace_ptr->firstsig, TRUE, TRUE);
95 }
96 /* free signal data and each signal structure */
97 sig_free (trace, trace->firstsig, FALSE, TRUE);
98 trace->firstsig = NULL;
99 trace->lastsig = NULL;
100 trace->dispsig = NULL;
101 trace->numsig = 0;
102 }
103
trace_read_cb(Widget w,Trace_t * trace)104 void trace_read_cb (
105 Widget w,
106 Trace_t *trace)
107 {
108 int i;
109
110 if (DTPRINT_ENTRY) printf ("In trace_read_cb - trace=%p\n",trace);
111
112 /* Clear the file format */
113 trace->dfile.fileformat = FF_AUTO;
114
115 if (!trace->fileselect.dialog) {
116 XtSetArg (arglist[0], XmNdefaultPosition, TRUE);
117 XtSetArg (arglist[1], XmNdialogTitle, XmStringCreateSimple ("Open Trace File") );
118
119 trace->fileselect.dialog = XmCreateFileSelectionDialog ( trace->main, "file", arglist, 2);
120 DAddCallback (trace->fileselect.dialog, XmNokCallback, fil_ok_cb, trace);
121 DAddCallback (trace->fileselect.dialog, XmNcancelCallback, (XtCallbackProc)unmanage_cb, trace->fileselect.dialog);
122 XtUnmanageChild ( XmFileSelectionBoxGetChild (trace->fileselect.dialog, XmDIALOG_HELP_BUTTON));
123
124 trace->fileselect.work_area = XmCreateWorkArea (trace->fileselect.dialog, "wa", arglist, 0);
125
126 /* Create FILE FORMAT */
127 trace->fileselect.format_menu = XmCreatePulldownMenu (trace->fileselect.work_area,"fmtrad",arglist,0);
128
129 for (i=0; i<FF_NUMFORMATS; i++) {
130 if (filetypes[i].selection) {
131 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple (filetypes[i].name) );
132 trace->fileselect.format_item[i] =
133 XmCreatePushButtonGadget (trace->fileselect.format_menu,"pdbutton",arglist,1);
134 DManageChild (trace->fileselect.format_item[i], trace, MC_NOKEYS);
135 DAddCallback (trace->fileselect.format_item[i], XmNactivateCallback, fil_format_option_cb, trace);
136 }
137 }
138
139 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("File Format"));
140 XtSetArg (arglist[1], XmNsubMenuId, trace->fileselect.format_menu);
141 trace->fileselect.format_option = XmCreateOptionMenu (trace->fileselect.work_area,"format",arglist,2);
142 DManageChild (trace->fileselect.format_option, trace, MC_NOKEYS);
143
144 /* Create save_ordering button */
145 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Preserve Signal Ordering"));
146 XtSetArg (arglist[1], XmNshadowThickness, 1);
147 trace->fileselect.save_ordering = XmCreateToggleButton (trace->fileselect.work_area,"save_ordering",arglist,2);
148 DManageChild (trace->fileselect.save_ordering, trace, MC_NOKEYS);
149
150 DManageChild (trace->fileselect.work_area, trace, MC_NOKEYS);
151
152 XSync (global->display,0);
153 }
154
155 /* Ordering */
156 XtSetArg (arglist[0], XmNset, global->save_ordering ? 1:0);
157 XtSetValues (trace->fileselect.save_ordering,arglist,1);
158
159 /* File format */
160 if (filetypes[file_format].selection) {
161 XtSetArg (arglist[0], XmNmenuHistory, trace->fileselect.format_item[file_format]);
162 XtSetValues (trace->fileselect.format_option, arglist, 1);
163 }
164
165 /* Set directory */
166 XtSetArg (arglist[0], XmNdirectory, XmStringCreateSimple (global->directory) );
167 XtSetValues (trace->fileselect.dialog,arglist,1);
168
169 fil_select_set_pattern (trace, trace->fileselect.dialog, filetypes[file_format].mask);
170
171 DManageChild (trace->fileselect.dialog, trace, MC_NOKEYS);
172
173 XSync (global->display,0);
174 }
175
trace_reread_all()176 void trace_reread_all ()
177 {
178 Trace_t* trace;
179 for (trace = global->trace_head; trace; trace = trace->next_trace) {
180 if (trace->loaded) {
181 trace_reread(trace);
182 }
183 }
184 }
185
trace_reread(Trace_t * trace)186 void trace_reread (
187 Trace_t *trace)
188 {
189 char *semi;
190 int read_fd;
191 struct stat newstat; /* New status on the reread file*/
192
193 if (!trace->loaded)
194 trace_read_cb (NULL, trace);
195 else {
196 /* Drop ;xxx */
197 if ((semi = strchr (trace->dfile.filename,';')))
198 *semi = '\0';
199
200 if (DTPRINT_ENTRY) printf ("In trace_reread_cb - rereading file=%s\n",trace->dfile.filename);
201
202 /* check the date first */
203 read_fd = open (trace->dfile.filename, O_RDONLY, 0);
204 if (read_fd>=1) {
205 /* Opened ok */
206 fstat (read_fd, &newstat);
207 close (read_fd);
208 if ((newstat.st_mtime == trace->dfile.filestat.st_mtime)
209 && (newstat.st_ctime == trace->dfile.filestat.st_ctime)) {
210 if (DTPRINT_FILE) printf (" file has not changed.\n");
211 if (DTPRINT_FILE) printf (" file has not changed, but rereading anyways.\n");
212 else return;
213 }
214 }
215
216 /* read the file */
217 fil_read (trace);
218 }
219 }
220
fil_read(Trace_t * trace)221 void fil_read (
222 Trace_t *trace)
223 {
224 int read_fd;
225 FILE *read_fp; /* Routines are responsible for assigning this! */
226 char *pchar;
227 char pipecmd[MAXFNAMELEN+20];
228 pipecmd[0]='\0'; /* MIPS: no automatic aggregate initialization */
229 read_fp = NULL; /* MIPS: no automatic aggregate initialization */
230
231 if (DTPRINT_ENTRY) printf ("In fil_read trace=%p filename=%s\n",trace,trace->dfile.filename);
232
233 /* Update directory name */
234 strcpy (global->directory, trace->dfile.filename);
235 file_directory (global->directory);
236
237 /* Clear the data structures & the screen */
238 XClearWindow (global->display, trace->wind);
239 set_cursor (DC_BUSY);
240 XSync (global->display,0);
241
242 /* free memory associated with the data */
243 sig_cross_preserve(trace);
244 free_data (trace);
245
246 /* get applicable config files */
247 config_read_defaults (trace, TRUE);
248
249 /* Compute the file format */
250 if (trace->dfile.fileformat == FF_AUTO) {
251 trace->dfile.fileformat = file_format;
252 }
253
254 /* Normalize format */
255 switch (trace->dfile.fileformat) {
256 case FF_AUTO:
257 case FF_DECSIM:
258 case FF_DECSIM_BIN:
259 #ifdef VMS
260 trace->dfile.fileformat = FF_DECSIM_BIN;
261 #else
262 /* Binary relys on varible RMS records - Ultrix has no such thing */
263 trace->dfile.fileformat = FF_DECSIM_ASCII;
264 #endif
265 break;
266 /* No default */
267 }
268
269 /* Open file and copy descriptor information */
270 read_fd = open (trace->dfile.filename, O_RDONLY, 0);
271 if (read_fd>0) {
272 fstat (read_fd, &(trace->dfile.filestat));
273 #ifndef VMS
274 if (! S_ISREG(trace->dfile.filestat.st_mode)) {
275 /* Not regular file */
276 close (read_fd);
277 read_fd = -1;
278 }
279 #endif
280 }
281 if (read_fd<1) {
282 /* Similar code below! */
283 sprintf (message,"Can't open file %s", trace->dfile.filename);
284 dino_error_ack (trace, message);
285
286 /* Clear cursor and return*/
287 sig_cross_restore (trace);
288 change_title (trace);
289 set_cursor (DC_NORMAL);
290 return;
291 }
292
293 #ifndef VMS
294 /* If compressed, close the file and open as uncompressed */
295 pipecmd[0]='\0';
296 if ((pchar=strrchr(trace->dfile.filename,'.')) != NULL ) {
297 if (!strcmp (pchar, ".Z")) sprintf (pipecmd, "uncompress -c %s", trace->dfile.filename);
298 if (!strcmp (pchar, ".gz")) sprintf (pipecmd, "gunzip -c %s", trace->dfile.filename);
299 }
300
301 if (trace->dfile.fileformat == FF_VERILOG_VPD) {
302 if (pipecmd[0]) {
303 /* Because vpd2vcd fseeks, it won't take a pipe as input, and we... */
304 sprintf (message,"Can't unzip/uncompress VPD traces.");
305 dino_error_ack (trace, message);
306 return;
307 }
308 sprintf (pipecmd, "vpd2vcd %s 2>/dev/null", trace->dfile.filename);
309 }
310
311 if (pipecmd[0]) {
312
313 if (DTPRINT_FILE) printf ("Piping: %s\n", pipecmd);
314
315 /* Decsim must be ASCII because of record format */
316 if (trace->dfile.fileformat == FF_DECSIM_BIN) trace->dfile.fileformat = FF_DECSIM_ASCII;
317
318 /* Close compressed file and open uncompressed file */
319 close (read_fd);
320
321 read_fp = popen (pipecmd, "r");
322 read_fd = fileno (read_fp);
323 if (!read_fp) {
324 /* Similar above! */
325 sprintf (message,"Can't create pipe with command '%s'", pipecmd);
326 dino_error_ack (trace, message);
327
328 /* Clear cursor and return */
329 sig_cross_restore (trace);
330 change_title (trace);
331 set_cursor (DC_NORMAL);
332 return;
333 }
334 }
335 #endif
336
337 /*
338 ** Read in the trace file using the format selected by the user
339 */
340 switch (trace->dfile.fileformat) {
341 case FF_DECSIM_BIN:
342 #ifdef VMS
343 decsim_read_binary (trace, read_fd);
344 #endif /* VMS */
345 break;
346 case FF_TEMPEST:
347 tempest_read (trace, read_fd);
348 break;
349 case FF_VERILOG:
350 case FF_VERILOG_VPD:
351 verilog_read (trace, read_fd);
352 break;
353 case FF_DECSIM_ASCII:
354 ascii_read (trace, read_fd, read_fp);
355 break;
356 default:
357 fprintf (stderr, "Unknown file format!!\n");
358 }
359
360 /* Close the file */
361 if (pipecmd[0] == '\0') {
362 close (read_fd);
363 }
364 #ifndef VMS
365 else {
366 fflush (read_fp);
367 pclose (read_fp);
368 }
369 #endif
370
371 /* Now add EOT to each signal and reset the cptr */
372 fil_trace_end (trace);
373
374 /* Change the name on title bar to filename */
375 change_title (trace);
376
377 /*
378 ** Clear the window and draw the screen with the new file
379 */
380 set_cursor (DC_NORMAL);
381 if (global->res_default) win_full_res (trace);
382 new_time (trace); /* Realignes start and displays */
383 vscroll_new (trace,0); /* Realign time */
384 if (DTPRINT_ENTRY) printf ("fil_read done!\n");
385 }
386
fil_select_set_pattern(Trace_t * trace,Widget dialog,char * pattern)387 void fil_select_set_pattern (
388 Trace_t *trace,
389 Widget dialog,
390 char *pattern)
391 /* Set the file requester pattern information (called in 2 places) */
392 {
393 char mask[MAXFNAMELEN], *dirname;
394 XmString xs_dirname;
395
396 /* Grab directory information */
397 XtSetArg (arglist[0], XmNdirectory, &xs_dirname);
398 XtGetValues (dialog, arglist, 1);
399 dirname = extract_first_xms_segment (xs_dirname);
400
401 /* Pattern information */
402 strcpy (mask, dirname);
403 strcat (mask, pattern);
404 XtSetArg (arglist[0], XmNdirMask, XmStringCreateSimple (mask) );
405 XtSetArg (arglist[1], XmNpattern, XmStringCreateSimple (pattern) );
406 XtSetValues (dialog,arglist,2);
407 }
408
fil_format_option_cb(Widget w,Trace_t * trace,XmSelectionBoxCallbackStruct * cb)409 void fil_format_option_cb (
410 Widget w,
411 Trace_t *trace,
412 XmSelectionBoxCallbackStruct *cb)
413 {
414 int i;
415 if (DTPRINT_ENTRY) printf ("In fil_format_option_cb trace=%p\n",trace);
416
417 for (i=0; i<FF_NUMFORMATS; i++) {
418 if (w == trace->fileselect.format_item[i]) {
419 file_format = i; /* Change global verion */
420 trace->dfile.fileformat = i; /* Specifically make this file use this format */
421 fil_select_set_pattern (trace, trace->fileselect.dialog, filetypes[file_format].mask);
422 }
423 }
424 }
425
fil_ok_cb(Widget w,Trace_t * trace,XmFileSelectionBoxCallbackStruct * cb)426 void fil_ok_cb (
427 Widget w,
428 Trace_t *trace,
429 XmFileSelectionBoxCallbackStruct *cb)
430 {
431 char *tmp;
432
433 if (DTPRINT_ENTRY) printf ("In fil_ok_cb trace=%p\n",trace);
434
435 /*
436 ** Unmanage the file select widget here and wait for sync so
437 ** the window goes away before the read process begins in case
438 ** the idle is very big.
439 */
440 XtUnmanageChild (trace->fileselect.dialog);
441 XSync (global->display,0);
442
443 tmp = extract_first_xms_segment (cb->value);
444 if (DTPRINT_FILE) printf ("filename=%s\n",tmp);
445
446 global->save_ordering = XmToggleButtonGetState (trace->fileselect.save_ordering);
447
448 strcpy (trace->dfile.filename, tmp);
449
450 DFree (tmp);
451
452 if (DTPRINT_FILE) printf ("In fil_ok_cb Filename=%s\n",trace->dfile.filename);
453 fil_read (trace);
454 }
455
456
help_cb(Widget w)457 void help_cb (
458 Widget w)
459 {
460 Trace_t *trace = widget_to_trace(w);
461 if (DTPRINT_ENTRY) printf ("in help_cb\n");
462 dino_information_ack (trace, help_message ());
463 }
464
help_trace_cb(Widget w)465 void help_trace_cb (
466 Widget w)
467 {
468 Trace_t *trace = widget_to_trace(w);
469 static char msg[2000];
470 static char msg2[1000];
471
472 if (DTPRINT_ENTRY) printf ("in help_trace_cb\n");
473
474 if (!trace->loaded) {
475 sprintf (msg, "No trace is loaded.\n");
476 }
477 else {
478 sprintf (msg, "%s\n\n", trace->dfile.filename);
479
480 sprintf (msg2, "File Format: %s\n", filetypes[trace->dfile.fileformat].name);
481 strcat (msg, msg2);
482
483 sprintf (msg2, "File Modified Date: %s\n", date_string (trace->dfile.filestat.st_ctime));
484 strcat (msg, msg2);
485
486 sprintf (msg2, "File Creation Date: %s\n", date_string (trace->dfile.filestat.st_mtime));
487 strcat (msg, msg2);
488
489 sprintf (msg2, "\nTimes stored to nearest: %s\n", time_units_to_string (global->time_precision, TRUE));
490 strcat (msg, msg2);
491 }
492
493 dino_information_ack (trace, msg);
494 }
495
496
help_doc_cb(Widget w)497 void help_doc_cb (
498 Widget w)
499 {
500 Trace_t *trace = widget_to_trace(w);
501
502 if (DTPRINT_ENTRY) printf ("in help_doc_cb\n");
503
504 /* May be called before the window was opened, if so ignore the help_doc */
505 if (!trace->work) return;
506
507 /* create the widget if it hasn't already been */
508 if (!trace->help_doc) {
509 XtSetArg (arglist[0], XmNdefaultPosition, TRUE);
510 XtSetArg (arglist[1], XmNdialogTitle, XmStringCreateSimple ("Dinotrace Documentation") );
511 trace->help_doc = XmCreateInformationDialog (trace->work, "info", arglist, 2);
512 DAddCallback (trace->help_doc, XmNokCallback, unmanage_cb, trace->help_doc);
513 XtUnmanageChild ( XmMessageBoxGetChild (trace->help_doc, XmDIALOG_CANCEL_BUTTON));
514 XtUnmanageChild ( XmMessageBoxGetChild (trace->help_doc, XmDIALOG_HELP_BUTTON));
515
516 /* create scrolled text widget */
517 XtSetArg (arglist[0], XmNrows, 40);
518 XtSetArg (arglist[1], XmNcolumns, 80);
519 XtSetArg (arglist[2], XmNeditable, FALSE);
520 XtSetArg (arglist[3], XmNvalue, dinodoc);
521 XtSetArg (arglist[4], XmNscrollVertical, TRUE);
522 XtSetArg (arglist[5], XmNeditMode, XmMULTI_LINE_EDIT);
523 XtSetArg (arglist[6], XmNscrollHorizontal, FALSE);
524 trace->help_doc_text = XmCreateScrolledText (trace->help_doc,"textn",arglist,7);
525
526 DManageChild (trace->help_doc_text, trace, MC_NOKEYS);
527 }
528
529 /* manage the widget */
530 DManageChild (trace->help_doc, trace, MC_NOKEYS);
531 }
532
533 #if !defined (fil_add_cptr)
534 #ifdef VMS
535 #pragma inline (fil_add_cptr)
536 #endif
537 /* WARNING, INLINED CODE IN FUNCTIONS.H */
fil_add_cptr(Signal_t * sig_ptr,Value_t * value_ptr,Boolean_t nocheck)538 void fil_add_cptr (
539 Signal_t *sig_ptr,
540 Value_t *value_ptr,
541 Boolean_t nocheck) /* compare against previous data */
542 {
543 ulong_t diff;
544 Value_t *cptr = sig_ptr->cptr;
545
546 /* Important! During the adding cptr points to the __last__ value added, not the next! */
547
548 /*
549 if (DTPRINT_FILE) printf ("Checking st %d v %d tm %d with st %d v %d time %d\n",
550 value_ptr->siglw.stbits.state, value_ptr->number[0],
551 CPTR_TIME(value_ptr),
552 cptr->siglw.stbits.state, cptr->number[0],
553 CPTR_TIME(cptr)
554 );
555 if (DTPRINT_FILE) printf ("val: %08x %08x %08x %08x %08x %08x ",
556 value_ptr->siglw.number, value_ptr->time,
557 value_ptr->number[0],value_ptr->number[1],
558 value_ptr->number[2],value_ptr->number[3]);
559 */
560
561 /* Comparing all 4 LW's works because we keep the unused LWs zeroed */
562 if ( nocheck
563 || ( cptr->siglw.stbits.state != value_ptr->siglw.stbits.state )
564 || ( cptr->number[0] != value_ptr->number[0] )
565 || ( cptr->number[1] != value_ptr->number[1] )
566 || ( cptr->number[2] != value_ptr->number[2] )
567 || ( cptr->number[3] != value_ptr->number[3] )
568 || ( cptr->number[4] != value_ptr->number[4] )
569 || ( cptr->number[5] != value_ptr->number[5] )
570 || ( cptr->number[6] != value_ptr->number[6] )
571 || ( cptr->number[7] != value_ptr->number[7] ) ) {
572
573 diff = (uint_t*)sig_ptr->cptr - (uint_t*)sig_ptr->bptr;
574 if (diff > sig_ptr->blocks ) {
575 /* if (DTPRINT_FILE) printf ("Realloc\n"); */
576 sig_ptr->blocks += BLK_SIZE;
577 sig_ptr->bptr = (Value_t *)XtRealloc
578 ((char*)sig_ptr->bptr,
579 (sig_ptr->blocks*sizeof(uint_t)) + (sizeof(Value_t)*2 + 2));
580 sig_ptr->cptr = (Value_t *)((uint_t*)sig_ptr->bptr + diff);
581 }
582
583 /* Update size of previous */
584 /* Note that if at the beginning of a trace, the loaded value may */
585 /* be from uninitialized data, in that case we don't care about the size */
586 value_ptr->siglw.stbits.size_prev = sig_ptr->cptr->siglw.stbits.size;
587 value_ptr->siglw.stbits.size = STATE_SIZE(value_ptr->siglw.stbits.state);
588 if (sig_ptr->cptr->siglw.number || sig_ptr->cptr!=sig_ptr->bptr) {
589 /* Not empty cptr list... have loaded something */
590 sig_ptr->cptr = CPTR_NEXT(sig_ptr->cptr);
591 }
592
593 /* Load new datum */
594 val_copy (sig_ptr->cptr, value_ptr);
595 /*if (DTPRINT_FILE) print_sig_info(sig_ptr);*/
596 }
597
598 }
599 #endif
600
fil_make_busses(Trace_t * trace,Boolean_t not_tempest)601 void fil_make_busses (
602 /* Take the list of signals and make it into a list of busses */
603 /* Also do the common stuff required for each signal. */
604 Trace_t *trace,
605 Boolean_t not_tempest) /* Use the name of the bus to find the bit vectors */
606 {
607 Signal_t *sig_ptr; /* ptr to current signal (lower bit number) */
608 int pos;
609 char postbusstuff[MAXSIGLEN] = "";
610
611 if (DTPRINT_ENTRY) printf ("In fil_make_busses\n");
612 if (DTPRINT_BUSSES) sig_print_names (trace);
613
614 /* Calculate numsig */
615 /* and allocate Signal's cptr, bptr, blocks, inc, type */
616 trace->numsig = 0;
617 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
618 /* Stash the characters after the bus name */
619 if (sig_ptr->signame_buspos) strcpy (postbusstuff, sig_ptr->signame_buspos);
620
621 /* Change the name to include the vector subscripts */
622 if (sig_ptr->msb_index >= 0) {
623 /* Add new vector info */
624 if (sig_ptr->bits >= 2) {
625 sprintf (sig_ptr->signame + strlen (sig_ptr->signame), "[%d:%d]",
626 sig_ptr->msb_index, sig_ptr->lsb_index);
627 }
628 else {
629 sprintf (sig_ptr->signame + strlen (sig_ptr->signame), "[%d]",
630 sig_ptr->msb_index);
631 }
632 }
633
634 /* Restore the characters after the bus name */
635 if (sig_ptr->signame_buspos) {
636 sig_ptr->signame = XtRealloc(sig_ptr->signame,
637 strlen (sig_ptr->signame) + strlen (postbusstuff) + 1);
638 strcat (sig_ptr->signame, postbusstuff);
639 }
640
641 /* Calc numsig, last_sig_ptr */
642 (trace->numsig) ++;
643
644 /* Create the bussed name & type */
645 if (sig_ptr->bits < 2) {
646 sig_ptr->type = 0;
647 }
648 else if (sig_ptr->bits < 33) {
649 sig_ptr->type = STATE_B32;
650 }
651 else if (sig_ptr->bits < 129) {
652 sig_ptr->type = STATE_B128;
653 }
654
655 /* Compute value_mask. This mask ANDed with the value will clear any bits that
656 are not represented in this vector. For example a 12 bit vector will only have the lower
657 twelve bits set, all others will be clear */
658
659 sig_ptr->value_mask[3] = sig_ptr->value_mask[2] = sig_ptr->value_mask[1] = sig_ptr->value_mask[0] = 0;
660
661 if (sig_ptr->bits > 127) sig_ptr->value_mask[3] = 0xFFFFFFFF;
662 else if (sig_ptr->bits > 96 ) sig_ptr->value_mask[3] = (0x7FFFFFFF >> (127-sig_ptr->bits));
663 else if (sig_ptr->bits > 95 ) sig_ptr->value_mask[2] = 0xFFFFFFFF;
664 else if (sig_ptr->bits > 64 ) sig_ptr->value_mask[2] = (0x7FFFFFFF >> (95-sig_ptr->bits));
665 else if (sig_ptr->bits > 63 ) sig_ptr->value_mask[1] = 0xFFFFFFFF;
666 else if (sig_ptr->bits > 32 ) sig_ptr->value_mask[1] = (0x7FFFFFFF >> (63-sig_ptr->bits));
667 else if (sig_ptr->bits > 31 ) sig_ptr->value_mask[0] = 0xFFFFFFFF;
668 else sig_ptr->value_mask[0] = (0x7FFFFFFF >> (31-sig_ptr->bits));
669
670 if (sig_ptr->value_mask[3]) sig_ptr->value_mask[2] = 0xFFFFFFFF;
671 if (sig_ptr->value_mask[2]) sig_ptr->value_mask[1] = 0xFFFFFFFF;
672 if (sig_ptr->value_mask[1]) sig_ptr->value_mask[0] = 0xFFFFFFFF;
673
674 /* Compute the position mask. This is used to convert a LW from the file into a LW for the
675 value. A condition is to prevent sign extension. */
676 pos = sig_ptr->file_pos & 0x1F; /* Must be position of LSB */
677 if (pos!=0) sig_ptr->pos_mask = (0x7FFFFFFF >> (pos-1));
678 else sig_ptr->pos_mask = 0xFFFFFFFF;
679
680 /* Compute the ending position of this data (DECSIM_Binary) */
681 sig_ptr->file_end_pos = sig_ptr->file_pos
682 + ((sig_ptr->file_type.flag.four_state) ? 2:1) * (sig_ptr->bits-1);
683
684 /* allocate the data storage memory */
685 if (!sig_ptr->copyof) {
686 sig_ptr->blocks = BLK_SIZE;
687 sig_ptr->bptr = (Value_t *)XtMalloc ((sig_ptr->blocks*sizeof(uint_t))
688 + (sizeof(Value_t)*2 + 2));
689 val_zero (sig_ptr->bptr); /* So we know is empty */
690 } else {
691 sig_ptr->bptr = NULL;
692 }
693 }
694
695 /* Must be separate loop, as bptr may change in a copyof's parent */
696 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
697 sig_ptr->cptr = sig_ptr->bptr;
698 }
699
700 if (DTPRINT_BUSSES) sig_print_names (trace);
701 }
702
703
fil_mark_cptr_end(Trace_t * trace)704 static void fil_mark_cptr_end (
705 Trace_t *trace)
706 {
707 Signal_t *sig_ptr, *sig_next_ptr;
708 Value_t value;
709 Boolean_t msg=FALSE;
710
711 /* loop thru each signal */
712 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_next_ptr) {
713 sig_next_ptr = sig_ptr->forward;
714
715 if (!sig_ptr->copyof) {
716 /* Must be a cptr which has the same time as the last time on the screen */
717 /* If none exists, create it */
718 val_zero(&value);
719
720 if (sig_ptr->cptr && (sig_ptr->cptr->siglw.number || sig_ptr->cptr!=sig_ptr->bptr)) {
721 Value_t *cptr = sig_ptr->cptr;
722 if (CPTR_TIME(cptr) != trace->end_time) {
723 val_copy (&value, sig_ptr->cptr);
724 value.time = trace->end_time;
725 fil_add_cptr (sig_ptr, &value, TRUE);
726 }
727 }
728 else {
729 if (DTDEBUG && !msg) {
730 printf ("%%W, No data for signal %s\n\tAdditional messages suppressed\n", sig_ptr->signame);
731 msg = TRUE;
732 }
733 /* Don't delete, may have copies pointing to it */
734 /* sig_free (trace, sig_ptr, FALSE, FALSE); sig_ptr=NULL; */
735 /* continue; */
736 }
737
738 /* Mark end of time */
739 value.time = EOT;
740 fil_add_cptr (sig_ptr, &value, TRUE);
741 }
742 }
743
744 /* Must be separate loop, as bptr may change in a copyof's parent */
745 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
746 if (sig_ptr->copyof) {
747 /* Parent may have moved */
748 sig_ptr->bptr = sig_ptr->copyof->bptr;
749 }
750 /* re-initialize the cptr's to the bptr's */
751 sig_ptr->cptr = sig_ptr->bptr;
752 assert (sig_ptr->bptr->siglw.stbits.size!=0);
753 }
754 }
755
fil_trace_end(Trace_t * trace)756 void fil_trace_end (
757 /* Perform stuff at end of trace - common across all reading routines */
758 Trace_t *trace)
759 {
760 Signal_t *sig_ptr;
761
762 if (DTPRINT_FILE) printf ("In fil_trace_end\n");
763
764 /* Modify ending cptrs to be correct */
765 fil_mark_cptr_end (trace);
766
767 /* Misc */
768 trace->dispsig = trace->firstsig;
769
770 /* Make sure time is within bounds */
771 if ( (global->time < trace->start_time) || (global->time > trace->end_time)) {
772 global->time = trace->start_time;
773 }
774
775 /* Mark as loaded */
776 trace->loaded = TRUE;
777
778 switch (trace->dfile.fileformat) {
779 case FF_TEMPEST:
780 case FF_DECSIM_ASCII:
781 case FF_DECSIM_BIN:
782 sig_modify_enables (trace);
783 break;
784 case FF_VERILOG:
785 case FF_VERILOG_VPD:
786 default:
787 break;
788 }
789
790 /* Create xstring of the name (to avoid calling again and again) */
791 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
792 sig_ptr->xsigname = XmStringCreateSimple (sig_ptr->signame);
793 }
794
795 /* Preserve file information */
796 sig_cross_restore (trace);
797
798 /* Read .dino file stuff yet again to get signal_highlights */
799 /* Don't report errors, as they would pop up for a second time. */
800 config_read_defaults (trace, FALSE);
801
802 /* Modify deleted trace to have latest options */
803 global->deleted_trace_head->dfile.hierarchy_separator = trace->dfile.hierarchy_separator;
804 global->deleted_trace_head->dfile.vector_separator = trace->dfile.hierarchy_separator;
805 global->deleted_trace_head->dfile.vectorend_separator = trace->dfile.vectorend_separator;
806
807 /* Apply the statenames */
808 draw_needupd_val_states ();
809 draw_needupd_val_search ();
810 draw_needupd_sig_search ();
811 draw_needupd_sig_start ();
812 grid_calc_autos (trace);
813
814 if (DTPRINT_FILE) printf ("fil_trace_end: Done\n");
815 }
816
817 /****************************** MENU OPTIONS ******************************/
818
trace_reread_all_cb(Widget w,Trace_t * trace)819 void trace_reread_all_cb (Widget w, Trace_t* trace) {
820 trace_reread_all();
821 }
trace_reread_cb(Widget w,Trace_t * trace)822 void trace_reread_cb (Widget w, Trace_t* trace) {
823 trace_reread (trace);
824 }
825