1 /******************************************************************************
2 * DESCRIPTION: Dinotrace source: CCLI tempest trace 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 bas 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 #include <errno.h>
59
60 #include "functions.h"
61 #include "bintradef.h"
62
63 /**********************************************************************/
64
65 #ifdef VMS
66 #define TRA$W_NODNAMLEN tra$r_data.tra$$r_nnr_data.tra$r_fill_11.tra$r_fill_12.tra$w_nodnamlen
67 #define TRA$T_NODNAMSTR tra$r_data.tra$$r_nnr_data.tra$r_fill_11.tra$r_fill_12.tra$t_nodnamstr
68 #define TRA$B_DATTYP tra$r_data.tra$$r_nfd_data.tra$b_dattyp
69 #define TRA$W_BITLEN tra$r_data.tra$$r_nfd_data.tra$w_bitlen
70 #define TRA$L_BITPOS tra$r_data.tra$$r_nfd_data.tra$l_bitpos
71 #define TRA$L_TIME_LO tra$r_data.tra$$r_nsr_data.tra$r_fill_13.tra$r_fill_14.tra$l_time_lo
72 #define TRA$L_TIME_HI tra$r_data.tra$$r_nsr_data.tra$r_fill_13.tra$r_fill_14.tra$l_time_hi
73 #endif /* VMS */
74
75 /* Extract 1 bit or 2 bits from bit position POS in the buffer */
76 /* Type casting to long is important to prevent bit 7 & 8 from separating */
77 /* Note that pos is used twice, no ++'s! */
78 #define EXTRACT_2STATE(buf,pos) ((int)(((*((unsigned long *)(((unsigned long)(buf)) + ((pos)>>3)))) >> ((pos) & 7)) & 1))
79 #define EXTRACT_4STATE(buf,pos) ((int)(((*((unsigned long *)(((unsigned long)(buf)) + ((pos)>>3)))) >> ((pos) & 7)) & 3))
80
81 #if 0
82 int EXTRACT_2STATE (
83 uint_t pos,
84 const ulong_t *buf)
85 {
86 register uint_t bitcnt, bit_pos;
87 register uint_t bit_mask;
88 register uint_t bit_pos_in_lw;
89 register uint_t *lw_ptr;
90 register uint_t data;
91 uint_t bit_data;
92
93 return (((*((ulong_t *)(((ulong_t)(buf)) + ((pos)>>3)))) >> ((pos) & 7)) & 1);
94
95 if (DTPRINT_FILE) printf ("extr2st buf %x pos %x temp %x ", buf, pos);
96
97 /*
98 (( ( *((((ulong_t *)_buf_) + ((_pos_)>>5))) ) >> ((_pos_) & 0x1F) )&1)
99 */
100
101 lw_ptr = buf + ( pos >> 5 );
102 data = *lw_ptr;
103 /* bit_mask = 0x1F - ( pos & 0x1F); */
104 bit_mask = (pos) & 0x1F;
105 bit_data = ( data >> bit_mask ) & 1;
106
107 if (DTPRINT_FILE) printf (" Data %x >> Mask %x = %d Bit %d\n", data, bit_mask, data>>bit_mask,bit_data);
108 /*
109 for (bit_mask=0; bit_mask<32; bit_mask++) {
110 printf ("%d=%x ", bit_mask, data>>bit_mask);
111 }
112 printf ("\n");
113 */
114 return (bit_data);
115 }
116 #endif
117
118 #ifdef VMS
119 #pragma inline (read_4state_to_value)
120 #endif
read_4state_to_value(const Signal_t * sig_ptr,const char * buf,Value_t * value_ptr)121 static void read_4state_to_value (
122 const Signal_t *sig_ptr,
123 const char *buf,
124 Value_t *value_ptr)
125 {
126 register int bitcnt, bit_pos;
127 int bitval;
128 int bitval_and, bitval_or;
129
130 /* Preset the state to be based upon first bit (to speed things up) */
131 bitval = EXTRACT_4STATE (buf, sig_ptr->file_pos);
132 if (bitval & 2) bitval ^= 1; /* decsim 2=Z which is STATE_Z=3 */
133 bitval_and = bitval_or = bitval;
134
135 /* Extract the values, HIGH 32 BITS */
136 bit_pos = sig_ptr->file_pos;
137 for (bitcnt=96; bitcnt < (MIN (128, sig_ptr->bits)); bitcnt++, bit_pos+=2) {
138 bitval = EXTRACT_4STATE (buf, bit_pos);
139 if (bitval & 2) bitval ^= 1; /* decsim 2=Z which is STATE_Z=3 */
140 bitval_and &= bitval; bitval_or |= bitval;
141 value_ptr->number[3] = (value_ptr->number[3]<<1) | (bitval&1);
142 value_ptr->number[7] = (value_ptr->number[7]<<1) | ((bitval>>1)&1);
143 }
144
145 /* Extract the values, UPPER MID 32 BITS */
146 bit_pos = sig_ptr->file_pos;
147 for (bitcnt=64; bitcnt < (MIN (96, sig_ptr->bits)); bitcnt++, bit_pos+=2) {
148 bitval = EXTRACT_4STATE (buf, bit_pos);
149 if (bitval & 2) bitval ^= 1; /* decsim 2=Z which is STATE_Z=3 */
150 bitval_and &= bitval; bitval_or |= bitval;
151 value_ptr->number[2] = (value_ptr->number[2]<<1) | (bitval&1);
152 value_ptr->number[6] = (value_ptr->number[6]<<1) | ((bitval>>1)&1);
153 }
154
155 /* Extract the values LOWER MID 32 BITS */
156 for (bitcnt=32; bitcnt < (MIN (64, sig_ptr->bits)); bitcnt++, bit_pos+=2) {
157 bitval = EXTRACT_4STATE (buf, bit_pos);
158 if (bitval & 2) bitval ^= 1; /* decsim 2=Z which is STATE_Z=3 */
159 bitval_and &= bitval; bitval_or |= bitval;
160 value_ptr->number[1] = (value_ptr->number[1]<<1) | (bitval&1);
161 value_ptr->number[5] = (value_ptr->number[5]<<1) | ((bitval>>1)&1);
162 }
163
164 /* Extract the values LOW 32 BITS */
165 for (bitcnt=0; bitcnt < (MIN (32, sig_ptr->bits)); bitcnt++, bit_pos+=2) {
166 bitval = EXTRACT_4STATE (buf, bit_pos);
167 if (bitval & 2) bitval ^= 1; /* decsim 2=Z which is STATE_Z=3 */
168 bitval_and &= bitval; bitval_or |= bitval;
169 value_ptr->number[0] = (value_ptr->number[0]<<1) | (bitval&1);
170 value_ptr->number[4] = (value_ptr->number[4]<<1) | ((bitval>>1)&1);
171 }
172
173 if (bitval_and == bitval_or) {
174 /* All bits the same */
175 switch (bitval) {
176 case STATE_1:
177 value_ptr->siglw.stbits.state = sig_ptr->type;
178 value_ptr->siglw.stbits.allhigh = TRUE;
179 break;
180 default: value_ptr->siglw.stbits.state = bitval; break;
181 }
182 } else {
183 val_minimize (value_ptr, NULL);
184 }
185 }
186
187 #ifdef VMS
188 #pragma inline (read_2state_to_value)
189 #endif
read_2state_to_value(const Signal_t * sig_ptr,const char * buf,Value_t * value_ptr)190 static void read_2state_to_value (
191 const Signal_t *sig_ptr,
192 const char *buf,
193 Value_t *value_ptr)
194 {
195 register int bitcnt, bit_pos;
196 int bitval;
197 int bitval_and;
198
199 /* Preset the state to be based upon first bit (to speed things up) */
200 bitval = EXTRACT_2STATE (buf, sig_ptr->file_pos);
201 bitval_and = bitval;
202
203 /* Extract the values, HIGH 32 BITS */
204 bit_pos = sig_ptr->file_pos;
205 for (bitcnt=96; bitcnt < (MIN (128, sig_ptr->bits)); bitcnt++, bit_pos++) {
206 bitval = EXTRACT_2STATE (buf, bit_pos);
207 value_ptr->number[3] = (value_ptr->number[3]<<1) | bitval;
208 }
209
210 /* Extract the values, UPPER MID 32 BITS */
211 for (bitcnt=64; bitcnt < (MIN (96, sig_ptr->bits)); bitcnt++, bit_pos++) {
212 bitval = EXTRACT_2STATE (buf, bit_pos);
213 value_ptr->number[2] = (value_ptr->number[2]<<1) | bitval;
214 }
215
216 /* Extract the values LOWER MID 32 BITS */
217 for (bitcnt=32; bitcnt < (MIN (64, sig_ptr->bits)); bitcnt++, bit_pos++) {
218 bitval = EXTRACT_2STATE (buf, bit_pos);
219 value_ptr->number[1] = (value_ptr->number[1]<<1) | bitval;
220 }
221
222 /* Extract the values LOW 32 BITS */
223 for (bitcnt=0; bitcnt < (MIN (32, sig_ptr->bits)); bitcnt++, bit_pos++) {
224 bitval = EXTRACT_2STATE (buf, bit_pos);
225 value_ptr->number[0] = (value_ptr->number[0]<<1) | bitval;
226 }
227
228 if (value_ptr->number[0] | value_ptr->number[1] | value_ptr->number[2] | value_ptr->number[3]) {
229 value_ptr->siglw.stbits.state = sig_ptr->type;
230 if (bitval_and) value_ptr->siglw.stbits.allhigh = TRUE;
231 } else {
232 value_ptr->siglw.stbits.state = STATE_0;
233 }
234 }
235
236 #ifdef VMS
237 #pragma inline (fil_decsim_binary_add_cptr)
238 #endif
fil_decsim_binary_add_cptr(Signal_t * sig_ptr,const char * buf,DTime_t time,Boolean_t nocheck)239 static void fil_decsim_binary_add_cptr (
240 /* Add a cptr corresponding to the decsim value for this signal */
241 Signal_t *sig_ptr,
242 const char *buf,
243 DTime_t time,
244 Boolean_t nocheck) /* don't compare against previous data */
245 {
246 register int state;
247 Value_t value;
248
249 /* zero the value */
250 val_zero (&value);
251
252 if (sig_ptr->bits < 2) {
253 /* Single bit signal */
254 if (sig_ptr->file_type.flag.four_state == 0)
255 state = EXTRACT_2STATE (buf, sig_ptr->file_pos)?STATE_1:STATE_0;
256 else {
257 /*
258 if (DTDEBUG &&
259 (EXTRACT_4STATE (buf, sig_ptr->file_pos) !=
260 ((EXTRACT_2STATE (buf, sig_ptr->file_pos+1) * 2) +
261 EXTRACT_2STATE (buf, sig_ptr->file_pos))))
262 printf ("Mismatch@%d %s: %d!=%d,%d,%d\n",
263 sig_ptr->file_pos,
264 sig_ptr->signame,
265 EXTRACT_4STATE (buf, sig_ptr->file_pos),
266 EXTRACT_2STATE (buf, sig_ptr->file_pos + 1),
267 EXTRACT_2STATE (buf, sig_ptr->file_pos),
268 EXTRACT_2STATE (buf, sig_ptr->file_pos - 1));
269 */
270
271 state = EXTRACT_4STATE (buf, sig_ptr->file_pos);
272 if (state & 2) state ^= 1; /* decsim 2=Z which is STATE_Z=3 */
273 }
274 }
275 else {
276 /* Multibit signal */
277 if (sig_ptr->file_type.flag.four_state == 0)
278 read_2state_to_value (sig_ptr, buf, &value);
279 else read_4state_to_value (sig_ptr, buf, &value);
280 }
281
282 value.time = time;
283 fil_add_cptr (sig_ptr, &value, nocheck);
284 }
285
286 #ifndef VMS
never_just_to_avoid_unused(void)287 void never_just_to_avoid_unused (void) {
288 fil_decsim_binary_add_cptr (NULL, NULL, 0, 0);
289 }
290 #endif
291
292 #ifdef VMS
decsim_read_binary(Trace_t * trace,int read_fd)293 void decsim_read_binary (
294 Trace_t *trace,
295 int read_fd)
296 {
297 static struct bintrarec *buf, *last_buf;
298 static struct bintrarec bufa;
299 static struct bintrarec bufb;
300 int first_data=TRUE; /* True till first data is loaded */
301 int len;
302 int next_different_lw_pos; /* LW pos with different value than last time slice */
303 int time;
304 Signal_t *sig_ptr,*last_sig_ptr;
305 int max_lw_pos=0; /* Maximum position in buf that has trace data */
306 DTime_t time_divisor;
307
308 time_divisor = time_units_to_multiplier (global->time_precision);
309
310 /* Signal description data */
311 last_sig_ptr = NULL;
312 trace->firstsig = NULL;
313
314 /* setup data buffers */
315 buf = &bufa;
316 last_buf = &bufb;
317
318 for (;;) {
319 /* Alternate between buffers so that we have the data from the last time slice */
320 if (last_buf == &bufb) {
321 buf = &bufb;
322 last_buf = &bufa;
323 }
324 else {
325 buf = &bufa;
326 last_buf = &bufb;
327 }
328
329 if (read (read_fd, buf, sizeof (struct bintrarec)) == 0) {
330 break;
331 }
332
333 switch (buf->tra$b_class) {
334 /***** CLASS: Header *****/
335 case tra$k_mhr:
336 switch (buf->tra$b_type) {
337 case tra$k_mmh:
338 case tra$k_mdr:
339 break;
340 default:
341 if (DTPRINT) printf ( "%%E, Unknown header type %d\n", buf->tra$b_type);
342 }
343 break;
344
345 /***** CLASS: Signal *****/
346 case tra$k_sir:
347 switch (buf->tra$b_type) {
348 /**** TYPE: Begin Of Signal Section ****/
349 case tra$k_nns:
350 break;
351
352 /**** TYPE: End Of Signal Section ****/
353 case tra$k_nss:
354 fil_make_busses (trace, TRUE);
355 break;
356
357 /**** TYPE: Unknown ****/
358 default:
359 if (DTPRINT) printf ("%%E, Unknown section identifier type %d\n", buf->tra$b_type);
360 }
361 break;
362
363 /***** CLASS: Data records *****/
364 case tra$k_dr:
365 switch (buf->tra$b_type) {
366
367 /**** TYPE: Node format data ****/
368 case tra$k_nfd:
369 /* This should be rewritten to use signal_new_file */
370 error_needs_rewrite_to_use_signal_new_file__contact_wsnyder; /* Comment this out, and it might work though!*/
371 sig_ptr = DNewCalloc (Signal_t);
372 sig_ptr->trace = trace;
373 sig_ptr->dfile = &(trace->dfile);
374 sig_ptr->radix = global->radixs[0];
375 sig_ptr->file_pos = buf->TRA$L_BITPOS;
376 /* if (DTPRINT_FILE) printf ("Reading signal format data, ptr=%d\n", sig_ptr); */
377
378 sig_ptr->file_type.flags = 0;
379 sig_ptr->file_type.flag.four_state = ! (buf->TRA$B_DATTYP == tra$k_twosta);
380
381 /* Save the maximum position in the trace */
382 if ((sig_ptr->file_pos >> 5) > max_lw_pos) {
383 max_lw_pos = ( (sig_ptr->file_pos + (sig_ptr->file_type.flag.four_state ? 2:1)
384 * sig_ptr->bits ) >> 5) + 1 /* so over estimate */;
385 }
386
387 /* initialize all the pointers that aren't NULL */
388 if (last_sig_ptr) last_sig_ptr->forward = sig_ptr;
389 sig_ptr->backward = last_sig_ptr;
390 if (trace->firstsig==NULL) trace->firstsig = sig_ptr;
391 trace->lastsig = sig_ptr;
392 break;
393
394 /**** TYPE: Node signal name data ****/
395 case tra$k_nnr:
396 /* if (DTPRINT_FILE) printf ("Reading signal name data, ptr=%d\n", sig_ptr); */
397 len = buf->TRA$W_NODNAMLEN;
398 sig_ptr->signame = (char *)XtMalloc(16+len); /* allow extra space in case becomes vector */
399 strncpy (sig_ptr->signame, buf->TRA$T_NODNAMSTR, (size_t) len);
400 sig_ptr->signame[len] = '\0';
401
402 last_sig_ptr = sig_ptr;
403 break;
404
405 /**** TYPE: Node state data ****/
406 case tra$k_nsr:
407 time = ((buf->TRA$L_TIME_LO>>1)&0x3FFFFFFF) / time_divisor +
408 ((buf->TRA$L_TIME_HI)&0x3FFFFFFF) * (0x40000000 / time_divisor);
409
410 /* save start/ end time */
411 if (first_data) {
412 trace->start_time = time;
413 }
414 trace->end_time = time;
415
416 /* Compute first LW that has a different value in it */
417 next_different_lw_pos = trace->firstsig->file_pos >> 5; /* Grab first pos in LWs */
418 while ( next_different_lw_pos <= max_lw_pos
419 && ( ((long *)buf)[next_different_lw_pos]
420 == ((long *)last_buf)[next_different_lw_pos] )) {
421 next_different_lw_pos++;
422 }
423 /*
424 printf ("ST %d-%d %c%c%c%c%c: ", next_different_lw_pos, max_lw_pos,
425 ( ((long *)buf)[5] == ((long *)last_buf)[5])?'-':'5',
426 ( ((long *)buf)[6] == ((long *)last_buf)[6])?'-':'6',
427 ( ((long *)buf)[7] == ((long *)last_buf)[7])?'-':'7',
428 ( ((long *)buf)[8] == ((long *)last_buf)[8])?'-':'8',
429 ( ((long *)buf)[9] == ((long *)last_buf)[9])?'-':'9'
430 );
431 */
432
433 /* save data for each signal */
434 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
435 if (( next_different_lw_pos <= (sig_ptr->file_end_pos >> 5)) || first_data) {
436 /* A bit in this signal's range has changed. Decode the value.
437 This signal itself may not have changed though, since there could
438 be 31 of 32 signals in this LW that were not changed. */
439
440 fil_decsim_binary_add_cptr (sig_ptr, buf, time, first_data);
441
442 /* Compute next different lw */
443 if (((sig_ptr->file_end_pos + 1) >> 5) > next_different_lw_pos) {
444 /* This signal completely used the different lw, find another */
445 /* (else there are other signals later also using this lw) */
446 next_different_lw_pos = (sig_ptr->file_end_pos+1) >> 5; /* Cvt to LW position */
447 while ( next_different_lw_pos <= max_lw_pos
448 && ( ((long *)buf)[next_different_lw_pos]
449 == ((long *)last_buf)[next_different_lw_pos] )) {
450 next_different_lw_pos++;
451 }
452 /* printf ("%d ", next_different_lw_pos); */
453 }
454 }
455
456 /* else signal couldn't have changed in this time slice.
457 This speed bypass saves an enourmous amount of time */
458 else {
459 /* For debugging, Accumulate statistics on how often we skipped this signal */
460 /* sig_ptr->color ++; */
461 }
462 }
463 /* printf ("\n"); */
464
465 first_data = FALSE;
466 break;
467
468 /**** TYPE: Unknown ****/
469 default:
470 if (DTDEBUG) printf ("Unknown data record type %d\n", buf->tra$b_type);
471 }
472 break;
473
474 /**** CLASS: EOF ****/
475 case tra$k_mtr:
476 break;
477
478 /**** CLASS: Unknown ****/
479 default:
480 if (DTPRINT_FILE) printf ("Unknown record class %d, assuming ASCII\n", buf->tra$b_class);
481 ascii_read (trace, read_fd, NULL);
482 return;
483 }
484 }
485
486 if (DTPRINT_FILE) printf ("Times = %d to %d\n", trace->start_time, trace->end_time);
487
488 /* Print skipping statistics * /
489 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
490 printf ("%d\tLW %d-%d\tSig %s\n",sig_ptr->color,
491 sig_ptr->file_pos >> 5, sig_ptr->file_end_pos >> 5, sig_ptr->signame);
492 sig_ptr->color = 0;
493 }
494 */
495 }
496 #endif /* VMS */
497
498
499 #ifdef VMS
500 #pragma inline (fil_tempest_binary_add_cptr)
501 #endif
fil_tempest_binary_add_cptr(Signal_t * sig_ptr,const uint_t * buf,DTime_t time,Boolean_t nocheck)502 static void fil_tempest_binary_add_cptr (
503 /* Add a cptr corresponding to the text at value_strg */
504 Signal_t *sig_ptr,
505 const uint_t *buf,
506 DTime_t time,
507 Boolean_t nocheck) /* don't compare against previous data */
508 {
509 register int state=STATE_U, bit;
510 register uint_t value_index;
511 register uint_t data_index;
512 register uint_t data_mask;
513 Value_t value;
514
515 /* zero the value */
516 val_zero (&value);
517
518 /* determine starting index and bit mask */
519 if (sig_ptr->bits < 2) {
520 /* Single bit signal */
521 if (sig_ptr->file_type.flag.four_state == 0) {
522 data_index = (sig_ptr->file_pos >> 5);
523 data_mask = 1 << ((sig_ptr->file_pos) & 0x1F);
524
525 state = (buf[data_index] & data_mask)?STATE_1:STATE_0;
526 }
527
528 else { /* Single bit four state (not really supported) */
529 data_index = (sig_ptr->file_pos >> 5);
530 data_mask = 1 << ((sig_ptr->file_pos) & 0x1F);
531
532 value_index = (buf[data_index] & data_mask); /* Used as temp */
533 if (!(data_mask = data_mask << 1)) {
534 data_mask = 1;
535 data_index++;
536 }
537 /* Note STATE_ encodings map directly to the 4 state values */
538 state = (value_index << 1) + (buf[data_index] & data_mask);
539 }
540 }
541 else {
542 /* Multibit signal */
543 if (sig_ptr->file_type.flag.four_state == 0) {
544 buf += (sig_ptr->file_pos >> 5); /* Point to LSB's LW */
545 bit = (sig_ptr->file_pos & 0x1f); /* Point to LSB's bit position in LW */
546
547 /* We want to take the data and move it so that the LSB of the data to be extracted is
548 now in value[0]. This is effectively a shift right of "bit" bits. The fun comes in
549 because we want more than one LW of accuracy. (Give me a 128 bit architecture!)
550 This method runs fast because it can execute in parallel and has no branches. */
551
552 value.number[0] = (((buf[0] >> bit) & sig_ptr->pos_mask)
553 | ((buf[1] << (32-bit)) & (~sig_ptr->pos_mask)))
554 & sig_ptr->value_mask[0];
555 value.number[1] = (((buf[1] >> bit) & sig_ptr->pos_mask)
556 | ((buf[2] << (32-bit)) & (~sig_ptr->pos_mask)))
557 & sig_ptr->value_mask[1];
558 value.number[2] = (((buf[2] >> bit) & sig_ptr->pos_mask)
559 | ((buf[3] << (32-bit)) & (~sig_ptr->pos_mask)))
560 & sig_ptr->value_mask[2];
561 value.number[3] = (((buf[3] >> bit) & sig_ptr->pos_mask)
562 | ((buf[4] << (32-bit)) & (~sig_ptr->pos_mask)))
563 & sig_ptr->value_mask[3];
564 if (value.number[0] | value.number[1] | value.number[2] | value.number[3]) {
565 if (( value.number[0] == sig_ptr->value_mask[0])
566 & (value.number[1] == sig_ptr->value_mask[1])
567 & (value.number[2] == sig_ptr->value_mask[2])
568 & (value.number[3] == sig_ptr->value_mask[3])) {
569 value.siglw.stbits.allhigh = TRUE;
570 }
571 state = sig_ptr->type;
572 } else {
573 state = STATE_0;
574 }
575 }
576 else {
577 state = STATE_U;
578 }
579 }
580
581 value.siglw.stbits.state = state;
582 value.time = time;
583 fil_add_cptr (sig_ptr, &value, nocheck);
584
585 /*if (DTPRINT_FILE) printf ("Sig %s State %d Value %d\n", sig_ptr->signame, value.siglw.stbits.state,
586 value.number[0]);*/
587 }
588
bin_read(int fd,void * buf,size_t size)589 static int bin_read (int fd, void *buf, size_t size)
590 {
591 size_t got_tot = 0;
592 size_t remaining = size;
593 char* bufc = (char*)buf;
594 if (size <= 0) return 0;
595 do {
596 int got_this = read (fd, bufc, remaining);
597 if (got_this>0) {
598 got_tot += got_this;
599 bufc += got_this;
600 remaining -= got_this;
601 } else if (got_this < 0) {
602 if (errno != EAGAIN && errno != EINTR) {
603 /* read failed, presume error */
604 printf("Read failed in bin_read (%i, -, %i)\n", fd, (int)size);
605 perror("dinotrace");
606 break;
607 } else {
608 got_this = 0;
609 }
610 } else {
611 /* end-of-file */
612 break;
613 }
614 } while (got_tot < size);
615 return (got_tot);
616 }
617
bin_read_little_uint_t32(int read_fd)618 static uint_t bin_read_little_uint_t32 (int read_fd)
619 /* Read a little endian 32 bit uint_t, correct to internal representation */
620 {
621 uint_t status;
622 uint_t littledata;
623 uint_t naturaldata;
624
625 status = bin_read (read_fd, &littledata, 4);
626 if (status) {} // UNUSED
627 /* Actually it's ANTILITTLE, but it's a symetric function */
628 naturaldata = LITTLEENDIANIZE32 (littledata);
629 return (naturaldata);
630 }
631
tempest_read(Trace_t * trace,int read_fd)632 void tempest_read (
633 Trace_t *trace,
634 int read_fd)
635 {
636 uint_t status;
637 uint_t numBytes,numRows,numBitsRow,numBitsRowPad;
638 uint_t *data;
639 uint_t *data_xor;
640 Boolean_t first_data;
641 Boolean_t have_phase = FALSE;
642 uint_t i,j;
643 uint_t pad_len;
644 uint_t time, last_time=EOT;
645 Signal_t *sig_ptr=NULL;
646 Boolean_t verilator_xor_format;
647 char chardata[4096];
648
649 /* Read the file identification block */
650 status = bin_read (read_fd, chardata, 4);
651 chardata[4]='\0';
652 verilator_xor_format = !strncmp (chardata,"BX",2);
653 if (!status || (!strncmp (chardata,"BT",2) && !strncmp (chardata,"BX",2) )) {
654 sprintf (message, "Bad File Format (=%s)\n", chardata);
655 dino_error_ack(trace, message);
656 return;
657 }
658
659 numBytes = bin_read_little_uint_t32 (read_fd);
660 trace->numsig = bin_read_little_uint_t32 (read_fd);
661 numRows = bin_read_little_uint_t32 (read_fd);
662 numBitsRow = bin_read_little_uint_t32 (read_fd);
663 numBitsRowPad = bin_read_little_uint_t32 (read_fd);
664
665 if (DTPRINT_FILE) {
666 if (verilator_xor_format) printf ("This is Verilator Compressed XOR format.\n");
667 printf ("File Sig=%s Bytes=%d Signals=%d Rows=%d Bits/Row=%d Bits/Row(pad)=%d\n",
668 chardata,numBytes,trace->numsig,numRows,numBitsRow,numBitsRowPad);
669 }
670
671 /** Read the signal description data - a signal description block is
672 ** created for each signal describing the signal and containing ptrs
673 ** for the trace data, current trace location, etc.
674 */
675 trace->firstsig=NULL;
676 for (i=0;i<trace->numsig;i++) {
677 union sig_file_type_u file_type;
678 uint_t sigChars,sigFlags,sigOffset,sigWidth;
679
680 sigFlags = bin_read_little_uint_t32 (read_fd);
681 sigOffset = bin_read_little_uint_t32 (read_fd);
682 sigWidth = bin_read_little_uint_t32 (read_fd);
683 sigChars = bin_read_little_uint_t32 (read_fd);
684 if (sigChars >= sizeof(chardata)) {
685 sprintf (message, "Signal name too long (=%d): Trace may be corrupt.\n", sigChars);
686 dino_error_ack(trace, message);
687 return;
688 }
689
690 status = bin_read (read_fd, chardata, sigChars);
691 chardata[sigChars] = '\0';
692
693 if (DTPRINT_FILE) {
694 printf ("sigFlags=%x sigOffset=%d sigWidth=%d sigChars=%d sigName=%s\n",
695 sigFlags,sigOffset,sigWidth,sigChars,chardata);
696 }
697
698 /* These could be simplified as they map 1:1, but safer not to */
699 file_type.flags = 0;
700 file_type.flag.pin_input = ((sigFlags & 1) != 0);
701 file_type.flag.pin_output = ((sigFlags & 2) != 0);
702 file_type.flag.pin_psudo = ((sigFlags & 4) != 0);
703 file_type.flag.pin_timestamp = ((sigFlags & 8) != 0);
704 file_type.flag.four_state = ((sigFlags & 16) != 0);
705
706 sig_new_file (trace, chardata,
707 sigOffset, 0,
708 sigWidth, -1/*msb*/, -1/*lsb*/,
709 file_type);
710
711 /* Detect phase signal -- not completely reliable */
712 /* This prevents a bug when a trace starts on phase b */
713 if (sigOffset < 64
714 && (0==strcmp ("Phase", chardata+sigChars-5)
715 || 0==strcmp ("phase", chardata+sigChars-5))) {
716 if (DTPRINT_FILE) printf ("Have Phase indication\n");
717 have_phase = TRUE;
718 }
719
720 /* Checks */
721 if (file_type.flag.four_state != 0) {
722 sprintf (message,"Four state tempest not supported.\nSignal %s will be wrong.",chardata);
723 dino_warning_ack (trace, message);
724 }
725
726 /* Read the pad bits */
727 pad_len = (sigChars%8) ? 8 - (sigChars%8) : 0;
728 status = bin_read (read_fd, chardata, pad_len);
729 }
730
731 /* Make the busses */
732 fil_make_busses (trace, FALSE);
733
734 /* Make storage space, with some overhead */
735 data = (uint_t *)XtCalloc (32 + numBitsRowPad/32, sizeof(uint_t));
736 data_xor = (uint_t *)XtCalloc (32 + numBitsRowPad/32, sizeof(uint_t));
737
738 /* Read the signal trace data
739 * Pass 0-(numRows-1) reads the data, pass numRows processes last line */
740 first_data = TRUE;
741
742 /* Don't use numRows as it is written when CCLI exits, and may be incorrect
743 if CCLI was CTL-Ced */
744
745 while (1) {
746 /* Read a row of data */
747 if (verilator_xor_format) {
748 status = bin_read (read_fd, data_xor, numBitsRowPad/8);
749 if (status < numBitsRowPad/8) break; /* End of data */
750
751 /* Un-exor the data */
752 /* Correct endianization */
753 for (j = 0; j <= (numBitsRowPad/(sizeof(uint_t)*8)); j++) {
754 uint_t littledata = data_xor[j];
755 /* cppcheck-suppress selfAssignment */
756 littledata = LITTLEENDIANIZE32 (littledata);
757 data[j] ^= littledata;
758 }
759 }
760 else {
761 /* Regular format */
762 status = bin_read (read_fd, data, numBitsRowPad/8);
763 if (status < numBitsRowPad/8) break; /* End of data */
764
765 /* Correct endianization */
766 #if WORDS_BIGENDIAN /* If little, make sure whole loop goes away */
767 for (j = 0; j <= (numBitsRowPad/(sizeof(uint_t)*8)); j++) {
768 uint_t littledata = data[j];
769 data[j] = LITTLEENDIANIZE32 (littledata);
770 }
771 #endif
772 }
773
774 /** Extract the phase - this will be used as a 'time' value and
775 ** is multiplied by 100 to make the trace easier to read
776 */
777
778 time = data[0] * global->tempest_time_mult;
779 if (time == last_time) time+= MAX(1,global->tempest_time_mult/2);
780 last_time = time;
781 if (first_data && have_phase) {
782 int phase = data[1] & 1;
783 if (phase) time += MAX(1,global->tempest_time_mult/2);
784 if (DTPRINT_FILE) printf ("Initial phase detected: %d Adjust 1|%d\n", phase, global->tempest_time_mult/2);
785 }
786
787 #if 0
788 if (DTPRINT_FILE) {
789 printf ("read: time=%d status %d data=%08x [time %d] %08x\n", time,
790 status, data[0], data[0], data[1]);
791 }
792 #endif
793
794 /*
795 ** If this is the first row, save the starting and initial
796 ** time, else eventually the end time will be saved.
797 */
798 if (first_data)
799 trace->start_time = time;
800 else trace->end_time = time;
801
802 /* Fortunately, Tempest and Decsim have identical binary packed formats. */
803 /* Perhaps it's because both were written by Digital's SEG CAD. */
804 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
805 fil_tempest_binary_add_cptr (sig_ptr, data, time, first_data);
806 }
807
808 first_data = FALSE;
809 }/* end for */
810
811 DFree (data);
812 }
813
814