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