diff --git a/vpi/fstapi.c b/vpi/fstapi.c index 3ffb32140..a2d00454b 100644 --- a/vpi/fstapi.c +++ b/vpi/fstapi.c @@ -33,24 +33,41 @@ #include #endif -/* this define is to force writer backward compatibility with old readers */ -#ifndef FST_DYNAMIC_ALIAS_DISABLE +#if HAVE_ALLOCA_H +#include +#elif defined(__GNUC__) +#ifndef __MINGW32__ +#ifndef alloca +#define alloca __builtin_alloca +#endif +#else +#include +#endif +#elif defined(_MSC_VER) +#include +#define alloca _alloca +#endif + +#ifndef PATH_MAX +#define PATH_MAX (4096) +#endif + /* note that Judy versus Jenkins requires more experimentation: they are */ /* functionally equivalent though it appears Jenkins is slightly faster. */ /* in addition, Jenkins is not bound by the LGPL. */ #ifdef _WAVE_HAVE_JUDY #include #else +/* should be more than enough for fstWriterSetSourceStem() */ +#define FST_PATH_HASHMASK ((1UL << 16) - 1) typedef const void *Pcvoid_t; typedef void *Pvoid_t; typedef void **PPvoid_t; #define JudyHSIns(a,b,c,d) JenkinsIns((a),(b),(c),(hashmask)) #define JudyHSFreeArray(a,b) JenkinsFree((a),(hashmask)) void JenkinsFree(void *base_i, uint32_t hashmask); -void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t hashmask); +void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask); #endif -#endif - #undef FST_DEBUG @@ -65,7 +82,9 @@ void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t ha #define FST_ID_NAM_ATTR_SIZ (65536+4096) #define FST_DOUBLE_ENDTEST (2.7182818284590452354) #define FST_HDR_SIM_VERSION_SIZE (128) -#define FST_HDR_DATE_SIZE (120) +#define FST_HDR_DATE_SIZE (119) +#define FST_HDR_FILETYPE_SIZE (1) +#define FST_HDR_TIMEZERO_SIZE (8) #define FST_GZIO_LEN (32768) #if defined(__i386__) || defined(__x86_64__) || defined(_AIX) @@ -135,6 +154,36 @@ return(ftruncate(fd, length)); } +/* + * realpath compatibility + */ +static char *fstRealpath(const char *path, char *resolved_path) +{ +#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH + +#if (defined(__MACH__) && defined(__APPLE__)) +if(!resolved_path) + { + resolved_path = malloc(PATH_MAX+1); /* fixes bug on Leopard when resolved_path == NULL */ + } +#endif + +return(realpath(path, resolved_path)); + +#else +#ifdef __MINGW32__ +if(!resolved_path) + { + resolved_path = malloc(PATH_MAX+1); + } +return(_fullpath(resolved_path, path, PATH_MAX)); +#else +return(NULL); +#endif +#endif +} + + /* * mmap compatibility */ @@ -304,6 +353,21 @@ do { return(pnt); } + + +static unsigned char *fstCopyVarint64ToRight(unsigned char *pnt, uint64_t v) +{ +uint64_t nxt; + +while((nxt = v>>7)) + { + *(pnt++) = (v&0x7f) | 0x80; + v = nxt; + } +*(pnt++) = (v&0x7f); + +return(pnt); +} static uint64_t fstGetVarint64(unsigned char *mem, int *skiplen) @@ -490,7 +554,6 @@ uint64_t firsttime; uint32_t vchg_siz; uint32_t vchg_alloc_siz; - uint32_t secnum; off_t section_start; @@ -503,6 +566,8 @@ uint32_t num_blackouts; uint64_t dump_size_limit; +unsigned char filetype; /* default is 0, FST_FT_VERILOG */ + unsigned compress_hier : 1; unsigned repack_on_close : 1; unsigned skip_writing_section_hdr : 1; @@ -533,6 +598,9 @@ size_t fst_huge_break_size; fstHandle next_huge_break; +Pvoid_t path_array; +uint32_t path_array_count; + unsigned fseek_failed : 1; }; @@ -672,12 +740,15 @@ time(&walltime); strcpy(dbuf, asctime(localtime(&walltime))); fstFwrite(dbuf, FST_HDR_DATE_SIZE, 1, xc->handle); /* +202 date */ -/* date size is deliberately overspecified at 120 bytes in order to provide backfill for new args */ +/* date size is deliberately overspecified at 119 bytes (originally 128) in order to provide backfill for new args */ -#define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE) +#define FST_HDR_OFFS_FILETYPE (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE) +fputc(xc->filetype, xc->handle); /* +321 filetype */ + +#define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_FILETYPE + FST_HDR_FILETYPE_SIZE) fstWriterUint64(xc->handle, xc->timezero); /* +322 timezero */ -#define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + 8) +#define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + FST_HDR_TIMEZERO_SIZE) /* +330 next section starts here */ fflush(xc->handle); } @@ -1796,6 +1867,14 @@ if(xc && !xc->already_in_close && !xc->already_in_flush) pthread_attr_destroy(&xc->thread_attr); #endif + if(xc->path_array) + { +#ifndef _WAVE_HAVE_JUDY + const uint32_t hashmask = FST_PATH_HASHMASK; +#endif + JudyHSFreeArray(&(xc->path_array), NULL); + } + free(xc->filename); xc->filename = NULL; free(xc); } @@ -1843,7 +1922,44 @@ if(xc && vers) } -static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ) +void fstWriterSetFileType(void *ctx, enum fstFileType filetype) +{ +struct fstWriterContext *xc = (struct fstWriterContext *)ctx; +if(xc) + { + if((filetype >= FST_FT_MIN) && (filetype <= FST_FT_MAX)) + { + off_t fpos = ftello(xc->handle); + + xc->filetype = filetype; + + fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_FILETYPE, SEEK_SET); + fputc(xc->filetype, xc->handle); + fflush(xc->handle); + fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); + } + } +} + + +static void fstWriterSetAttrDoubleArgGeneric(void *ctx, int typ, uint64_t arg1, uint64_t arg2) +{ +struct fstWriterContext *xc = (struct fstWriterContext *)ctx; +if(xc) + { + unsigned char buf[11]; /* ceil(64/7) = 10 + null term */ + unsigned char *pnt = fstCopyVarint64ToRight(buf, arg1); + if(arg1) + { + *pnt = 0; /* this converts any *nonzero* arg1 when made a varint into a null-term string */ + } + + fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, (char *)buf, arg2); + } +} + + +static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ, uint64_t arg) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && comm) @@ -1857,21 +1973,87 @@ if(xc && comm) s++; } - fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, 0); + fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, arg); free(sf); } } +static void fstWriterSetSourceStem_2(void *ctx, const char *path, unsigned int line, unsigned int use_realpath, int typ) +{ +struct fstWriterContext *xc = (struct fstWriterContext *)ctx; + +if(xc && path && path[0]) + { + uint64_t sidx = 0; + int slen = strlen(path); +#ifndef _WAVE_HAVE_JUDY + const uint32_t hashmask = FST_PATH_HASHMASK; + const unsigned char *path2 = (const unsigned char *)path; +#else + char *path2 = alloca(slen + 1); /* judy lacks const qualifier in its JudyHSIns definition */ + strcpy(path2, path); +#endif + + PPvoid_t pv = JudyHSIns(&(xc->path_array), path2, slen, NULL); + if(*pv) + { + sidx = (long)(*pv); + } + else + { + char *rp = NULL; + + sidx = ++xc->path_array_count; + *pv = (void *)(long)(xc->path_array_count); + + if(use_realpath) + { + rp = fstRealpath( +#ifndef _WAVE_HAVE_JUDY + (const char *) +#endif + path2, NULL); + } + + fstWriterSetAttrGeneric(xc, rp ? rp : +#ifndef _WAVE_HAVE_JUDY + (const char *) +#endif + path2, FST_MT_PATHNAME, sidx); + + if(rp) + { + free(rp); + } + } + + fstWriterSetAttrDoubleArgGeneric(xc, typ, sidx, line); + } +} + + +void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath) +{ +fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCESTEM); +} + + +void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath) +{ +fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCEISTEM); +} + + void fstWriterSetComment(void *ctx, const char *comm) { -fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT); +fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT, 0); } void fstWriterSetEnvVar(void *ctx, const char *envvar) { -fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR); +fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR, 0); } @@ -1903,14 +2085,14 @@ if(xc && s) { switch(*pnt) { - case 'm': seconds_exp = -3; mat = 1; break; - case 'u': seconds_exp = -6; mat = 1; break; - case 'n': seconds_exp = -9; mat = 1; break; + case 'm': seconds_exp = -3; mat = 1; break; + case 'u': seconds_exp = -6; mat = 1; break; + case 'n': seconds_exp = -9; mat = 1; break; case 'p': seconds_exp = -12; mat = 1; break; case 'f': seconds_exp = -15; mat = 1; break; case 'a': seconds_exp = -18; mat = 1; break; case 'z': seconds_exp = -21; mat = 1; break; - case 's': seconds_exp = -0; mat = 1; break; + case 's': seconds_exp = 0; mat = 1; break; default: break; } @@ -2020,8 +2202,19 @@ return(0); /* - * writer attr/scope/var creation + * writer attr/scope/var creation: + * fstWriterCreateVar2() is used to dump VHDL or other languages, but the + * underlying variable needs to map to Verilog/SV via the proper fstVarType vt */ +fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd, + uint32_t len, const char *nam, fstHandle aliasHandle, + const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt) +{ +fstWriterSetAttrGeneric(ctx, type ? type : "", FST_MT_SUPVAR, (svt<date : NULL); } + +int fstReaderGetFileType(void *ctx) +{ +struct fstReaderContext *xc = (struct fstReaderContext *)ctx; +return(xc ? xc->filetype : FST_FT_VERILOG); +} + + int64_t fstReaderGetTimezero(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; @@ -3196,6 +3400,15 @@ if(!(isfeof=feof(xc->fh))) xc->hier.u.attr.name_length = pnt - xc->hier.u.scope.name; xc->hier.u.attr.arg = fstReaderVarint64(xc->fh); + + if(xc->hier.u.attr.typ == FST_AT_MISC) + { + if((xc->hier.u.attr.subtype == FST_MT_SOURCESTEM)||(xc->hier.u.attr.subtype == FST_MT_SOURCEISTEM)) + { + int sidx_skiplen_dummy = 0; + xc->hier.u.attr.arg_from_name = fstGetVarint64((unsigned char *)xc->str_scope_nam, &sidx_skiplen_dummy); + } + } break; case FST_ST_GEN_ATTREND: @@ -3233,7 +3446,9 @@ if(!(isfeof=feof(xc->fh))) case FST_VT_SV_ENUM: case FST_VT_SV_SHORTREAL: xc->hier.htyp = FST_HT_VAR; - + xc->hier.u.var.svt_workspace = FST_SVT_NONE; + xc->hier.u.var.sdt_workspace = FST_SDT_NONE; + xc->hier.u.var.sxt_workspace = 0; xc->hier.u.var.typ = tag; xc->hier.u.var.direction = fgetc(xc->fh); xc->hier.u.var.name = pnt = xc->str_scope_nam; @@ -3368,7 +3583,7 @@ while(!feof(xc->fh)) { case FST_ST_VCD_SCOPE: scopetype = fgetc(xc->fh); - if((scopetype < FST_ST_VCD_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE; + if((scopetype < FST_ST_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE; pnt = str; while((ch = fgetc(xc->fh))) { @@ -3394,6 +3609,8 @@ while(!feof(xc->fh)) }; /* attrname */ *pnt = 0; + if(!str[0]) { strcpy(str, "\"\""); } + attrarg = fstReaderVarint64(xc->fh); if(fv) @@ -3417,7 +3634,17 @@ while(!feof(xc->fh)) } else { - fprintf(fv, "$attrbegin %s %02x %s %"PRId64" $end\n", attrtypes[attrtype], subtype, str, attrarg); + if((subtype == FST_MT_SOURCESTEM)||(subtype == FST_MT_SOURCEISTEM)) + { + int sidx_skiplen_dummy = 0; + uint64_t sidx = fstGetVarint64((unsigned char *)str, &sidx_skiplen_dummy); + + fprintf(fv, "$attrbegin %s %02x %"PRId64" %"PRId64" $end\n", attrtypes[attrtype], subtype, sidx, attrarg); + } + else + { + fprintf(fv, "$attrbegin %s %02x %s %"PRId64" $end\n", attrtypes[attrtype], subtype, str, attrarg); + } } break; } @@ -3705,6 +3932,8 @@ if(gzread_pass_status) xc->version[FST_HDR_SIM_VERSION_SIZE] = 0; fstFread(xc->date, FST_HDR_DATE_SIZE, 1, xc->f); xc->date[FST_HDR_DATE_SIZE] = 0; + ch = fgetc(xc->f); + xc->filetype = (unsigned char)ch; xc->timezero = fstReaderUint64(xc->f); } } @@ -4004,6 +4233,8 @@ scatterptr = calloc(xc->maxhandle, sizeof(uint32_t)); headptr = calloc(xc->maxhandle, sizeof(uint32_t)); length_remaining = calloc(xc->maxhandle, sizeof(uint32_t)); +if(fv) { fprintf(fv, "$dumpvars\n"); } + for(;;) { uint32_t *tc_head = NULL; @@ -5492,7 +5723,7 @@ acceptable. Do NOT use for cryptographic purposes. -------------------------------------------------------------------- */ -static uint32_t j_hash(uint8_t *k, uint32_t length, uint32_t initval) +static uint32_t j_hash(const uint8_t *k, uint32_t length, uint32_t initval) { uint32_t a,b,c,len; @@ -5551,7 +5782,7 @@ unsigned char mem[1]; }; -void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t hashmask) +void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask) { struct collchain_t ***base = (struct collchain_t ***)base_i; uint32_t hf, h; diff --git a/vpi/fstapi.h b/vpi/fstapi.h index 7c77ced32..9ace034ac 100644 --- a/vpi/fstapi.h +++ b/vpi/fstapi.h @@ -40,6 +40,16 @@ extern "C" { typedef uint32_t fstHandle; +enum fstFileType { + FST_FT_MIN = 0, + + FST_FT_VERILOG = 0, + FST_FT_VHDL = 1, + FST_FT_VERILOG_VHDL = 2, + + FST_FT_MAX = 2 +}; + enum fstBlockType { FST_BL_HDR = 0, FST_BL_VCDATA = 1, @@ -53,7 +63,8 @@ enum fstBlockType { }; enum fstScopeType { - FST_ST_VCD_MIN = 0, + FST_ST_MIN = 0, + FST_ST_VCD_MODULE = 0, FST_ST_VCD_TASK = 1, FST_ST_VCD_FUNCTION = 2, @@ -66,9 +77,19 @@ enum fstScopeType { FST_ST_VCD_INTERFACE = 9, FST_ST_VCD_PACKAGE = 10, FST_ST_VCD_PROGRAM = 11, - FST_ST_VCD_MAX = 11, - FST_ST_MAX = 11, + FST_ST_VHDL_ARCHITECTURE = 12, + FST_ST_VHDL_PROCEDURE = 13, + FST_ST_VHDL_FUNCTION = 14, + FST_ST_VHDL_RECORD = 15, + FST_ST_VHDL_PROCESS = 16, + FST_ST_VHDL_BLOCK = 17, + FST_ST_VHDL_FOR_GENERATE = 18, + FST_ST_VHDL_IF_GENERATE = 19, + FST_ST_VHDL_GENERATE = 20, + FST_ST_VHDL_PACKAGE = 21, + + FST_ST_MAX = 21, FST_ST_GEN_ATTRBEGIN = 252, FST_ST_GEN_ATTREND = 253, @@ -78,7 +99,8 @@ enum fstScopeType { }; enum fstVarType { - FST_VT_VCD_MIN = 0, /* start of VCD datatypes */ + FST_VT_MIN = 0, /* start of vartypes */ + FST_VT_VCD_EVENT = 0, FST_VT_VCD_INTEGER = 1, FST_VT_VCD_PARAMETER = 2, @@ -105,26 +127,32 @@ enum fstVarType { FST_VT_SV_BIT = 22, FST_VT_SV_LOGIC = 23, - FST_VT_SV_INT = 24, /* declare as 31:0 */ - FST_VT_SV_SHORTINT = 25, /* declare as 15:0 */ - FST_VT_SV_LONGINT = 26, /* declare as 63:0 */ - FST_VT_SV_BYTE = 27, /* declare as 7:0 */ + FST_VT_SV_INT = 24, /* declare as size = 32 */ + FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */ + FST_VT_SV_LONGINT = 26, /* declare as size = 64 */ + FST_VT_SV_BYTE = 27, /* declare as size = 8 */ FST_VT_SV_ENUM = 28, /* declare as appropriate type range */ - FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL */ + FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */ - FST_VT_VCD_MAX = 29 /* end of VCD datatypes */ + FST_VT_MAX = 29 /* end of vartypes */ }; enum fstVarDir { + FST_VD_MIN = 0, + FST_VD_IMPLICIT = 0, FST_VD_INPUT = 1, FST_VD_OUTPUT = 2, FST_VD_INOUT = 3, + FST_VD_BUFFER = 4, + FST_VD_LINKAGE = 5, - FST_VD_MAX = 3 + FST_VD_MAX = 5 }; enum fstHierType { + FST_HT_MIN = 0, + FST_HT_SCOPE = 0, FST_HT_UPSCOPE = 1, FST_HT_VAR = 2, @@ -135,7 +163,9 @@ enum fstHierType { }; enum fstAttrType { - FST_AT_MISC = 0, + FST_AT_MIN = 0, + + FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */ FST_AT_ARRAY = 1, FST_AT_ENUM = 2, FST_AT_PACK = 3, @@ -144,14 +174,22 @@ enum fstAttrType { }; enum fstMiscType { - FST_MT_COMMENT = 0, /* self-contained: does not need matching FST_HT_ATTREND, use fstWriterSetComment() to emit */ - FST_MT_ENVVAR = 1, /* self-contained: does not need matching FST_HT_ATTREND, use fstWriterSetEnvVar() to emit */ - FST_MT_UNKNOWN = 2, + FST_MT_MIN = 0, - FST_MT_MAX = 2 + FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */ + FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */ + FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */ + FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */ + FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */ + FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */ + FST_MT_UNKNOWN = 6, + + FST_MT_MAX = 6 }; enum fstArrayType { + FST_AR_MIN = 0, + FST_AR_NONE = 0, FST_AR_UNPACKED = 1, FST_AR_PACKED = 2, @@ -188,6 +226,49 @@ enum fstPackType { FST_PT_MAX = 3 }; +enum fstSupplementalVarType { + FST_SVT_MIN = 0, + + FST_SVT_NONE = 0, + + FST_SVT_VHDL_SIGNAL = 1, + FST_SVT_VHDL_VARIABLE = 2, + FST_SVT_VHDL_CONSTANT = 3, + FST_SVT_VHDL_FILE = 4, + FST_SVT_VHDL_MEMORY = 5, + + FST_SVT_MAX = 5, +}; + +enum fstSupplementalDataType { + FST_SDT_MIN = 0, + + FST_SDT_NONE = 0, + + FST_SDT_VHDL_BOOLEAN = 1, + FST_SDT_VHDL_BIT = 2, + FST_SDT_VHDL_BIT_VECTOR = 3, + FST_SDT_VHDL_STD_ULOGIC = 4, + FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5, + FST_SDT_VHDL_STD_LOGIC = 6, + FST_SDT_VHDL_STD_LOGIC_VECTOR = 7, + FST_SDT_VHDL_UNSIGNED = 8, + FST_SDT_VHDL_SIGNED = 9, + FST_SDT_VHDL_INTEGER = 10, + FST_SDT_VHDL_REAL = 11, + FST_SDT_VHDL_NATURAL = 12, + FST_SDT_VHDL_POSITIVE = 13, + FST_SDT_VHDL_TIME = 14, + FST_SDT_VHDL_CHARACTER = 15, + FST_SDT_VHDL_STRING = 16, + + FST_SDT_MAX = 16, + + FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */ + FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1) +}; + + struct fstHier { unsigned char htyp; @@ -195,7 +276,7 @@ unsigned char htyp; union { /* if htyp == FST_HT_SCOPE */ struct fstHierScope { - unsigned char typ; /* FST_ST_VCD_MODULE ... FST_ST_VCD_PROGRAM */ + unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */ const char *name; const char *component; uint32_t name_length; /* strlen(u.scope.name) */ @@ -204,8 +285,11 @@ union { /* if htyp == FST_HT_VAR */ struct fstHierVar { - unsigned char typ; /* FST_VT_VCD_EVENT ... FST_VT_GEN_STRING */ - unsigned char direction; /* FST_VD_IMPLICIT ... FST_VD_INOUT */ + unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */ + unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */ + unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */ + unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */ + unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */ const char *name; uint32_t length; fstHandle handle; @@ -215,10 +299,11 @@ union { /* if htyp == FST_HT_ATTRBEGIN */ struct fstHierAttr { - unsigned char typ; /* FST_AT_MISC ... FST_AT_PACK */ + unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */ unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */ const char *name; uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */ + uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */ uint32_t name_length; /* strlen(u.attr.name) */ } attr; } u; @@ -228,101 +313,101 @@ union { /* * writer functions */ -fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd, - uint32_t len, const char *nam, fstHandle aliasHandle); +void fstWriterClose(void *ctx); +void * fstWriterCreate(const char *nam, int use_compressed_hier); + /* used for Verilog/SV */ +fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd, + uint32_t len, const char *nam, fstHandle aliasHandle); + /* future expansion for VHDL and other languages. The variable type, data type, etc map onto + the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */ +fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd, + uint32_t len, const char *nam, fstHandle aliasHandle, + const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt); +void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val); +void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len); +void fstWriterEmitDumpActive(void *ctx, int enable); +void fstWriterEmitTimeChange(void *ctx, uint64_t tim); +void fstWriterFlushContext(void *ctx); +int fstWriterGetDumpSizeLimitReached(void *ctx); +int fstWriterGetFseekFailed(void *ctx); +void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype, + const char *attrname, uint64_t arg); +void fstWriterSetAttrEnd(void *ctx); +void fstWriterSetComment(void *ctx, const char *comm); +void fstWriterSetDate(void *ctx, const char *dat); +void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes); +void fstWriterSetEnvVar(void *ctx, const char *envvar); +void fstWriterSetFileType(void *ctx, enum fstFileType filetype); +void fstWriterSetPackType(void *ctx, int typ); /* type = 0 (libz), 1 (fastlz) */ +void fstWriterSetParallelMode(void *ctx, int enable); +void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */ +void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, + const char *scopename, const char *scopecomp); +void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath); +void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath); +void fstWriterSetTimescale(void *ctx, int ts); +void fstWriterSetTimescaleFromString(void *ctx, const char *s); +void fstWriterSetTimezero(void *ctx, int64_t tim); +void fstWriterSetUpscope(void *ctx); +void fstWriterSetVersion(void *ctx, const char *vers); -void fstWriterSetPackType(void *ctx, int typ); /* type = 0 (libz), 1 (fastlz) */ -void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */ -void fstWriterSetParallelMode(void *ctx, int enable); -void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes); -int fstWriterGetDumpSizeLimitReached(void *ctx); -int fstWriterGetFseekFailed(void *ctx); - -void *fstWriterCreate(const char *nam, int use_compressed_hier); -void fstWriterClose(void *ctx); -void fstWriterSetDate(void *ctx, const char *dat); -void fstWriterSetVersion(void *ctx, const char *vers); -void fstWriterSetComment(void *ctx, const char *comm); -void fstWriterSetEnvVar(void *ctx, const char *envvar); -void fstWriterSetTimescale(void *ctx, int ts); -void fstWriterSetTimescaleFromString(void *ctx, const char *s); -void fstWriterSetTimezero(void *ctx, int64_t tim); -void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, - const char *scopename, const char *scopecomp); -void fstWriterSetUpscope(void *ctx); -void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val); -void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len); -void fstWriterEmitDumpActive(void *ctx, int enable); -void fstWriterEmitTimeChange(void *ctx, uint64_t tim); -void fstWriterFlushContext(void *ctx); -void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype, - const char *attrname, uint64_t arg); -void fstWriterSetAttrEnd(void *ctx); /* * reader functions */ -void *fstReaderOpen(const char *nam); -void *fstReaderOpenForUtilitiesOnly(void); -void fstReaderClose(void *ctx); - -int fstReaderProcessHier(void *ctx, FILE *vcdhandle); -int fstReaderIterateHierRewind(void *ctx); +void fstReaderClose(void *ctx); +void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx); +void fstReaderClrFacProcessMaskAll(void *ctx); +uint64_t fstReaderGetAliasCount(void *ctx); +const char * fstReaderGetCurrentFlatScope(void *ctx); +void * fstReaderGetCurrentScopeUserInfo(void *ctx); +int fstReaderGetCurrentScopeLen(void *ctx); +const char * fstReaderGetDateString(void *ctx); +int fstReaderGetDoubleEndianMatchState(void *ctx); +uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx); +unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx); +uint64_t fstReaderGetEndTime(void *ctx); +int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx); +int fstReaderGetFileType(void *ctx); +int fstReaderGetFseekFailed(void *ctx); +fstHandle fstReaderGetMaxHandle(void *ctx); +uint64_t fstReaderGetMemoryUsedByWriter(void *ctx); +uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx); +uint64_t fstReaderGetScopeCount(void *ctx); +uint64_t fstReaderGetStartTime(void *ctx); +signed char fstReaderGetTimescale(void *ctx); +int64_t fstReaderGetTimezero(void *ctx); +uint64_t fstReaderGetValueChangeSectionCount(void *ctx); +char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf); +uint64_t fstReaderGetVarCount(void *ctx); +const char * fstReaderGetVersionString(void *ctx); struct fstHier *fstReaderIterateHier(void *ctx); +int fstReaderIterateHierRewind(void *ctx); +int fstReaderIterBlocks(void *ctx, + void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), + void *user_callback_data_pointer, FILE *vcdhandle); +int fstReaderIterBlocks2(void *ctx, + void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), + void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len), + void *user_callback_data_pointer, FILE *vcdhandle); +void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable); +void * fstReaderOpen(const char *nam); +void * fstReaderOpenForUtilitiesOnly(void); +const char * fstReaderPopScope(void *ctx); +int fstReaderProcessHier(void *ctx, FILE *vcdhandle); +const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info); +void fstReaderResetScope(void *ctx); +void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx); +void fstReaderSetFacProcessMaskAll(void *ctx); +void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time); +void fstReaderSetUnlimitedTimeRange(void *ctx); -void fstReaderResetScope(void *ctx); -const char *fstReaderPopScope(void *ctx); -const char *fstReaderPushScope(void *ctx, const char *nam, void *user_info); -const char *fstReaderGetCurrentFlatScope(void *ctx); -void *fstReaderGetCurrentScopeUserInfo(void *ctx); -int fstReaderGetCurrentScopeLen(void *ctx); - -signed char fstReaderGetTimescale(void *ctx); -int64_t fstReaderGetTimezero(void *ctx); -uint64_t fstReaderGetStartTime(void *ctx); -uint64_t fstReaderGetEndTime(void *ctx); -uint64_t fstReaderGetMemoryUsedByWriter(void *ctx); -uint64_t fstReaderGetScopeCount(void *ctx); -uint64_t fstReaderGetVarCount(void *ctx); -fstHandle fstReaderGetMaxHandle(void *ctx); -uint64_t fstReaderGetAliasCount(void *ctx); -uint64_t fstReaderGetValueChangeSectionCount(void *ctx); -int fstReaderGetDoubleEndianMatchState(void *ctx); -const char *fstReaderGetVersionString(void *ctx); -const char *fstReaderGetDateString(void *ctx); -int fstReaderGetFseekFailed(void *ctx); - -void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time); -void fstReaderSetUnlimitedTimeRange(void *ctx); - -uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx); -uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx); -unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx); - -int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx); -void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx); -void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx); -void fstReaderSetFacProcessMaskAll(void *ctx); -void fstReaderClrFacProcessMaskAll(void *ctx); - -void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable); - -int fstReaderIterBlocks(void *ctx, - void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), - void *user_callback_data_pointer, FILE *vcdhandle); - -int fstReaderIterBlocks2(void *ctx, - void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), - void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len), - void *user_callback_data_pointer, FILE *vcdhandle); - -char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf); /* * utility functions */ -int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len); -int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len); +int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len); +int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len); #ifdef __cplusplus }