1 /*
2  * Copyright (c) Tony Bybell 2013-2017.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  */
9 
10 #include <config.h>
11 #include <fstapi.h>
12 #include "fsdb_wrapper_api.h"
13 
14 #ifdef WAVE_FSDB_READER_IS_PRESENT
15 
16 #ifdef NOVAS_FSDB
17 #undef NOVAS_FSDB
18 #endif
19 
20 #include "ffrAPI.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #ifdef HAVE_INTTYPES_H
24 #include <inttypes.h>
25 #endif
26 
27 #define FSDBR_FXT2U64(xt) (((uint64_t)(xt).hltag.H << 32) | ((uint64_t)(xt).hltag.L))
28 
29 #ifndef FALSE
30 #define FALSE   0
31 #endif
32 
33 #ifndef TRUE
34 #define TRUE    1
35 #endif
36 
__TreeCB(fsdbTreeCBType cb_type,void * client_data,void * tree_cb_data)37 static bool_T __TreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data)
38 {
39 return(TRUE); /* currently unused along with var/scope traversal */
40 }
41 
42 static bool_T __MyTreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data);
43 
44 
fsdbReaderOpenFile(char * nam)45 extern "C" void *fsdbReaderOpenFile(char *nam)
46 {
47 fsdbFileType ft;
48 uint_T blk_idx = 0;
49 
50 if(!ffrObject::ffrIsFSDB(nam))
51 	{
52 	return(NULL);
53 	}
54 
55 ffrFSDBInfo fsdb_info;
56 ffrObject::ffrGetFSDBInfo(nam, fsdb_info);
57 if((fsdb_info.file_type != FSDB_FT_VERILOG) && (fsdb_info.file_type != FSDB_FT_VERILOG_VHDL) && (fsdb_info.file_type != FSDB_FT_VHDL))
58 	{
59 	return(NULL);
60 	}
61 
62 ffrObject *fsdb_obj = ffrObject::ffrOpen3(nam);
63 if(!fsdb_obj)
64 	{
65 	return(NULL);
66 	}
67 
68 fsdb_obj->ffrSetTreeCBFunc(__TreeCB, NULL);
69 
70 ft = fsdb_obj->ffrGetFileType();
71 if((ft != FSDB_FT_VERILOG) && (ft != FSDB_FT_VERILOG_VHDL) && (ft != FSDB_FT_VHDL))
72 	{
73         fsdb_obj->ffrClose();
74 	return(NULL);
75 	}
76 
77 fsdb_obj->ffrReadDataTypeDefByBlkIdx(blk_idx); /* necessary if FSDB file has transaction data ... we don't process this but it prevents possible crashes */
78 
79 return((void *)fsdb_obj);
80 }
81 
82 
fsdbReaderReadScopeVarTree(void * ctx,void (* cb)(void *))83 extern "C" void fsdbReaderReadScopeVarTree(void *ctx,void (*cb)(void *))
84 {
85 ffrObject *fsdb_obj = (ffrObject *)ctx;
86 
87 fsdb_obj->ffrSetTreeCBFunc(__MyTreeCB, (void *) cb);
88 fsdb_obj->ffrReadScopeVarTree();
89 }
90 
91 
fsdbReaderGetMaxVarIdcode(void * ctx)92 extern "C" int fsdbReaderGetMaxVarIdcode(void *ctx)
93 {
94 ffrObject *fsdb_obj = (ffrObject *)ctx;
95 fsdbVarIdcode max_var_idcode = fsdb_obj->ffrGetMaxVarIdcode();
96 return(max_var_idcode);
97 }
98 
99 
fsdbReaderAddToSignalList(void * ctx,int i)100 extern "C" void fsdbReaderAddToSignalList(void *ctx, int i)
101 {
102 ffrObject *fsdb_obj = (ffrObject *)ctx;
103 fsdb_obj->ffrAddToSignalList(i);
104 }
105 
106 
fsdbReaderResetSignalList(void * ctx)107 extern "C" void fsdbReaderResetSignalList(void *ctx)
108 {
109 ffrObject *fsdb_obj = (ffrObject *)ctx;
110 fsdb_obj->ffrResetSignalList();
111 }
112 
113 
fsdbReaderLoadSignals(void * ctx)114 extern "C" void fsdbReaderLoadSignals(void *ctx)
115 {
116 ffrObject *fsdb_obj = (ffrObject *)ctx;
117 fsdb_obj->ffrLoadSignals();
118 }
119 
120 
fsdbReaderCreateVCTraverseHandle(void * ctx,int i)121 extern "C" void *fsdbReaderCreateVCTraverseHandle(void *ctx, int i)
122 {
123 ffrObject *fsdb_obj = (ffrObject *)ctx;
124 ffrVCTrvsHdl hdl = fsdb_obj->ffrCreateVCTraverseHandle(i);
125 return((void *)hdl);
126 }
127 
128 
fsdbReaderHasIncoreVC(void * ctx,void * hdl)129 extern "C" int fsdbReaderHasIncoreVC(void *ctx, void *hdl)
130 {
131 ffrObject *fsdb_obj = (ffrObject *)ctx;
132 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
133 return(fsdb_hdl->ffrHasIncoreVC() == TRUE);
134 }
135 
136 
fsdbReaderFree(void * ctx,void * hdl)137 extern "C" void fsdbReaderFree(void *ctx, void *hdl)
138 {
139 ffrObject *fsdb_obj = (ffrObject *)ctx;
140 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
141 
142 fsdb_hdl->ffrFree();
143 }
144 
145 
fsdbReaderGetMinXTag(void * ctx,void * hdl)146 extern "C" uint64_t fsdbReaderGetMinXTag(void *ctx, void *hdl)
147 {
148 ffrObject *fsdb_obj = (ffrObject *)ctx;
149 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
150 fsdbTag64 timetag;
151 
152 fsdb_hdl->ffrGetMinXTag((void*)&timetag);
153 uint64_t rv = (((uint64_t)timetag.H) << 32) | ((uint64_t)timetag.L);
154 return(rv);
155 }
156 
157 
fsdbReaderGetMaxXTag(void * ctx,void * hdl)158 extern "C" uint64_t fsdbReaderGetMaxXTag(void *ctx, void *hdl)
159 {
160 ffrObject *fsdb_obj = (ffrObject *)ctx;
161 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
162 fsdbTag64 timetag;
163 
164 fsdb_hdl->ffrGetMaxXTag((void*)&timetag);
165 uint64_t rv = (((uint64_t)timetag.H) << 32) | ((uint64_t)timetag.L);
166 return(rv);
167 }
168 
169 
fsdbReaderGotoXTag(void * ctx,void * hdl,uint64_t tim)170 extern "C" int fsdbReaderGotoXTag(void *ctx, void *hdl, uint64_t tim)
171 {
172 ffrObject *fsdb_obj = (ffrObject *)ctx;
173 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
174 fsdbTag64 timetag;
175 
176 timetag.H = (uint32_t)(tim >> 32);
177 timetag.L = (uint32_t)(tim & 0xFFFFFFFFUL);
178 
179 return(fsdb_hdl->ffrGotoXTag((void*)&timetag) == FSDB_RC_SUCCESS);
180 }
181 
182 
fsdbReaderGetXTag(void * ctx,void * hdl,int * rc)183 extern "C" uint64_t fsdbReaderGetXTag(void *ctx, void *hdl, int *rc)
184 {
185 ffrObject *fsdb_obj = (ffrObject *)ctx;
186 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
187 fsdbTag64 timetag;
188 
189 *rc = (fsdb_hdl->ffrGetXTag((void*)&timetag) == FSDB_RC_SUCCESS);
190 uint64_t rv = (((uint64_t)timetag.H) << 32) | ((uint64_t)timetag.L);
191 return(rv);
192 }
193 
194 
fsdbReaderGetVC(void * ctx,void * hdl,void ** val_ptr)195 extern "C" int fsdbReaderGetVC(void *ctx, void *hdl, void **val_ptr)
196 {
197 ffrObject *fsdb_obj = (ffrObject *)ctx;
198 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
199 
200 return(fsdb_hdl->ffrGetVC((byte_T**)val_ptr) == FSDB_RC_SUCCESS);
201 }
202 
203 
fsdbReaderGotoNextVC(void * ctx,void * hdl)204 extern "C" int fsdbReaderGotoNextVC(void *ctx, void *hdl)
205 {
206 ffrObject *fsdb_obj = (ffrObject *)ctx;
207 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
208 
209 return(fsdb_hdl->ffrGotoNextVC() == FSDB_RC_SUCCESS);
210 }
211 
212 
fsdbReaderUnloadSignals(void * ctx)213 extern "C" void fsdbReaderUnloadSignals(void *ctx)
214 {
215 ffrObject *fsdb_obj = (ffrObject *)ctx;
216 fsdb_obj->ffrUnloadSignals();
217 }
218 
219 
fsdbReaderClose(void * ctx)220 extern "C" void fsdbReaderClose(void *ctx)
221 {
222 ffrObject *fsdb_obj = (ffrObject *)ctx;
223 fsdb_obj->ffrClose();
224 }
225 
226 
fsdbReaderGetBytesPerBit(void * hdl)227 extern "C" int fsdbReaderGetBytesPerBit(void *hdl)
228 {
229 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
230 
231 return(fsdb_hdl->ffrGetBytesPerBit());
232 }
233 
234 
fsdbReaderGetBitSize(void * hdl)235 extern "C" int fsdbReaderGetBitSize(void *hdl)
236 {
237 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
238 
239 return(fsdb_hdl->ffrGetBitSize());
240 }
241 
242 
fsdbReaderGetVarType(void * hdl)243 extern "C" int fsdbReaderGetVarType(void *hdl)
244 {
245 ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl;
246 
247 return(fsdb_hdl->ffrGetVarType());
248 }
249 
250 
fsdbReaderTranslateVC(void * hdl,void * val_ptr)251 extern "C" char *fsdbReaderTranslateVC(void *hdl, void *val_ptr)
252 {
253 ffrVCTrvsHdl vc_trvs_hdl = (ffrVCTrvsHdl)hdl;
254 byte_T *vc_ptr = (byte_T *)val_ptr;
255 
256 static byte_T buffer[FSDB_MAX_BIT_SIZE+1];
257 uint_T i;
258 fsdbVarType   var_type;
259 
260 switch (vc_trvs_hdl->ffrGetBytesPerBit())
261 	{
262 	case FSDB_BYTES_PER_BIT_1B:
263 	        for (i = 0; i < vc_trvs_hdl->ffrGetBitSize(); i++)
264 			{
265 		    	switch(vc_ptr[i])
266 				{
267 	 	    		case FSDB_BT_VCD_0:
268 		        		buffer[i] = '0';
269 		        		break;
270 
271 		    		case FSDB_BT_VCD_1:
272 		        		buffer[i] = '1';
273 		        		break;
274 
275 		    		case FSDB_BT_VCD_Z:
276 		        		buffer[i] = 'z';
277 		        		break;
278 
279 		    		case FSDB_BT_VCD_X:
280 		    		default:
281 		        		buffer[i] = 'x';
282 					break;
283 		    		}
284 	        	}
285 	        buffer[i] = 0;
286 		break;
287 
288 	case FSDB_BYTES_PER_BIT_2B:
289 	        for (i = 0; i < vc_trvs_hdl->ffrGetBitSize(); i++)
290 			{
291 		    	switch(vc_ptr[i * 2])
292 				{
293 				case FSDB_BT_EVCD_D:
294 				case FSDB_BT_EVCD_d:
295 				case FSDB_BT_EVCD_L:
296 				case FSDB_BT_EVCD_l:
297 				case FSDB_BT_EVCD_0:
298 		        		buffer[i] = '0';
299 		        		break;
300 
301 				case FSDB_BT_EVCD_U:
302 				case FSDB_BT_EVCD_u:
303 				case FSDB_BT_EVCD_H:
304 				case FSDB_BT_EVCD_h:
305 				case FSDB_BT_EVCD_1:
306 		        		buffer[i] = '1';
307 		        		break;
308 
309 				case FSDB_BT_EVCD_Z:
310 				case FSDB_BT_EVCD_T:
311 				case FSDB_BT_EVCD_F:
312 				case FSDB_BT_EVCD_f:
313 		        		buffer[i] = 'z';
314 		        		break;
315 
316 				case FSDB_BT_EVCD_N:
317 				case FSDB_BT_EVCD_X:
318 				case FSDB_BT_EVCD_QSTN:
319 				case FSDB_BT_EVCD_A:
320 				case FSDB_BT_EVCD_a:
321 				case FSDB_BT_EVCD_B:
322 				case FSDB_BT_EVCD_b:
323 				case FSDB_BT_EVCD_C:
324 				case FSDB_BT_EVCD_c:
325 		    		default:
326 		        		buffer[i] = 'x';
327 					break;
328 		    		}
329 	        	}
330 	        buffer[i] = 0;
331 		break;
332 
333 	case FSDB_BYTES_PER_BIT_4B:
334 		var_type = vc_trvs_hdl->ffrGetVarType();
335 		switch(var_type)
336 			{
337 			case FSDB_VT_VCD_MEMORY_DEPTH:
338 			case FSDB_VT_VHDL_MEMORY_DEPTH:
339 				buffer[0] = 0;
340 				break;
341 
342 			default:
343 				vc_trvs_hdl->ffrGetVC(&vc_ptr);
344 				sprintf((char *)buffer, "%f", *((float*)vc_ptr));
345 				break;
346 			}
347 		break;
348 
349 	case FSDB_BYTES_PER_BIT_8B:
350 		sprintf((char *)buffer, "%.16g", *((double*)vc_ptr));
351 		break;
352 
353 	default:
354 		buffer[0] = 0;
355 		break;
356 	}
357 
358 return((char *)buffer);
359 }
360 
361 
fsdbReaderExtractScaleUnit(void * ctx,int * mult,char * scale)362 extern "C" int fsdbReaderExtractScaleUnit(void *ctx, int *mult, char *scale)
363 {
364 ffrObject *fsdb_obj = (ffrObject *)ctx;
365 uint_T digit;
366 char *unit;
367 
368 str_T su = fsdb_obj->ffrGetScaleUnit();
369 fsdbRC rc = fsdb_obj->ffrExtractScaleUnit(su, digit, unit);
370 
371 if(rc == FSDB_RC_SUCCESS)
372 	{
373 	*mult = digit ? ((int)digit) : 1; /* in case digit is zero */
374 	*scale = unit[0];
375 	}
376 
377 return(rc == FSDB_RC_SUCCESS);
378 }
379 
380 
fsdbReaderGetMinFsdbTag64(void * ctx,uint64_t * tim)381 extern "C" int fsdbReaderGetMinFsdbTag64(void *ctx, uint64_t *tim)
382 {
383 ffrObject *fsdb_obj = (ffrObject *)ctx;
384 fsdbTag64 tag64;
385 fsdbRC rc = fsdb_obj->ffrGetMinFsdbTag64(&tag64);
386 
387 if(rc == FSDB_RC_SUCCESS)
388 	{
389 	*tim = (((uint64_t)tag64.H) << 32) | ((uint64_t)tag64.L);
390 	}
391 
392 return(rc == FSDB_RC_SUCCESS);
393 }
394 
395 
fsdbReaderGetMaxFsdbTag64(void * ctx,uint64_t * tim)396 extern "C" int fsdbReaderGetMaxFsdbTag64(void *ctx, uint64_t *tim)
397 {
398 ffrObject *fsdb_obj = (ffrObject *)ctx;
399 fsdbTag64 tag64;
400 fsdbRC rc = fsdb_obj->ffrGetMaxFsdbTag64(&tag64);
401 
402 if(rc == FSDB_RC_SUCCESS)
403 	{
404 	*tim = (((uint64_t)tag64.H) << 32) | ((uint64_t)tag64.L);
405 	}
406 
407 return(rc == FSDB_RC_SUCCESS);
408 }
409 
410 
__fsdbReaderGetStatisticsCB(fsdbTreeCBType cb_type,void * client_data,void * tree_cb_data)411 static bool_T __fsdbReaderGetStatisticsCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data)
412 {
413 struct fsdbReaderGetStatistics_t *gs = (struct fsdbReaderGetStatistics_t *)client_data;
414 
415 switch (cb_type)
416 	{
417 	case FSDB_TREE_CBT_VAR:		gs->varCount++;
418 					break;
419 
420 	case FSDB_TREE_CBT_STRUCT_BEGIN:
421 	case FSDB_TREE_CBT_SCOPE:	gs->scopeCount++;
422 					break;
423 
424 	default:			break;
425 	}
426 
427 return(TRUE);
428 }
429 
430 
fsdbReaderGetStatistics(void * ctx)431 extern "C" struct fsdbReaderGetStatistics_t *fsdbReaderGetStatistics(void *ctx)
432 {
433 ffrObject *fsdb_obj = (ffrObject *)ctx;
434 struct fsdbReaderGetStatistics_t *gs = (struct fsdbReaderGetStatistics_t *)calloc(1, sizeof(struct fsdbReaderGetStatistics_t));
435 
436 fsdb_obj->ffrSetTreeCBFunc(__fsdbReaderGetStatisticsCB, gs);
437 fsdb_obj->ffrReadScopeVarTree();
438 
439 return(gs);
440 }
441 
442 
443 static void
__DumpScope(fsdbTreeCBDataScope * scope,void (* cb)(void *))444 __DumpScope(fsdbTreeCBDataScope* scope, void (*cb)(void *))
445 {
446 str_T type;
447 char bf[65537];
448 
449 switch (scope->type)
450 	{
451     	case FSDB_ST_VCD_MODULE:
452 		type = (str_T) "vcd_module";
453 		break;
454 
455 	case FSDB_ST_VCD_TASK:
456 		type = (str_T) "vcd_task";
457 		break;
458 
459 	case FSDB_ST_VCD_FUNCTION:
460 		type = (str_T) "vcd_function";
461 		break;
462 
463 	case FSDB_ST_VCD_BEGIN:
464 		type = (str_T) "vcd_begin";
465 		break;
466 
467 	case FSDB_ST_VCD_FORK:
468 		type = (str_T) "vcd_fork";
469 		break;
470 
471 	case FSDB_ST_VCD_GENERATE:
472 		type = (str_T) "vcd_generate";
473 		break;
474 
475 	case FSDB_ST_SV_INTERFACE:
476 		type = (str_T) "sv_interface";
477 		break;
478 
479 	case FSDB_ST_VHDL_ARCHITECTURE:
480 		type = (str_T) "vhdl_architecture";
481 		break;
482 
483 	case FSDB_ST_VHDL_PROCEDURE:
484 		type = (str_T) "vhdl_procedure";
485 		break;
486 
487 	case FSDB_ST_VHDL_FUNCTION:
488 		type = (str_T) "vhdl_function";
489 		break;
490 
491 	case FSDB_ST_VHDL_RECORD:
492 		type = (str_T) "vhdl_record";
493 		break;
494 
495 	case FSDB_ST_VHDL_PROCESS:
496 		type = (str_T) "vhdl_process";
497 		break;
498 
499 	case FSDB_ST_VHDL_BLOCK:
500 		type = (str_T) "vhdl_block";
501 		break;
502 
503 	case FSDB_ST_VHDL_FOR_GENERATE:
504 		type = (str_T) "vhdl_for_generate";
505 		break;
506 
507 	case FSDB_ST_VHDL_IF_GENERATE:
508 		type = (str_T) "vhdl_if_generate";
509 		break;
510 
511 	case FSDB_ST_VHDL_GENERATE:
512 		type = (str_T) "vhdl_generate";
513 		break;
514 
515 	default:
516 		type = (str_T) "unknown_scope_type";
517 		break;
518     	}
519 
520 sprintf(bf, "Scope: %s %s %s", type, scope->name, scope->module ? scope->module : "NULL");
521 cb(bf);
522 }
523 
524 
itoa_2(int value,char * result)525 static char* itoa_2(int value, char* result)
526 {
527 char* ptr = result, *ptr1 = result, tmp_char;
528 int tmp_value;
529 
530 do {
531         tmp_value = value;
532         value /= 10;
533         *ptr++ = "9876543210123456789" [9 + (tmp_value - value * 10)];
534 } while ( value );
535 
536 if (tmp_value < 0) *ptr++ = '-';
537 result = ptr;
538 *ptr-- = '\0';
539 while(ptr1 < ptr) {
540         tmp_char = *ptr;
541         *ptr--= *ptr1;
542         *ptr1++ = tmp_char;
543 }
544 return(result);
545 }
546 
547 
548 static void
__DumpVar(fsdbTreeCBDataVar * var,void (* cb)(void *))549 __DumpVar(fsdbTreeCBDataVar *var, void (*cb)(void *))
550 {
551 str_T type;
552 str_T bpb;
553 str_T direction;
554 char *pnt;
555 int len;
556 int typelen;
557 int dirlen;
558 char bf[65537];
559 
560 switch(var->bytes_per_bit)
561 	{
562    	case FSDB_BYTES_PER_BIT_1B:
563 		bpb = (str_T) "1B";
564 		break;
565 
566     	case FSDB_BYTES_PER_BIT_2B:
567 		bpb = (str_T) "2B";
568 		break;
569 
570     	case FSDB_BYTES_PER_BIT_4B:
571 		bpb = (str_T) "4B";
572 		break;
573 
574     	case FSDB_BYTES_PER_BIT_8B:
575 		bpb = (str_T) "8B";
576 		break;
577 
578     	default:
579 		bpb = (str_T) "XB";
580 		break;
581 	}
582 
583 switch (var->type)
584 	{
585     	case FSDB_VT_VCD_EVENT:
586 		type = (str_T) "vcd_event";
587 		typelen = 9;
588   		break;
589 
590     	case FSDB_VT_VCD_INTEGER:
591 		type = (str_T) "vcd_integer";
592 		typelen = 11;
593 		break;
594 
595     	case FSDB_VT_VCD_PARAMETER:
596 		type = (str_T) "vcd_parameter";
597 		typelen = 13;
598 		break;
599 
600     	case FSDB_VT_VCD_REAL:
601 		type = (str_T) "vcd_real";
602 		typelen = 8;
603 		break;
604 
605     	case FSDB_VT_VCD_REG:
606 		type = (str_T) "vcd_reg";
607 		typelen = 7;
608 		break;
609 
610     	case FSDB_VT_VCD_SUPPLY0:
611 		type = (str_T) "vcd_supply0";
612 		typelen = 11;
613 		break;
614 
615     	case FSDB_VT_VCD_SUPPLY1:
616 		type = (str_T) "vcd_supply1";
617 		typelen = 11;
618 		break;
619 
620     	case FSDB_VT_VCD_TIME:
621 		type = (str_T) "vcd_time";
622 		typelen = 8;
623 		break;
624 
625     	case FSDB_VT_VCD_TRI:
626 		type = (str_T) "vcd_tri";
627 		typelen = 7;
628 		break;
629 
630     	case FSDB_VT_VCD_TRIAND:
631 		type = (str_T) "vcd_triand";
632 		typelen = 10;
633 		break;
634 
635     	case FSDB_VT_VCD_TRIOR:
636 		type = (str_T) "vcd_trior";
637 		typelen = 9;
638 		break;
639 
640     	case FSDB_VT_VCD_TRIREG:
641 		type = (str_T) "vcd_trireg";
642 		typelen = 10;
643 		break;
644 
645     	case FSDB_VT_VCD_TRI0:
646 		type = (str_T) "vcd_tri0";
647 		typelen = 8;
648 		break;
649 
650     	case FSDB_VT_VCD_TRI1:
651 		type = (str_T) "vcd_tri1";
652 		typelen = 8;
653 		break;
654 
655     	case FSDB_VT_VCD_WAND:
656 		type = (str_T) "vcd_wand";
657 		typelen = 8;
658 		break;
659 
660     	case FSDB_VT_VCD_WIRE:
661 		type = (str_T) "vcd_wire";
662 		typelen = 8;
663 		break;
664 
665     	case FSDB_VT_VCD_WOR:
666 		type = (str_T) "vcd_wor";
667 		typelen = 7;
668 		break;
669 
670     	case FSDB_VT_VCD_PORT:
671 		type = (str_T) "vcd_port";
672 		typelen = 8;
673 		break;
674 
675     	case FSDB_VT_VHDL_SIGNAL:
676     	case FSDB_VT_VHDL_VARIABLE:
677     	case FSDB_VT_VHDL_CONSTANT:
678     	case FSDB_VT_VHDL_FILE:
679     	case FSDB_VT_VCD_MEMORY:
680     	case FSDB_VT_VHDL_MEMORY:
681     	case FSDB_VT_VCD_MEMORY_DEPTH:
682     	case FSDB_VT_VHDL_MEMORY_DEPTH:
683 		switch(var->vc_dt)
684 			{
685 			case FSDB_VC_DT_FLOAT:
686 			case FSDB_VC_DT_DOUBLE:
687 				type = (str_T) "vcd_real";
688 				typelen = 8;
689 				break;
690 
691 			case FSDB_VC_DT_UNKNOWN:
692 			case FSDB_VC_DT_BYTE:
693 			case FSDB_VC_DT_SHORT:
694 			case FSDB_VC_DT_INT:
695 			case FSDB_VC_DT_LONG:
696 			case FSDB_VC_DT_HL_INT:
697 			case FSDB_VC_DT_PHYSICAL:
698 			default:
699 				if(var->type == FSDB_VT_VHDL_SIGNAL)
700 					{
701 					type = (str_T) "vcd_wire";
702 					typelen = 8;
703 					}
704 				else
705 					{
706 					type = (str_T) "vcd_reg";
707 					typelen = 7;
708 					}
709 				break;
710 			}
711 		break;
712 
713 	case FSDB_VT_STREAM: /* these hold transactions: not yet supported */
714 		type = (str_T) "stream";
715 		typelen = 6;
716 		break;
717 
718     	default:
719 		type = (str_T) "vcd_wire";
720 		typelen = 8;
721 		break;
722     	}
723 
724     switch(var->direction)
725 	{
726 	case FSDB_VD_INPUT:    	direction = (str_T) "input"; 	dirlen = 5; break;
727 	case FSDB_VD_OUTPUT:   	direction = (str_T) "output"; 	dirlen = 6; break;
728 	case FSDB_VD_INOUT:    	direction = (str_T) "inout"; 	dirlen = 5; break;
729 	case FSDB_VD_BUFFER:   	direction = (str_T) "buffer"; 	dirlen = 6; break;
730 	case FSDB_VD_LINKAGE:  	direction = (str_T) "linkage"; 	dirlen = 7; break;
731 	case FSDB_VD_IMPLICIT:
732 	default:	       	direction = (str_T) "implicit"; dirlen = 8; break;
733 	}
734 
735 /*
736 sprintf(bf, "Var: %s %s l:%d r:%d %s %d %s %d", type, var->name, var->lbitnum, var->rbitnum,
737 	direction,
738 	var->u.idcode, bpb, var->dtidcode);
739 */
740 
741 memcpy(bf, "Var: ", 5);
742 pnt = bf+5;
743 len = typelen; /* strlen(type) */
744 memcpy(pnt, type, len);
745 pnt += len;
746 *(pnt++) = ' ';
747 len = strlen(var->name);
748 memcpy(pnt, var->name, len);
749 pnt += len;
750 memcpy(pnt, " l:", 3);
751 pnt += 3;
752 pnt = itoa_2(var->lbitnum, pnt);
753 memcpy(pnt, " r:", 3);
754 pnt += 3;
755 pnt = itoa_2(var->rbitnum, pnt);
756 *(pnt++) = ' ';
757 len = dirlen; /* strlen(direction) */
758 memcpy(pnt, direction, len);
759 pnt += len;
760 *(pnt++) = ' ';
761 pnt = itoa_2(var->u.idcode, pnt);
762 *(pnt++) = ' ';
763 len = 2; /* strlen(bpb) */
764 memcpy(pnt, bpb, len);
765 pnt += len;
766 *(pnt++) = ' ';
767 pnt = itoa_2(var->dtidcode, pnt);
768 *(pnt) = 0;
769 
770 cb(bf);
771 }
772 
773 
774 static void
__DumpStruct(fsdbTreeCBDataStructBegin * str,void (* cb)(void *))775 __DumpStruct(fsdbTreeCBDataStructBegin* str, void (*cb)(void *))
776 {
777 char bf[65537];
778 
779 /* printf("NAME: %s FIELDS: %d TYPE: %d is_partial_dumped: %d\n", str->name, (int)str->fieldCount, (int)str->type, (int)str->is_partial_dumped); */
780 
781 sprintf(bf, "Scope: vcd_struct %s %s", str->name, "NULL");
782 cb(bf);
783 }
784 
785 
786 static void
__DumpArray(fsdbTreeCBDataArrayBegin * arr,void (* cb)(void *))787 __DumpArray(fsdbTreeCBDataArrayBegin* arr, void (*cb)(void *))
788 {
789 /* printf("NAME: %s SIZE: %d is_partial_dumped: %d\n", arr->name, (int)arr->size, (int)arr->is_partial_dumped); */
790 }
791 
792 
793 
__MyTreeCB(fsdbTreeCBType cb_type,void * client_data,void * tree_cb_data)794 static bool_T __MyTreeCB(fsdbTreeCBType cb_type,
795 			 void *client_data, void *tree_cb_data)
796 {
797 void (*cb)(void *) = (void (*)(void *))client_data;
798 char bf[16];
799 
800 switch (cb_type)
801 	{
802     	case FSDB_TREE_CBT_BEGIN_TREE:
803 		/* fprintf(stderr, "Begin Tree:\n"); */
804 		break;
805 
806     	case FSDB_TREE_CBT_SCOPE:
807 		__DumpScope((fsdbTreeCBDataScope*)tree_cb_data, cb);
808 		break;
809 
810     	case FSDB_TREE_CBT_VAR:
811 		__DumpVar((fsdbTreeCBDataVar*)tree_cb_data, cb);
812 		break;
813 
814     	case FSDB_TREE_CBT_UPSCOPE:
815 		strcpy(bf, "Upscope:");
816 		cb(bf);
817 		break;
818 
819     	case FSDB_TREE_CBT_END_TREE:
820 		strcpy(bf, "End Tree:");
821 		cb(bf);
822 		break;
823 
824 	case FSDB_TREE_CBT_STRUCT_BEGIN:
825 		__DumpStruct((fsdbTreeCBDataStructBegin*)tree_cb_data, cb);
826 		break;
827 
828 	case FSDB_TREE_CBT_STRUCT_END:
829 		strcpy(bf, "Upscope:");
830 		cb(bf);
831 		break;
832 
833 	/* not yet supported */
834     	case FSDB_TREE_CBT_ARRAY_BEGIN:
835 		__DumpArray((fsdbTreeCBDataArrayBegin*)tree_cb_data, cb);
836 		break;
837     	case FSDB_TREE_CBT_ARRAY_END:
838 		break;
839 
840     	case FSDB_TREE_CBT_FILE_TYPE:
841     	case FSDB_TREE_CBT_SIMULATOR_VERSION:
842     	case FSDB_TREE_CBT_SIMULATION_DATE:
843     	case FSDB_TREE_CBT_X_AXIS_SCALE:
844     	case FSDB_TREE_CBT_END_ALL_TREE:
845     	case FSDB_TREE_CBT_RECORD_BEGIN:
846     	case FSDB_TREE_CBT_RECORD_END:
847         	break;
848 
849     	default:
850 		return(FALSE);
851     	}
852 
853 return(TRUE);
854 }
855 
856 
857 /*
858  * $dumpoff/$dumpon support
859  */
fsdbReaderGetDumpOffRange(void * ctx,struct fsdbReaderBlackoutChain_t ** r)860 extern "C" unsigned int fsdbReaderGetDumpOffRange(void *ctx, struct fsdbReaderBlackoutChain_t **r)
861 {
862 ffrObject *fsdb_obj = (ffrObject *)ctx;
863 
864 if(fsdb_obj->ffrHasDumpOffRange())
865         {
866         uint_T count;
867         fsdbDumpOffRange *fdr = NULL;
868 
869         if(FSDB_RC_SUCCESS == fsdb_obj->ffrGetDumpOffRange(count, fdr))
870                 {
871                 uint_T i;
872                 *r = (struct fsdbReaderBlackoutChain_t *)calloc(count * 2, sizeof(struct fsdbReaderBlackoutChain_t));
873 
874                 for(i=0;i<count;i++)
875                         {
876                         (*r)[i].tim = FSDBR_FXT2U64(fdr[i*2  ].begin); (*r)[i*2  ].active = 0;
877                         (*r)[i].tim = FSDBR_FXT2U64(fdr[i*2+1].begin); (*r)[i*2+1].active = 1;
878                         }
879 
880                 return(count*2);
881                 }
882         }
883 
884 if(*r) { *r = NULL; }
885 return(0);
886 }
887 
888 
889 /*
890  * Transactions are currently not processed and are skipped
891  */
fsdbReaderGetTransInfo(void * ctx,int idx,void ** trans_info)892 extern "C" int fsdbReaderGetTransInfo(void *ctx, int idx, void **trans_info)
893 {
894 ffrObject *fsdb_obj = (ffrObject *)ctx;
895 ffrTransInfo *info = NULL;
896 
897 fsdbRC rc = fsdb_obj->ffrGetTransInfo((fsdbTransId)idx, info);
898 *trans_info = info;
899 
900 return(rc != FSDB_RC_FAILURE);
901 }
902 
903 
904 /*
905  * Reformat FSDB hierarchy info into FST's format (for use with WAVE_USE_FSDB_FST_BRIDGE)
906  */
907 static void
__DumpScope2(fsdbTreeCBDataScope * scope,void (* cb)(void *))908 __DumpScope2(fsdbTreeCBDataScope* scope, void (*cb)(void *))
909 {
910 unsigned char typ;
911 struct fstHier fh;
912 
913 switch (scope->type)
914 	{
915     	case FSDB_ST_VCD_MODULE:
916 		typ = FST_ST_VCD_MODULE;
917 		break;
918 
919 	case FSDB_ST_VCD_TASK:
920 		typ = FST_ST_VCD_TASK;
921 		break;
922 
923 	case FSDB_ST_VCD_FUNCTION:
924 		typ = FST_ST_VCD_FUNCTION;
925 		break;
926 
927 	case FSDB_ST_VCD_BEGIN:
928 		typ = FST_ST_VCD_BEGIN;
929 		break;
930 
931 	case FSDB_ST_VCD_FORK:
932 		typ = FST_ST_VCD_FORK;
933 		break;
934 
935 	case FSDB_ST_VCD_GENERATE:
936 		typ = FST_ST_VCD_GENERATE;
937 		break;
938 
939 	case FSDB_ST_SV_INTERFACE:
940 		typ = FST_ST_VCD_INTERFACE;
941 		break;
942 
943 	case FSDB_ST_VHDL_ARCHITECTURE:
944 		typ = FST_ST_VHDL_ARCHITECTURE;
945 		break;
946 
947 	case FSDB_ST_VHDL_PROCEDURE:
948 		typ = FST_ST_VHDL_PROCEDURE;
949 		break;
950 
951 	case FSDB_ST_VHDL_FUNCTION:
952 		typ = FST_ST_VHDL_FUNCTION;
953 		break;
954 
955 	case FSDB_ST_VHDL_RECORD:
956 		typ = FST_ST_VHDL_RECORD;
957 		break;
958 
959 	case FSDB_ST_VHDL_PROCESS:
960 		typ = FST_ST_VHDL_PROCESS;
961 		break;
962 
963 	case FSDB_ST_VHDL_BLOCK:
964 		typ = FST_ST_VHDL_BLOCK;
965 		break;
966 
967 	case FSDB_ST_VHDL_FOR_GENERATE:
968 		typ = FST_ST_VHDL_FOR_GENERATE;
969 		break;
970 
971 	case FSDB_ST_VHDL_IF_GENERATE:
972 		typ = FST_ST_VHDL_IF_GENERATE;
973 		break;
974 
975 	case FSDB_ST_VHDL_GENERATE:
976 		typ = FST_ST_VHDL_GENERATE;
977 		break;
978 
979 	default:
980 		typ = FST_ST_VCD_MODULE;
981 		break;
982     	}
983 
984 fh.htyp = FST_HT_SCOPE;
985 fh.u.scope.typ = typ;
986 fh.u.scope.name = scope->name;
987 fh.u.scope.name_length = strlen(fh.u.scope.name);
988 if(scope->module)
989 	{
990 	fh.u.scope.component = scope->module;
991 	fh.u.scope.component_length = strlen(fh.u.scope.component);
992 	}
993 	else
994 	{
995 	fh.u.scope.component = NULL;
996 	fh.u.scope.component_length = 0;
997 	}
998 
999 cb(&fh);
1000 }
1001 
1002 
1003 static void
__DumpVar2(fsdbTreeCBDataVar * var,void (* cb)(void *))1004 __DumpVar2(fsdbTreeCBDataVar *var, void (*cb)(void *))
1005 {
1006 unsigned char typ;
1007 unsigned char dir;
1008 struct fstHier fh;
1009 
1010 switch (var->type)
1011 	{
1012     	case FSDB_VT_VCD_EVENT:
1013 		typ = FST_VT_VCD_EVENT;
1014   		break;
1015 
1016     	case FSDB_VT_VCD_INTEGER:
1017 		typ = FST_VT_VCD_INTEGER;
1018 		break;
1019 
1020     	case FSDB_VT_VCD_PARAMETER:
1021 		typ = FST_VT_VCD_PARAMETER;
1022 		break;
1023 
1024     	case FSDB_VT_VCD_REAL:
1025 		typ = FST_VT_VCD_REAL;
1026 		break;
1027 
1028     	case FSDB_VT_VCD_REG:
1029 		typ = FST_VT_VCD_REG;
1030 		break;
1031 
1032     	case FSDB_VT_VCD_SUPPLY0:
1033 		typ = FST_VT_VCD_SUPPLY0;
1034 		break;
1035 
1036     	case FSDB_VT_VCD_SUPPLY1:
1037 		typ = FST_VT_VCD_SUPPLY1;
1038 		break;
1039 
1040     	case FSDB_VT_VCD_TIME:
1041 		typ = FST_VT_VCD_TIME;
1042 		break;
1043 
1044     	case FSDB_VT_VCD_TRI:
1045 		typ = FST_VT_VCD_TRI;
1046 		break;
1047 
1048     	case FSDB_VT_VCD_TRIAND:
1049 		typ = FST_VT_VCD_TRIAND;
1050 		break;
1051 
1052     	case FSDB_VT_VCD_TRIOR:
1053 		typ = FST_VT_VCD_TRIOR;
1054 		break;
1055 
1056     	case FSDB_VT_VCD_TRIREG:
1057 		typ = FST_VT_VCD_TRIREG;
1058 		break;
1059 
1060     	case FSDB_VT_VCD_TRI0:
1061 		typ = FST_VT_VCD_TRI0;
1062 		break;
1063 
1064     	case FSDB_VT_VCD_TRI1:
1065 		typ = FST_VT_VCD_TRI1;
1066 		break;
1067 
1068     	case FSDB_VT_VCD_WAND:
1069 		typ = FST_VT_VCD_WAND;
1070 		break;
1071 
1072     	case FSDB_VT_VCD_WIRE:
1073 		typ = FST_VT_VCD_WIRE;
1074 		break;
1075 
1076     	case FSDB_VT_VCD_WOR:
1077 		typ = FST_VT_VCD_WOR;
1078 		break;
1079 
1080     	case FSDB_VT_VCD_PORT:
1081 		typ = FST_VT_VCD_PORT;
1082 		break;
1083 
1084     	case FSDB_VT_VHDL_SIGNAL:
1085     	case FSDB_VT_VHDL_VARIABLE:
1086     	case FSDB_VT_VHDL_CONSTANT:
1087     	case FSDB_VT_VHDL_FILE:
1088     	case FSDB_VT_VCD_MEMORY:
1089     	case FSDB_VT_VHDL_MEMORY:
1090     	case FSDB_VT_VCD_MEMORY_DEPTH:
1091     	case FSDB_VT_VHDL_MEMORY_DEPTH:
1092 		switch(var->vc_dt)
1093 			{
1094 			case FSDB_VC_DT_FLOAT:
1095 			case FSDB_VC_DT_DOUBLE:
1096 				typ = FST_VT_VCD_REAL;
1097 				break;
1098 
1099 			case FSDB_VC_DT_UNKNOWN:
1100 			case FSDB_VC_DT_BYTE:
1101 			case FSDB_VC_DT_SHORT:
1102 			case FSDB_VC_DT_INT:
1103 			case FSDB_VC_DT_LONG:
1104 			case FSDB_VC_DT_HL_INT:
1105 			case FSDB_VC_DT_PHYSICAL:
1106 			default:
1107 				if(var->type == FSDB_VT_VHDL_SIGNAL)
1108 					{
1109 					typ = FST_VT_VCD_WIRE;
1110 					}
1111 				else
1112 					{
1113 					typ = FST_VT_VCD_REG;
1114 					}
1115 				break;
1116 			}
1117 		break;
1118 
1119 	case FSDB_VT_STREAM: /* these hold transactions: not yet supported */
1120 		typ = FST_VT_GEN_STRING;
1121 		break;
1122 
1123     	default:
1124 		typ = FST_VT_VCD_WIRE;
1125 		break;
1126     	}
1127 
1128     switch(var->direction)
1129 	{
1130 	case FSDB_VD_INPUT:    	dir = FST_VD_INPUT; break;
1131 	case FSDB_VD_OUTPUT:   	dir = FST_VD_OUTPUT; break;
1132 	case FSDB_VD_INOUT:    	dir = FST_VD_INOUT; break;
1133 	case FSDB_VD_BUFFER:   	dir = FST_VD_BUFFER; break;
1134 	case FSDB_VD_LINKAGE:  	dir = FST_VD_LINKAGE; break;
1135 	case FSDB_VD_IMPLICIT:
1136 	default:	       	dir = FST_VD_IMPLICIT; break;
1137 	}
1138 
1139 
1140 fh.htyp = FST_HT_VAR;
1141 fh.u.var.typ = typ;
1142 fh.u.var.direction = dir;
1143 fh.u.var.svt_workspace = 0;
1144 fh.u.var.sdt_workspace = 0;
1145 fh.u.var.sxt_workspace = 0;
1146 fh.u.var.name = var->name;
1147 fh.u.var.length = (var->lbitnum > var->rbitnum) ? (var->lbitnum - var->rbitnum + 1) : (var->rbitnum - var->lbitnum + 1);
1148 fh.u.var.handle = var->u.idcode;
1149 fh.u.var.name_length = strlen(fh.u.var.name);
1150 fh.u.var.is_alias = 0; // for now
1151 
1152 cb(&fh);
1153 }
1154 
1155 
1156 static void
__DumpStruct2(fsdbTreeCBDataStructBegin * str,void (* cb)(void *))1157 __DumpStruct2(fsdbTreeCBDataStructBegin* str, void (*cb)(void *))
1158 {
1159 struct fstHier fh;
1160 
1161 fh.htyp = FST_HT_SCOPE;
1162 fh.u.scope.typ = FST_ST_VCD_STRUCT;
1163 fh.u.scope.name = str->name;
1164 fh.u.scope.name_length = strlen(fh.u.scope.name);
1165 fh.u.scope.component = NULL;
1166 fh.u.scope.component_length = 0;
1167 
1168 cb(&fh);
1169 }
1170 
1171 
1172 static void
__DumpArray2(fsdbTreeCBDataArrayBegin * arr,void (* cb)(void *))1173 __DumpArray2(fsdbTreeCBDataArrayBegin* arr, void (*cb)(void *))
1174 {
1175 /* printf("NAME: %s SIZE: %d is_partial_dumped: %d\n", arr->name, (int)arr->size, (int)arr->is_partial_dumped); */
1176 }
1177 
1178 
1179 
__MyTreeCB2(fsdbTreeCBType cb_type,void * client_data,void * tree_cb_data)1180 static bool_T __MyTreeCB2(fsdbTreeCBType cb_type,
1181 			 void *client_data, void *tree_cb_data)
1182 {
1183 void (*cb)(void *) = (void (*)(void *))client_data;
1184 struct fstHier fh;
1185 
1186 
1187 
1188 char bf[16];
1189 
1190 switch (cb_type)
1191 	{
1192     	case FSDB_TREE_CBT_BEGIN_TREE:
1193 		/* fprintf(stderr, "Begin Tree:\n"); */
1194 		break;
1195 
1196     	case FSDB_TREE_CBT_SCOPE:
1197 		__DumpScope2((fsdbTreeCBDataScope*)tree_cb_data, cb);
1198 		break;
1199 
1200     	case FSDB_TREE_CBT_VAR:
1201 		__DumpVar2((fsdbTreeCBDataVar*)tree_cb_data, cb);
1202 		break;
1203 
1204     	case FSDB_TREE_CBT_UPSCOPE:
1205 	case FSDB_TREE_CBT_STRUCT_END:
1206 		fh.htyp = FST_HT_UPSCOPE;
1207 		cb(&fh);
1208 		break;
1209 
1210     	case FSDB_TREE_CBT_END_TREE:
1211 		fh.htyp = FST_HT_TREEEND;
1212 		cb(&fh);
1213 		break;
1214 
1215 	case FSDB_TREE_CBT_STRUCT_BEGIN:
1216 		__DumpStruct2((fsdbTreeCBDataStructBegin*)tree_cb_data, cb);
1217 		break;
1218 
1219 	/* not yet supported */
1220     	case FSDB_TREE_CBT_ARRAY_BEGIN:
1221 		__DumpArray2((fsdbTreeCBDataArrayBegin*)tree_cb_data, cb);
1222 		break;
1223     	case FSDB_TREE_CBT_ARRAY_END:
1224 		break;
1225 
1226     	case FSDB_TREE_CBT_FILE_TYPE:
1227     	case FSDB_TREE_CBT_SIMULATOR_VERSION:
1228     	case FSDB_TREE_CBT_SIMULATION_DATE:
1229     	case FSDB_TREE_CBT_X_AXIS_SCALE:
1230     	case FSDB_TREE_CBT_END_ALL_TREE:
1231     	case FSDB_TREE_CBT_RECORD_BEGIN:
1232     	case FSDB_TREE_CBT_RECORD_END:
1233         	break;
1234 
1235     	default:
1236 		return(FALSE);
1237     	}
1238 
1239 return(TRUE);
1240 }
1241 
fsdbReaderReadScopeVarTree2(void * ctx,void (* cb)(void *))1242 extern "C" void fsdbReaderReadScopeVarTree2(void *ctx,void (*cb)(void *))
1243 {
1244 ffrObject *fsdb_obj = (ffrObject *)ctx;
1245 
1246 fsdb_obj->ffrSetTreeCBFunc(__MyTreeCB2, (void *) cb);
1247 fsdb_obj->ffrReadScopeVarTree();
1248 }
1249 
1250 #else
1251 
dummy_compilation_unit(void)1252 static void dummy_compilation_unit(void)
1253 {
1254 
1255 }
1256 
1257 #endif
1258