1 /*
2  * Copyright (c) 2003-2012 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 DEFS_LXTW_H
24 #define DEFS_LXTW_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 <errno.h>
35 #include <unistd.h>
36 #ifdef HAVE_INTTYPES_H
37 #include <inttypes.h>
38 #endif
39 #include <zlib.h>
40 
41 #ifndef HAVE_FSEEKO
42 #define fseeko fseek
43 #define ftello ftell
44 #endif
45 
46 #include "wavealloca.h"
47 
48 #define LXT2_WR_HDRID (0x1380)
49 #define LXT2_WR_VERSION (0x0001)
50 
51 #define LXT2_WR_GRANULE_SIZE (64)
52 #define LXT2_WR_GRANULE_NUM (256)
53 #define LXT2_WR_PARTIAL_SIZE (2048)
54 
55 #define LXT2_WR_GRAN_SECT_TIME 0
56 #define LXT2_WR_GRAN_SECT_DICT 1
57 #define LXT2_WR_GRAN_SECT_TIME_PARTIAL 2
58 
59 #define LXT2_WR_GZWRITE_BUFFER 4096
60 #define LXT2_WR_SYMPRIME 500009
61 
62 typedef uint64_t lxttime_t;
63 typedef  int64_t lxtstime_t;
64 
65 
66 #ifndef _MSC_VER
67 	#ifdef __MINGW32__
68 		#define LXT2_WR_LLD "%I64d"
69 	#else
70         	#define LXT2_WR_LLD "%lld"
71 	#endif
72         #define LXT2_WR_LLDESC(x) x##LL
73         #define LXT2_WR_ULLDESC(x) x##ULL
74 #else
75         #define LXT2_WR_LLD "%I64d"
76         #define LXT2_WR_LLDESC(x) x##i64
77         #define LXT2_WR_ULLDESC(x) x##i64
78 #endif
79 
80 #if LXT2_WR_GRANULE_SIZE > 32
81 typedef unsigned long long granmsk_t;
82 #define LXT2_WR_GRAN_0VAL (LXT2_WR_ULLDESC(0))
83 #define LXT2_WR_GRAN_1VAL (LXT2_WR_ULLDESC(1))
84 #else
85 typedef unsigned int granmsk_t;
86 #define LXT2_WR_GRAN_0VAL (0)
87 #define LXT2_WR_GRAN_1VAL (1)
88 #endif
89 
90 
91 enum LXT2_WR_Encodings {
92 	LXT2_WR_ENC_0,
93 	LXT2_WR_ENC_1,
94 	LXT2_WR_ENC_INV,
95 	LXT2_WR_ENC_LSH0,
96 	LXT2_WR_ENC_LSH1,
97 	LXT2_WR_ENC_RSH0,
98 	LXT2_WR_ENC_RSH1,
99 
100 	LXT2_WR_ENC_ADD1,
101 	LXT2_WR_ENC_ADD2,
102 	LXT2_WR_ENC_ADD3,
103 	LXT2_WR_ENC_ADD4,
104 
105 	LXT2_WR_ENC_SUB1,
106 	LXT2_WR_ENC_SUB2,
107 	LXT2_WR_ENC_SUB3,
108 	LXT2_WR_ENC_SUB4,
109 
110 	LXT2_WR_ENC_X,
111 	LXT2_WR_ENC_Z,
112 
113 	LXT2_WR_ENC_BLACKOUT,
114 
115 	LXT2_WR_DICT_START
116 	};
117 
118 /*
119  * integer splay
120  */
121 typedef struct lxt2_wr_ds_tree_node lxt2_wr_ds_Tree;
122 struct lxt2_wr_ds_tree_node {
123     lxt2_wr_ds_Tree * left, * right;
124     granmsk_t item;
125     int val;
126     lxt2_wr_ds_Tree * next;
127 };
128 
129 
130 /*
131  * string splay
132  */
133 typedef struct lxt2_wr_dslxt_tree_node lxt2_wr_dslxt_Tree;
134 struct lxt2_wr_dslxt_tree_node {
135     lxt2_wr_dslxt_Tree * left, * right;
136     char *item;
137     unsigned int val;
138     lxt2_wr_dslxt_Tree * next;
139 };
140 
141 
142 struct lxt2_wr_trace
143 {
144 FILE *handle;
145 gzFile zhandle;
146 
147 lxt2_wr_dslxt_Tree *dict;	/* dictionary manipulation */
148 unsigned int num_dict_entries;
149 unsigned int dict_string_mem_required;
150 lxt2_wr_dslxt_Tree *dict_head;
151 lxt2_wr_dslxt_Tree *dict_curr;
152 
153 lxt2_wr_ds_Tree *mapdict;	/* bitmap compression */
154 unsigned int num_map_entries;
155 lxt2_wr_ds_Tree *mapdict_head;
156 lxt2_wr_ds_Tree *mapdict_curr;
157 
158 off_t position;
159 off_t zfacname_predec_size, zfacname_size, zfacgeometry_size;
160 off_t zpackcount, zpackcount_cumulative;
161 off_t current_chunk, current_chunkz;
162 
163 struct lxt2_wr_symbol *sym[LXT2_WR_SYMPRIME];
164 struct lxt2_wr_symbol **sorted_facs;
165 struct lxt2_wr_symbol *symchain;
166 unsigned int numfacs, numalias;
167 int numfacbytes;
168 int longestname;
169 
170 int numsections, numblock;
171 off_t facname_offset, facgeometry_offset;
172 
173 lxttime_t mintime, maxtime;
174 lxtstime_t timezero;
175 unsigned int timegranule;
176 int timescale;
177 unsigned int timepos;
178 unsigned int maxgranule;
179 lxttime_t firsttime, lasttime;
180 lxttime_t timetable[LXT2_WR_GRANULE_SIZE];
181 
182 unsigned int partial_iter;
183 
184 char *compress_fac_str;
185 int compress_fac_len;
186 
187 lxttime_t flushtime;
188 unsigned flush_valid : 1;
189 
190 unsigned do_strip_brackets : 1;
191 unsigned emitted : 1;			/* gate off change field zmode changes when set */
192 unsigned timeset : 1;			/* time has been modified from 0..0 */
193 unsigned bumptime : 1;			/* says that must go to next time position in granule as value change exists for current time */
194 unsigned granule_dirty : 1;		/* for flushing out final block */
195 unsigned blackout : 1;			/* blackout on/off */
196 unsigned partial : 1;			/* partial (vertical) trace support */
197 unsigned partial_zip : 1;		/* partial (vertical) trace support for zip subregions */
198 unsigned no_checkpoint : 1;		/* turns off interblock checkpointing */
199 unsigned partial_preference : 1;	/* partial preference encountered on some facs */
200 
201 char initial_value;
202 
203 char zmode[4];				/* fills in with "wb0".."wb9" */
204 unsigned int gzbufpnt;
205 unsigned char gzdest[LXT2_WR_GZWRITE_BUFFER + 4];	/* enough for zlib buffering */
206 
207 char *lxtname;
208 off_t break_size;
209 off_t break_header_size;
210 unsigned int break_number;
211 };
212 
213 
214 struct lxt2_wr_symbol
215 {
216 struct lxt2_wr_symbol *next;
217 struct lxt2_wr_symbol *symchain;
218 char *name;
219 int namlen;
220 
221 int facnum;
222 struct lxt2_wr_symbol *aliased_to;
223 
224 char *value;	/* fac's actual value */
225 
226 unsigned int rows;
227 int msb, lsb;
228 int len;
229 int flags;
230 
231 unsigned partial_preference : 1;	/* in order to shove nets to the first partial group */
232 
233 unsigned int chgpos;
234 granmsk_t msk;				/* must contain LXT2_WR_GRANULE_SIZE bits! */
235 unsigned int chg[LXT2_WR_GRANULE_SIZE];
236 };
237 
238 
239 #define LXT2_WR_SYM_F_BITS         (0)
240 #define LXT2_WR_SYM_F_INTEGER      (1<<0)
241 #define LXT2_WR_SYM_F_DOUBLE       (1<<1)
242 #define LXT2_WR_SYM_F_STRING       (1<<2)
243 #define LXT2_WR_SYM_F_TIME         (LXT2_WR_SYM_F_STRING)      /* user must correctly format this as a string */
244 #define LXT2_WR_SYM_F_ALIAS        (1<<3)
245 
246 #define LXT2_WR_SYM_F_SIGNED       (1<<4)
247 #define LXT2_WR_SYM_F_BOOLEAN      (1<<5)
248 #define LXT2_WR_SYM_F_NATURAL      ((1<<6)|(LXT2_WR_SYM_F_INTEGER))
249 #define LXT2_WR_SYM_F_POSITIVE     ((1<<7)|(LXT2_WR_SYM_F_INTEGER))
250 #define LXT2_WR_SYM_F_CHARACTER    (1<<8)
251 
252 #define LXT2_WR_SYM_F_CONSTANT     (1<<9)
253 #define LXT2_WR_SYM_F_VARIABLE     (1<<10)
254 #define LXT2_WR_SYM_F_SIGNAL       (1<<11)
255 
256 #define LXT2_WR_SYM_F_IN           (1<<12)
257 #define LXT2_WR_SYM_F_OUT          (1<<13)
258 #define LXT2_WR_SYM_F_INOUT        (1<<14)
259 
260 #define LXT2_WR_SYM_F_WIRE         (1<<15)
261 #define LXT2_WR_SYM_F_REG          (1<<16)
262 
263 
264 			/* file I/O */
265 struct lxt2_wr_trace *	lxt2_wr_init(const char *name);
266 void 			lxt2_wr_flush(struct lxt2_wr_trace *lt);
267 void 			lxt2_wr_close(struct lxt2_wr_trace *lt);
268 
269 			/* for dealing with very large traces, split into multiple files approximately "siz" in length */
270 void 			lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz);
271 
272 			/* 0 = no compression, 9 = best compression, 4 = default */
273 void			lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth);
274 
275 			/* default is partial off, turning on makes for faster trace reads, nonzero zipmode causes vertical compression */
276 void			lxt2_wr_set_partial_off(struct lxt2_wr_trace *lt);
277 void			lxt2_wr_set_partial_on(struct lxt2_wr_trace *lt, int zipmode);
278 void			lxt2_wr_set_partial_preference(struct lxt2_wr_trace *lt, const char *name);
279 
280 			/* turning off checkpointing makes for smaller files */
281 void			lxt2_wr_set_checkpoint_off(struct lxt2_wr_trace *lt);
282 void			lxt2_wr_set_checkpoint_on(struct lxt2_wr_trace *lt);
283 
284 			/* facility creation */
285 void                    lxt2_wr_set_initial_value(struct lxt2_wr_trace *lt, char value);
286 struct lxt2_wr_symbol *	lxt2_wr_symbol_find(struct lxt2_wr_trace *lt, const char *name);
287 struct lxt2_wr_symbol *	lxt2_wr_symbol_add(struct lxt2_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags);
288 struct lxt2_wr_symbol *	lxt2_wr_symbol_alias(struct lxt2_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb);
289 void			lxt2_wr_symbol_bracket_stripping(struct lxt2_wr_trace *lt, int doit);
290 
291 			/* each granule is LXT2_WR_GRANULE_SIZE (32 or 64) timesteps, default is 256 per section */
292 void 			lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule);
293 
294 			/* time ops */
295 void 			lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale);
296 void 			lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval);
297 int 			lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval);
298 int 			lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval);
299 int 			lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval);
300 int 			lxt2_wr_inc_time_by_delta64(struct lxt2_wr_trace *lt, lxttime_t timeval);
301 
302                         /* allows blackout regions in LXT files */
303 void                    lxt2_wr_set_dumpoff(struct lxt2_wr_trace *lt);
304 void                    lxt2_wr_set_dumpon(struct lxt2_wr_trace *lt);
305 
306 			/* left fill on bit_string uses vcd semantics (left fill with value[0] unless value[0]=='1', then use '0') */
307 int 			lxt2_wr_emit_value_int(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, int value);
308 int 			lxt2_wr_emit_value_double(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, double value);
309 int 			lxt2_wr_emit_value_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value);
310 int 			lxt2_wr_emit_value_bit_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value);
311 
312 #ifdef __cplusplus
313 }
314 #endif
315 
316 #endif
317