1 /*
2  * Copyright (c) 2009-2018 Tony Bybell.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  *
22  * SPDX-License-Identifier: MIT
23  */
24 
25 #ifndef FST_API_H
26 #define FST_API_H
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <zlib.h>
37 #include <inttypes.h>
38 #include <unistd.h>
39 #include <time.h>
40 
41 #define FST_RDLOAD "FSTLOAD | "
42 
43 typedef uint32_t fstHandle;
44 typedef uint32_t fstEnumHandle;
45 
46 enum fstWriterPackType {
47     FST_WR_PT_ZLIB             = 0,
48     FST_WR_PT_FASTLZ           = 1,
49     FST_WR_PT_LZ4              = 2
50 };
51 
52 enum fstFileType {
53     FST_FT_MIN                 = 0,
54 
55     FST_FT_VERILOG             = 0,
56     FST_FT_VHDL                = 1,
57     FST_FT_VERILOG_VHDL        = 2,
58 
59     FST_FT_MAX                 = 2
60 };
61 
62 enum fstBlockType {
63     FST_BL_HDR                 = 0,
64     FST_BL_VCDATA              = 1,
65     FST_BL_BLACKOUT            = 2,
66     FST_BL_GEOM                = 3,
67     FST_BL_HIER                = 4,
68     FST_BL_VCDATA_DYN_ALIAS    = 5,
69     FST_BL_HIER_LZ4            = 6,
70     FST_BL_HIER_LZ4DUO         = 7,
71     FST_BL_VCDATA_DYN_ALIAS2   = 8,
72 
73     FST_BL_ZWRAPPER            = 254,   /* indicates that whole trace is gz wrapped */
74     FST_BL_SKIP                = 255    /* used while block is being written */
75 };
76 
77 enum fstScopeType {
78     FST_ST_MIN                 = 0,
79 
80     FST_ST_VCD_MODULE          = 0,
81     FST_ST_VCD_TASK            = 1,
82     FST_ST_VCD_FUNCTION        = 2,
83     FST_ST_VCD_BEGIN           = 3,
84     FST_ST_VCD_FORK            = 4,
85     FST_ST_VCD_GENERATE        = 5,
86     FST_ST_VCD_STRUCT          = 6,
87     FST_ST_VCD_UNION           = 7,
88     FST_ST_VCD_CLASS           = 8,
89     FST_ST_VCD_INTERFACE       = 9,
90     FST_ST_VCD_PACKAGE         = 10,
91     FST_ST_VCD_PROGRAM         = 11,
92 
93     FST_ST_VHDL_ARCHITECTURE   = 12,
94     FST_ST_VHDL_PROCEDURE      = 13,
95     FST_ST_VHDL_FUNCTION       = 14,
96     FST_ST_VHDL_RECORD         = 15,
97     FST_ST_VHDL_PROCESS        = 16,
98     FST_ST_VHDL_BLOCK          = 17,
99     FST_ST_VHDL_FOR_GENERATE   = 18,
100     FST_ST_VHDL_IF_GENERATE    = 19,
101     FST_ST_VHDL_GENERATE       = 20,
102     FST_ST_VHDL_PACKAGE        = 21,
103 
104     FST_ST_MAX                 = 21,
105 
106     FST_ST_GEN_ATTRBEGIN       = 252,
107     FST_ST_GEN_ATTREND         = 253,
108 
109     FST_ST_VCD_SCOPE           = 254,
110     FST_ST_VCD_UPSCOPE         = 255
111 };
112 
113 enum fstVarType {
114     FST_VT_MIN                 = 0,     /* start of vartypes */
115 
116     FST_VT_VCD_EVENT           = 0,
117     FST_VT_VCD_INTEGER         = 1,
118     FST_VT_VCD_PARAMETER       = 2,
119     FST_VT_VCD_REAL            = 3,
120     FST_VT_VCD_REAL_PARAMETER  = 4,
121     FST_VT_VCD_REG             = 5,
122     FST_VT_VCD_SUPPLY0         = 6,
123     FST_VT_VCD_SUPPLY1         = 7,
124     FST_VT_VCD_TIME            = 8,
125     FST_VT_VCD_TRI             = 9,
126     FST_VT_VCD_TRIAND          = 10,
127     FST_VT_VCD_TRIOR           = 11,
128     FST_VT_VCD_TRIREG          = 12,
129     FST_VT_VCD_TRI0            = 13,
130     FST_VT_VCD_TRI1            = 14,
131     FST_VT_VCD_WAND            = 15,
132     FST_VT_VCD_WIRE            = 16,
133     FST_VT_VCD_WOR             = 17,
134     FST_VT_VCD_PORT            = 18,
135     FST_VT_VCD_SPARRAY         = 19,    /* used to define the rownum (index) port for a sparse array */
136     FST_VT_VCD_REALTIME        = 20,
137 
138     FST_VT_GEN_STRING          = 21,    /* generic string type   (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
139 
140     FST_VT_SV_BIT              = 22,
141     FST_VT_SV_LOGIC            = 23,
142     FST_VT_SV_INT              = 24,    /* declare as size = 32 */
143     FST_VT_SV_SHORTINT         = 25,    /* declare as size = 16 */
144     FST_VT_SV_LONGINT          = 26,    /* declare as size = 64 */
145     FST_VT_SV_BYTE             = 27,    /* declare as size = 8  */
146     FST_VT_SV_ENUM             = 28,    /* declare as appropriate type range */
147     FST_VT_SV_SHORTREAL        = 29,    /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
148 
149     FST_VT_MAX                 = 29     /* end of vartypes */
150 };
151 
152 enum fstVarDir {
153     FST_VD_MIN         = 0,
154 
155     FST_VD_IMPLICIT    = 0,
156     FST_VD_INPUT       = 1,
157     FST_VD_OUTPUT      = 2,
158     FST_VD_INOUT       = 3,
159     FST_VD_BUFFER      = 4,
160     FST_VD_LINKAGE     = 5,
161 
162     FST_VD_MAX         = 5
163 };
164 
165 enum fstHierType {
166     FST_HT_MIN         = 0,
167 
168     FST_HT_SCOPE       = 0,
169     FST_HT_UPSCOPE     = 1,
170     FST_HT_VAR         = 2,
171     FST_HT_ATTRBEGIN   = 3,
172     FST_HT_ATTREND     = 4,
173 
174     /* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
175     FST_HT_TREEBEGIN   = 5,
176     FST_HT_TREEEND     = 6,
177 
178     FST_HT_MAX         = 6
179 };
180 
181 enum fstAttrType {
182     FST_AT_MIN         = 0,
183 
184     FST_AT_MISC        = 0,     /* self-contained: does not need matching FST_HT_ATTREND */
185     FST_AT_ARRAY       = 1,
186     FST_AT_ENUM        = 2,
187     FST_AT_PACK        = 3,
188 
189     FST_AT_MAX         = 3
190 };
191 
192 enum fstMiscType {
193     FST_MT_MIN         = 0,
194 
195     FST_MT_COMMENT     = 0,     /* use fstWriterSetComment() to emit */
196     FST_MT_ENVVAR      = 1,     /* use fstWriterSetEnvVar() to emit */
197     FST_MT_SUPVAR      = 2,     /* use fstWriterCreateVar2() to emit */
198     FST_MT_PATHNAME    = 3,     /* reserved for fstWriterSetSourceStem() string -> number management */
199     FST_MT_SOURCESTEM  = 4,     /* use fstWriterSetSourceStem() to emit */
200     FST_MT_SOURCEISTEM = 5,     /* use fstWriterSetSourceInstantiationStem() to emit */
201     FST_MT_VALUELIST   = 6,	/* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */
202     FST_MT_ENUMTABLE   = 7,	/* use fstWriterCreateEnumTable() and fstWriterEmitEnumTableRef() to emit */
203     FST_MT_UNKNOWN     = 8,
204 
205     FST_MT_MAX         = 8
206 };
207 
208 enum fstArrayType {
209     FST_AR_MIN         = 0,
210 
211     FST_AR_NONE        = 0,
212     FST_AR_UNPACKED    = 1,
213     FST_AR_PACKED      = 2,
214     FST_AR_SPARSE      = 3,
215 
216     FST_AR_MAX         = 3
217 };
218 
219 enum fstEnumValueType {
220     FST_EV_SV_INTEGER           = 0,
221     FST_EV_SV_BIT               = 1,
222     FST_EV_SV_LOGIC             = 2,
223     FST_EV_SV_INT               = 3,
224     FST_EV_SV_SHORTINT          = 4,
225     FST_EV_SV_LONGINT           = 5,
226     FST_EV_SV_BYTE              = 6,
227     FST_EV_SV_UNSIGNED_INTEGER  = 7,
228     FST_EV_SV_UNSIGNED_BIT      = 8,
229     FST_EV_SV_UNSIGNED_LOGIC    = 9,
230     FST_EV_SV_UNSIGNED_INT      = 10,
231     FST_EV_SV_UNSIGNED_SHORTINT = 11,
232     FST_EV_SV_UNSIGNED_LONGINT  = 12,
233     FST_EV_SV_UNSIGNED_BYTE     = 13,
234 
235     FST_EV_REG			= 14,
236     FST_EV_TIME			= 15,
237 
238     FST_EV_MAX                  = 15
239 };
240 
241 enum fstPackType {
242     FST_PT_NONE          = 0,
243     FST_PT_UNPACKED      = 1,
244     FST_PT_PACKED        = 2,
245     FST_PT_TAGGED_PACKED = 3,
246 
247     FST_PT_MAX           = 3
248 };
249 
250 enum fstSupplementalVarType {
251     FST_SVT_MIN                    = 0,
252 
253     FST_SVT_NONE                   = 0,
254 
255     FST_SVT_VHDL_SIGNAL            = 1,
256     FST_SVT_VHDL_VARIABLE          = 2,
257     FST_SVT_VHDL_CONSTANT          = 3,
258     FST_SVT_VHDL_FILE              = 4,
259     FST_SVT_VHDL_MEMORY            = 5,
260 
261     FST_SVT_MAX                    = 5
262 };
263 
264 enum fstSupplementalDataType {
265     FST_SDT_MIN                    = 0,
266 
267     FST_SDT_NONE                   = 0,
268 
269     FST_SDT_VHDL_BOOLEAN           = 1,
270     FST_SDT_VHDL_BIT               = 2,
271     FST_SDT_VHDL_BIT_VECTOR        = 3,
272     FST_SDT_VHDL_STD_ULOGIC        = 4,
273     FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5,
274     FST_SDT_VHDL_STD_LOGIC         = 6,
275     FST_SDT_VHDL_STD_LOGIC_VECTOR  = 7,
276     FST_SDT_VHDL_UNSIGNED          = 8,
277     FST_SDT_VHDL_SIGNED            = 9,
278     FST_SDT_VHDL_INTEGER           = 10,
279     FST_SDT_VHDL_REAL              = 11,
280     FST_SDT_VHDL_NATURAL           = 12,
281     FST_SDT_VHDL_POSITIVE          = 13,
282     FST_SDT_VHDL_TIME              = 14,
283     FST_SDT_VHDL_CHARACTER         = 15,
284     FST_SDT_VHDL_STRING            = 16,
285 
286     FST_SDT_MAX                    = 16,
287 
288     FST_SDT_SVT_SHIFT_COUNT        = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */
289     FST_SDT_ABS_MAX                = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1)
290 };
291 
292 
293 struct fstHier
294 {
295 unsigned char htyp;
296 
297 union {
298         /* if htyp == FST_HT_SCOPE */
299         struct fstHierScope {
300                 unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */
301                 const char *name;
302                 const char *component;
303                 uint32_t name_length;           /* strlen(u.scope.name) */
304                 uint32_t component_length;      /* strlen(u.scope.component) */
305                 } scope;
306 
307         /* if htyp == FST_HT_VAR */
308         struct fstHierVar {
309                 unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */
310                 unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */
311                 unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */
312                 unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */
313                 unsigned int  sxt_workspace; /* zeroed out by FST reader, for client code use */
314                 const char *name;
315                 uint32_t length;
316                 fstHandle handle;
317                 uint32_t name_length; /* strlen(u.var.name) */
318                 unsigned is_alias : 1;
319                 } var;
320 
321         /* if htyp == FST_HT_ATTRBEGIN */
322         struct fstHierAttr {
323                 unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */
324                 unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
325                 const char *name;
326                 uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
327                 uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
328                 uint32_t name_length; /* strlen(u.attr.name) */
329                 } attr;
330         } u;
331 };
332 
333 
334 struct fstETab
335 {
336 char *name;
337 uint32_t elem_count;
338 char **literal_arr;
339 char **val_arr;
340 };
341 
342 
343 /*
344  * writer functions
345  */
346 void            fstWriterClose(void *ctx);
347 void *          fstWriterCreate(const char *nam, int use_compressed_hier);
348 fstEnumHandle   fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr);
349                 /* used for Verilog/SV */
350 fstHandle       fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
351                         uint32_t len, const char *nam, fstHandle aliasHandle);
352                 /* future expansion for VHDL and other languages.  The variable type, data type, etc map onto
353                    the current Verilog/SV one.  The "type" string is optional for a more verbose or custom description */
354 fstHandle       fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
355                         uint32_t len, const char *nam, fstHandle aliasHandle,
356                         const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
357 void            fstWriterEmitDumpActive(void *ctx, int enable);
358 void 		fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle);
359 void            fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
360 void            fstWriterEmitValueChange32(void *ctx, fstHandle handle,
361                         uint32_t bits, uint32_t val);
362 void            fstWriterEmitValueChange64(void *ctx, fstHandle handle,
363                         uint32_t bits, uint64_t val);
364 void            fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle,
365                         uint32_t bits, const uint32_t *val);
366 void            fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle,
367                         uint32_t bits, const uint64_t *val);
368 void            fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
369 void            fstWriterEmitTimeChange(void *ctx, uint64_t tim);
370 void            fstWriterFlushContext(void *ctx);
371 int             fstWriterGetDumpSizeLimitReached(void *ctx);
372 int             fstWriterGetFseekFailed(void *ctx);
373 void            fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
374                         const char *attrname, uint64_t arg);
375 void            fstWriterSetAttrEnd(void *ctx);
376 void            fstWriterSetComment(void *ctx, const char *comm);
377 void            fstWriterSetDate(void *ctx, const char *dat);
378 void            fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
379 void            fstWriterSetEnvVar(void *ctx, const char *envvar);
380 void            fstWriterSetFileType(void *ctx, enum fstFileType filetype);
381 void            fstWriterSetPackType(void *ctx, enum fstWriterPackType typ);
382 void            fstWriterSetParallelMode(void *ctx, int enable);
383 void            fstWriterSetRepackOnClose(void *ctx, int enable);       /* type = 0 (none), 1 (libz) */
384 void            fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
385                         const char *scopename, const char *scopecomp);
386 void            fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
387 void            fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
388 void            fstWriterSetTimescale(void *ctx, int ts);
389 void            fstWriterSetTimescaleFromString(void *ctx, const char *s);
390 void            fstWriterSetTimezero(void *ctx, int64_t tim);
391 void            fstWriterSetUpscope(void *ctx);
392 void		fstWriterSetValueList(void *ctx, const char *vl);
393 void            fstWriterSetVersion(void *ctx, const char *vers);
394 
395 
396 /*
397  * reader functions
398  */
399 void            fstReaderClose(void *ctx);
400 void            fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
401 void            fstReaderClrFacProcessMaskAll(void *ctx);
402 uint64_t        fstReaderGetAliasCount(void *ctx);
403 const char *    fstReaderGetCurrentFlatScope(void *ctx);
404 void *          fstReaderGetCurrentScopeUserInfo(void *ctx);
405 int             fstReaderGetCurrentScopeLen(void *ctx);
406 const char *    fstReaderGetDateString(void *ctx);
407 int             fstReaderGetDoubleEndianMatchState(void *ctx);
408 uint64_t        fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
409 unsigned char   fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
410 uint64_t        fstReaderGetEndTime(void *ctx);
411 int             fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
412 int             fstReaderGetFileType(void *ctx);
413 int             fstReaderGetFseekFailed(void *ctx);
414 fstHandle       fstReaderGetMaxHandle(void *ctx);
415 uint64_t        fstReaderGetMemoryUsedByWriter(void *ctx);
416 uint32_t        fstReaderGetNumberDumpActivityChanges(void *ctx);
417 uint64_t        fstReaderGetScopeCount(void *ctx);
418 uint64_t        fstReaderGetStartTime(void *ctx);
419 signed char     fstReaderGetTimescale(void *ctx);
420 int64_t         fstReaderGetTimezero(void *ctx);
421 uint64_t        fstReaderGetValueChangeSectionCount(void *ctx);
422 char *          fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
423 uint64_t        fstReaderGetVarCount(void *ctx);
424 const char *    fstReaderGetVersionString(void *ctx);
425 struct fstHier *fstReaderIterateHier(void *ctx);
426 int             fstReaderIterateHierRewind(void *ctx);
427 int             fstReaderIterBlocks(void *ctx,
428                         void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
429                         void *user_callback_data_pointer, FILE *vcdhandle);
430 int             fstReaderIterBlocks2(void *ctx,
431                         void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
432                         void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
433                         void *user_callback_data_pointer, FILE *vcdhandle);
434 void            fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
435 void *          fstReaderOpen(const char *nam);
436 void *          fstReaderOpenForUtilitiesOnly(void);
437 const char *    fstReaderPopScope(void *ctx);
438 int             fstReaderProcessHier(void *ctx, FILE *vcdhandle);
439 const char *    fstReaderPushScope(void *ctx, const char *nam, void *user_info);
440 void            fstReaderResetScope(void *ctx);
441 void            fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
442 void            fstReaderSetFacProcessMaskAll(void *ctx);
443 void            fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
444 void            fstReaderSetUnlimitedTimeRange(void *ctx);
445 void            fstReaderSetVcdExtensions(void *ctx, int enable);
446 
447 
448 /*
449  * utility functions
450  */
451 int             fstUtilityBinToEscConvertedLen(const unsigned char *s, int len); /* used for mallocs for fstUtilityBinToEsc() */
452 int             fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len);
453 int             fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
454 struct fstETab *fstUtilityExtractEnumTableFromString(const char *s);
455 void 		fstUtilityFreeEnumTable(struct fstETab *etab); /* must use to free fstETab properly */
456 
457 
458 #ifdef __cplusplus
459 }
460 #endif
461 
462 #endif
463