NAPA Compiler V4.50
Author: Yves Leduc, yves.leduc.be@gmail.com
Loading...
Searching...
No Matches
C:/Simulate/Napados/Source/fc.c
Go to the documentation of this file.
1/* ** MISCELLANEOUS FUNCTIONS DEFINITIONS *************************************************************************************** */
2
3#undef EXTERN
4#define EXTERN extern
5
6#include "./napa.h"
7#include "./proto.h"
8
9
10/* *** In this file: ************************************************************************************************************ */
11
12/* char *get_a_line(char *buf, unsigned long *nl,FILE *fp, unsigned long *mlin, const unsigned long *mfil) */
13
14/* double GCD(double n1, double n2) */
15/* double LCM(double n1, double n2) */
16
17/* int test_endianness(void) */
18/* int verify_rshift(void) */
19
20/* long f2printf(FILE *fp1, FILE *fp2, char *fmt, ...) */
21/* long process_condition(char *str, const unsigned long *mlin, const unsigned long *mfil) */
22
23/* void build_condition(char *cond, const unsigned long *ml, const unsigned long *mf) */
24/* void cat_file(const char *fnam, const char *type, long command, const unsigned long *mlin, const unsigned long *mfil) */
25/* void check_array_usage(void) */
26/* void check_directive_usage(void) */
27/* void check_record_usage(void) */
28/* void collect_export_definitions(void) */
29/* void compact_segment(void) */
30/* void complete_directives(void) */
31/* void default_control_variables(void) */
32/* void determine_output_segment_rate(void) */
33/* void determine_segment_processing_rate(void) */
34/* void determine_simulation_rate(void) */
35/* void expand_dump_definitions(void) */
36/* void expand_IO_definitions(void) */
37/* void expand_records(void) */
38/* void expand_string_variables(void) */
39/* void expand_update_definitions(void) */
40/* void last_message(void) */
41/* void print_error_location(const char *type, const unsigned long *mlin, const unsigned long *mfil) */
42/* void print_info_location(const char *type, const unsigned long *mlin, const unsigned long *mfil) */
43/* void print_limits(void) */
44/* void print_location(const unsigned long *mlin, const unsigned long *mfil) */
45/* void print_problem_location(const char *type, const unsigned long *mlin, const unsigned long *mfil, const char *kind) */
46/* void print_warning_location(const char *type, const unsigned long *mlin, const unsigned long *mfil) */
47/* void process_aliases(void) */
48/* void process_error_if_any(void) */
49/* void wall_clock(void) */
50
51
52/* ****************************************************************************************************************************** */
53
54/* output the current limits of the compiler set in file "napa.h" */
55
56void print_limits(void) {
57 (void) fprintf(STDERR, "\n\nCURRENT LIMITATION OF THE NAPA COMPILER:\n\n" );
58 (void) fprintf(STDERR, " max number of nodes = %6ld\n", MAXNODES );
59 (void) fprintf(STDERR, " max number of variables = %6ld\n", MAXVARS );
60 (void) fprintf(STDERR, " max number of updates = %6ld\n", MAXUPDATES );
61 (void) fprintf(STDERR, " max number of arrays of pointers = %6ld\n", MAXRECORDS );
62 (void) fprintf(STDERR, " max number of instantiation of cells = %6ld\n", MAXINSTANCES );
63 (void) fprintf(STDERR, " max number of declarations = %6ld\n", MAXDECLARES );
64 (void) fprintf(STDERR, " max number of common declarations = %6ld\n", MAXDECLARECOMMONS);
65 (void) fprintf(STDERR, " max number of opcodes = %6ld\n", MAXOPCODES );
66 (void) fprintf(STDERR, " max number of cell file names recorded = %6ld\n", MAXFILECELLS );
67 (void) fprintf(STDERR, " max number of functions to be recorded = %6ld\n", MAXFUNCTIONS );
68 (void) fprintf(STDERR, " max number of options to be recorded = %6ld\n", MAXOPTIONS );
69 (void) fprintf(STDERR, " max number of user's defined functions = %6ld\n", MAXUSERTOOLS );
70 (void) fprintf(STDERR, " max number of postprocessing functions = %6ld\n", MAXPOSTS );
71 (void) fprintf(STDERR, " max number of inject to nodes = %6ld\n", MAXINJECTS );
72 (void) fprintf(STDERR, " max number of IO streams = %6ld\n", MAXIOS );
73 (void) fprintf(STDERR, " max number of open files (simulation) = %6ld\n", MAXFILES );
74 (void) fprintf(STDERR, " max number of headers = %6ld\n", MAXHEADERS );
75 (void) fprintf(STDERR, " max number of directives = %6ld\n", MAXDIRS );
76 (void) fprintf(STDERR, " max number of cell parameters = %6ld\n", MAXPARMS );
77 (void) fprintf(STDERR, " max number of nodes stuck to a value = %6ld\n", MAXSTUCKS );
78 (void) fprintf(STDERR, " max number of command line parameters = %6ld\n", MAXCMDLINES );
79 (void) fprintf(STDERR, " max number of aliases = %6ld\n", MAXALIASES );
80 (void) fprintf(STDERR, " max number of arrays = %6ld\n", MAXARRAYS );
81 (void) fprintf(STDERR, " max number of simulation segments = %6ld\n", MAXSEGMENTS );
82 (void) fprintf(STDERR, " max number of exported variables = %6ld\n\n", MAXEXPORTS );
83 (void) fprintf(STDERR, " max depth for cell hierarchy = %6ld\n\n", MAXDEPTH );
84 (void) fprintf(STDERR, " max length of strings and tokens = %6ld\n", STRLENGTH );
85 (void) fprintf(STDERR, " max length of instructions = %6ld\n\n", LINLENGTH );
86 (void) fprintf(STDERR, "These limitations can be changed by a new compilation of the\n" );
87 (void) fprintf(STDERR, "sources after reworking the limits in source file 'napa.h'. \n" );
88 (void) fprintf(STDERR, "Please contact the author, yves.leduc.be@gmail.com \n\n" );
89
90 return;
91}
92
93
94/* Read a line from file pointed by 'fp', fill the string buffer 'buf' and return the number of lines read by this reading */
95/* process through pointer 'nl'. */
96
97/* This function performs all important line preprocessing: it cleans end of line, process continuation line, tracks line */
98/* numbering, expand iterative identifiers and update the 'mlin', 'mfil' documentation counters. */
99
100char *get_a_line(char *buf, unsigned long *nl, FILE *fp, unsigned long *mlin, const unsigned long *mfil) {
101 static char tok[LINLENGTH + 1L] = {'\0'};
102 static char *p = (char*) NULL;
103 long len;
104 int continue_on_next_line;
105 (void) strcpy(buf, "");
106 *nl = 0UL;
107 do {
108 p = fgets(tok, LINLENGTH, fp); /* read a line from the input file */
109 if ((char*) NULL == p) {
110 if (0UL < *nl) {
111 *mlin = *mlin + *nl;
112 print_error_location("continuation line", mlin, mfil);
113 (void) fprintf(STDERR, " end of file is detected although a new line was expected\n");
115 }
116 break;
117 }
118 clean_line(tok); /* clear comments, process tabs, end of line spaces */
119 len = LENGTH(tok);
120 (*nl)++;
121 if ((1UL < *nl) && (0L == len)) { /* many subtle errors undetected if authorized!!! */
122 *mlin = *mlin + *nl;
123 print_error_location("continuation line", mlin, mfil);
124 (void) fprintf(STDERR, " 'all blank' or 'all comment' lines are not allowed inside an instruction\n");
126 }
127 if (3L <= len) {
128 continue_on_next_line = (int) (('.' == tok[len-3L]) && ('.' == tok[len-2L]) && ('.' == tok[len-1L]));
129 /* could be true or false!*/
130 } else {
131 continue_on_next_line = false;
132 }
133 if (continue_on_next_line) {
134 tok[len-3L] = ' ';
135 tok[len-2L] = '\0';
136 clean_line(tok);
137 }
138 if ((LENGTH(buf) + LENGTH(tok)) > LINLENGTH) {
139 *mlin = *mlin + *nl;
140 print_error_location("instruction", mlin, mfil);
141 (void) fprintf(STDERR, " the length of instruction exceeds maximum length (%ld)\n", LINLENGTH);
142 print_limits();
144 }
145 if (1L < *nl) { /* insert blank before concatenating instr. lines */
146 (void) strcat(buf, " ");
147 }
148 (void) strcat(buf, tok);
149 } while (continue_on_next_line);
150 expand_iterative_identifiers(buf, mlin, mfil); /* iterative identifiers by extension */
151 return p;
152}
153
154
155/* Print in two output streams if stream is not 'NULL' */
156
157long f2printf(FILE *fp1, FILE *fp2, char *fmt, ...) {
158 va_list argp;
159 long n1 = 0L;
160 long n2 = 0L;
161 if ((FILE*) NULL != fp1) {
162 va_start(argp, fmt);
163 n1 = vfprintf(fp1, fmt, argp);
164 va_end(argp);
165 }
166 if (fp1 == fp2) {
167 return n1;
168 }
169 if ((FILE*) NULL != fp2) {
170 va_start(argp, fmt);
171 n2 = vfprintf(fp2, fmt, argp);
172 va_end(argp);
173 }
174 return MAX(n1, n2);
175}
176
177
178/* "default_control_variables" sets the default value of the variable controlling the NAPA simulation. */
179
180/* Several flags have been initialized during the process of the command line process (Verbose_Flag, Expand_Flag, List_Flag) */
181/* There is a tricky process to determine the length corresponding to default formats */
182/* for 'doub_format', 'int_format' and 'string_format' */
183
185 long i;
186 char tok[STRLENGTH] = {'\0'};
187 NAPA_Compile_Start = ((double) clock()) / ((double) CLOCKS_PER_SEC);
188 if (0 != atexit(last_message)) { /* register exit function */
189 print_error_location("control variables", NULL, NULL);
190 (void) fprintf(STDERR, " Registering 'last_message()' did not succeed\n");
191 }
192 (void) strcpy(Title_String, ""); /* default of title: empty string */
193 for (i = 0L; i < MAXCOMMENTS; i++) {
194 (void) strcpy(Comment_String[i], ""); /* default of comment: empty string */
195 }
196 (void) strcpy(Cmdline_String, ""); /* default of command_line parms */
197 (void) strcpy(I_Format, DEFAULT_I_FORMAT); /* default of output digital format */
198 (void) strcpy(X_Format, DEFAULT_X_FORMAT); /* default of output digital format (hexa) */
199 (void) strcpy(R_Format, DEFAULT_R_FORMAT); /* default of output analog format */
200 (void) strcpy(S_Format, DEFAULT_S_FORMAT); /* default of output string format */
201 (void) strcpy(Last_Instruction, ""); /* to trace instruction flow */
202 (void) strcpy(Last_Postprocess, ""); /* to trace postprocess flow */
203 Sampling_List.frequency = 1.0; /* default of operating frequency */
204 Seed_List.rndseed = 0L; /* default of seed for random number */
205 Interlude_List.number1 = 0L; /* default of interlude number */
206 Interlude_List.number2 = 0L; /* default of interlude number */
207 Loop_Flag = true;
208 Periodic_Flag = true;
209 Synchro_Flag = true;
210 Antithetic_Flag = false;
211 Array_Flag = false;
212 Assert_Flag = false;
213 Call_Flag = false;
214 Cmdline_Flag = false;
215 Comment_Flag = false;
216 Debug_Flag = false;
217 Delayed_Flag = false;
218 Directive_Flag = false;
219 Drop_Flag = false;
220 Dump_Flag = false;
221 Error_Flag = false;
222 Export_Flag = false;
223 Fs_Ext_Flag = false;
224 Fs_Flag = false;
225 Function_Flag = false;
226 Gateway_Flag = false;
227 Hierarchy_Flag = false;
228 Inject_Flag = false;
229 Input_Flag = false;
230 Interlude_Flag1 = false;
231 Interlude_Flag2 = false;
232 Interlude_Flag3 = false;
233 Interpolate_Flag = false;
234 Load_Flag = false;
235 Multdelay_Flag = false;
236 Option_Flag = false;
237 Output_Flag = false;
238 Ping_Flag = false;
239 Pointer_Flag = false;
240 Post_Flag = false;
241 Seed_Flag = false;
242 Stuck_Flag = false;
243 Terminate_Flag = false;
244 Title_Flag = false;
245 Tool_Flag = false;
246 Tool_Index_Flag = false;
247 Ts_Flag = false;
248 Ts_Ext_Flag = false;
249 Update_Flag = false;
250 User_Flag = false;
251 UserTool_Flag = false;
252 Warning_Flag = false;
253 Num_Aliases = 0L;
254 Num_Arrays = 0L;
255 Num_Asserts = 0L;
256 Num_Calls = 0L;
257 Num_Cells = 0L;
258 Num_Cmdlines = 0L;
259 Num_Comments = 0L;
261 Num_Consts = 0L;
262 Num_Creates = 0L;
263 Num_Debugs = 0L;
264 Num_Declares = 0L;
265 Num_Delays = 0L;
266 Max_Depth = 0L;
267 Num_Directives = 0L;
268 Num_Exports = 0L;
269 Num_FileCells = 0L;
270 Num_Functions = 0L;
271 Num_Generators = 0L;
272 Num_Groups = 0L;
273 Num_Headers = 0L;
274 Num_Inits = 0L;
275 Num_Injects = 0L;
276 Num_Instances = 0L;
277 Num_IOs = 0L;
278 Num_Macros = 0L;
279 Num_Nodes = 0L;
280 Num_Nulls = 0L;
281 Num_Opcodes = 0L;
282 Num_Posts = 0L;
283 Num_Records = 0L;
284 Num_Redefs = 0L;
285 Num_Restarts = 0L;
286 Num_Segments = 0L;
287 Num_Stucks = 0L;
288 Num_Tools = 0L;
289 Num_Updates = 0L;
290 Num_UserTools = 0L;
291 Num_Vars = 0L;
292 Num_Voids = 0L;
293 (void) snprintf(Condition_Assign, (size_t) (LINLENGTH-1L), "%s", "");
294 (void) snprintf(Export0_List_String, (size_t) (LINLENGTH-1L), "%s", "");
295 (void) snprintf(Export0_Head_String, (size_t) (LINLENGTH-1L), "%s", "");
296 (void) snprintf(tok, (size_t) (STRLENGTH-1L), I_Format, (NAPA_DIGITAL_TYPE) 1LL); /* eff. string len resulting of this format */
297 (void) snprintf(I_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok)-1L);
298 (void) snprintf(tok, (size_t) (STRLENGTH-1L), X_Format, (NAPA_DIGITAL_TYPE) 1LL); /* eff. string len resulting of this format */
299 (void) snprintf(X_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok)-1L);
300 (void) snprintf(tok, (size_t) (STRLENGTH-1L), R_Format, (NAPA_ANALOG_TYPE) 1.0); /* eff. string len resulting of this format */
301 (void) snprintf(R_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok)-1L);
302 (void) strcpy(S_String_Format, S_Format); /* eff. string len resulting of this format */
303 return;
304}
305
306
307/* This function adds directive 'NO_BANNER' if 'STRICTLY_NO_BANNER' has been defined, */
308/* as 'STRICTLY_NO_BANNER' should imply 'NO_BANNER' */
309
311 if ((UNDEFINED == directive_id("NO_BANNER")) && (UNDEFINED != directive_id("STRICTLY_NO_BANNER"))) {
312 strcpy_alloc(&(Directive_List[Num_Directives].name ), "NO_BANNER", NULL, NULL);
313 strcpy_alloc(&(Directive_List[Num_Directives].parms), "", NULL, NULL);
314 strcpy_alloc(&(Directive_List[Num_Directives].value), "", NULL, NULL);
315 increment_directive_number("directive");
316 }
317 return;
318}
319
320
321/* This function allows indirection inside string variables to update title. */
322
324 long i, len;
325 char *str = (char*) NULL;
326 char tok[LINLENGTH] = {'\0'};
327 if (0L < Num_Vars) {
328 for (i = 0L; i < Num_Vars; i++) {
329 if (STRING_DATA_TYPE == Var_List[i].type) {
330 (void) strcpy(tok, Var_List[i].value);
332 if (0 != strcmp(tok, Var_List[i].value)) {
333 strcpy_realloc(&(Var_List[i].value), tok, Var_List[i].mline, Var_List[i].mfile);
334 }
335 }
336 str = Var_List[i].value;
337 do {
338 str = get_token(str, tok, true);
339 if (0 == strcmp(tok, "when")) {
340 print_error_location("var", Var_List[i].mline, Var_List[i].mfile);
341 (void) fprintf(STDERR, " the definition of a variable cannot be conditioned by an event\n");
342 break;
343 }
344 } while (ISNOTEMPTY(tok));
345 }
346 }
347 expand_indirections(Title_String); /* title is always expanded after variables */
348 (void) strcpy(Short_Title_String, Title_String);
349 i = 0L;
350 while ('\0' != Title_String[i]) { /* extract first line of title */
351 if (('/' == Title_String[i]) && ('n' == Title_String[i+1L])) { /* the '\' was converted in '/' */
352 Short_Title_String[i] = '\0';
353 Title_String[i] = '\\'; /* restore the '\' */
354 } else {
356 }
357 i++;
358 }
359 if (Comment_Flag) {
360 len = 0L;
361 for (i = 0L; i < Num_Comments; i++) {
362 expand_indirections(Comment_String[i]); /* comment is always expanded after variables */
363 len = MAX(LENGTH(Comment_String[i]), len);
364 }
365 len += 1L;
366 for (i = 0L; i < Num_Comments; i++) {
367 (void) strcpy(tok, Comment_String[i]);
368 (void) snprintf(Comment_String[i], (size_t) (LINLENGTH-1L), "%s%*s", tok, (int) (len-LENGTH(tok))," ");
369 }
370 }
371 return;
372}
373
374
375/* Expand array of pointers definition, record must be sorted before this processing! */
376
377void expand_records(void) {
378 int n;
379 int nflag, pflag;
380 long i, a, sz, nr, nc;
381 long first;
382 char *s = (char*) NULL;
383 char *t1 = (char*) NULL;
384 char *t2 = (char*) NULL;
385 char sgn[2] = {'\0'};
386 char tok[STRLENGTH] = {'\0'};
387 char tok1[STRLENGTH] = {'\0'};
388 char tok2[STRLENGTH] = {'\0'};
389 char buf[LINLENGTH] = {'\0'};
390 char buf1[LINLENGTH] = {'\0'};
391 char buf2[LINLENGTH] = {'\0'};
392 if (0L == Num_Records) {
393 return;
394 }
395 for (i = 0L; i < Num_Records; i++) {
396 (void) strcpy(buf, "");
397 s = Record_List[i].list1; /* list of parameters */
398 sz = Record_List[i].size;
399 nr = Record_List[i].nrow;
400 nc = Record_List[i].ncol;
401 first = true;
402 for (;;) {
403 s = get_sign_and_token(s, sgn, tok);
404 if (ISEMPTY(tok)) {
405 break;
406 }
407 a = record_id(tok);
408 if (UNDEFINED == a) { /* atom of the array */
409 (void) strcat(buf, sgn);
410 (void) strcat(buf, tok);
411 (void) strcat(buf, " ");
412 continue;
413 }
414 (void) strcat(buf, Record_List[a].list1); /* expand array */
415 (void) strcat(buf, " ");
416 if (0L == Record_List[a].size) {
417 sz = 0L; /* array with undefined size */
418 nr = 0L;
419 nc = 0L;
420 } else {
421 sz += Record_List[a].size - 1L;
422 if ((!first) && (nc != Record_List[a].ncol)) { /* not rectangular */
423 nr = 1L;
424 nc = sz;
425 } else {
426 if (!first) {
427 nr++;
428 }
429 nc = Record_List[a].ncol;
430 }
431 first = false;
432 }
433 }
434 clean_line(buf);
435 strcpy_realloc(&(Record_List[i].list1), buf, Record_List[i].mline, Record_List[i].mfile);
436 strcpy_realloc(&(Record_List[i].list2), buf, Record_List[i].mline, Record_List[i].mfile);
437 Record_List[i].size = sz; /* new size */
438 Record_List[i].nrow = nr;
439 if (0L != nr) {
440 Record_List[i].ncol = sz / nr; /* keep dimensions to 2 by flattening subarrays */
441 } else {
442 Record_List[i].ncol = sz;
443 }
444 }
445 for (i = 0L; i < Num_Records; i++) {
446 s = Record_List[i].list1; /* list of parameters */
447 n = 0;
448 (void) strcpy(buf1, "");
449 (void) strcpy(buf2, "");
450 nflag = true;
451 pflag = true;
452 for (;;) {
453
454 s = get_sign_and_token(s, sgn, tok1);
455 (void) strcpy(tok, sgn);
456 (void) strcat(tok, tok1);
457
458 if (ISEMPTY(tok)) {
459 break;
460 }
461 (void) strcpy(tok1, tok);
462 (void) strcpy(tok2, tok);
463 t1 = strstr(tok1, "::");
464 t2 = strstr(tok2, "::");
465 if ((char*) NULL != t1) {
466 pflag = false;
467 nflag = nflag && true;
468 (void) strcpy(tok1, t1+2); /* passing by name, extract var for verification */
469 clean_line(tok1);
470 (void) strcat(buf1, tok1);
471 (void) strcat(buf1, " " );
472 *t2 = '\0';
473 (void) strcat(buf2, tok2);
474 (void) strcat(buf2, " " );
475 } else { /* passing by position */
476 nflag = false;
477 pflag = pflag && true;
478 clean_line(tok1);
479 (void) strcat(buf1, tok1);
480 (void) strcat(buf1, " " );
481 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%d ", n);
482 (void) strcat(buf2, tok2);
483 n++;
484 }
485 }
486 if (!(pflag || nflag)) {
487 print_error_location("record", Record_List[i].mline, Record_List[i].mfile);
488 (void) fprintf(STDERR, " inconsistant parameters passing: by position or by name?\n");
489 }
490 Record_List[i].nflag = nflag;
491 Record_List[i].pflag = pflag;
492 clean_line(buf1);
493 clean_line(buf2);
494 strcpy_realloc(&(Record_List[i].list1), buf1, Record_List[i].mline, Record_List[i].mfile);
495 strcpy_realloc(&(Record_List[i].list2), buf2, Record_List[i].mline, Record_List[i].mfile);
496 }
497 return;
498}
499
500
501/* Scan nodes and arrays to tag array usage */
502
504 long out;
505 long kd, m;
506 char *s = (char*) NULL;
507 char sgn[2] = {'\0'};
508 char tok1[STRLENGTH] = {'\0'};
509 for (out = 0L; out < Num_Nodes; out++) {
510 s = Node_List[out].value;
511 kd = Node_List[out].kind;
512 switch (kd) {
513 case ITOOL_KIND :
514 case DTOOL_KIND :
515 case IUSER_KIND :
516 case DUSER_KIND :
517 case DALGEBRA_KIND :
518 case IALGEBRA_KIND :
519 case ALGEBRA_KIND :
520 case TEST_KIND :
521 case CONST_KIND :
522 case DC_KIND :
523 for (;;) {
524 s = get_token(s, tok1, true);
525 if (ISEMPTY(tok1)) {
526 break;
527 }
528 m = array_name_id(tok1);
529 if (UNDEFINED != m) { /* detect use of array by file */
530 Array_List[m].used = true;
531 }
532 }
533 break;
534 case RAM_KIND :
535 case RAM2_KIND :
536 case ROM_KIND :
537 case ROM2_KIND :
538 s = get_sign_and_token(s, sgn, tok1);
539 m = array_id(tok1);
540 if (UNDEFINED != m) { /* detect use of array by name */
541 Array_List[m].used = true;
542 }
543 break;
544 default:
545 break;
546 }
547 }
548 for (m = 0L; m < Num_Arrays; m++) {
549 if ((Array_List[m].used) && (UNKNOWN_KIND != Array_List[m].kind)) {
550 Array_Flag = true;
551 continue;
552 }
553 }
554 return;
555}
556
557
558/* Scan nodes and records to tag record usage */
559
561 long out;
562 long kd, m;
563 char *s = (char*) NULL;
564 char *s1 = (char*) NULL;
565 char sgn[2] = {'\0'};
566 char tok1[STRLENGTH] = {'\0'};
567 for (out = 0L; out < Num_Nodes; out++) {
568 s = Node_List[out].value;
569 kd = Node_List[out].kind;
570 switch (kd) {
571 case ITOOL_KIND :
572 case DTOOL_KIND :
573 case IUSER_KIND :
574 case DUSER_KIND :
575 for (;;) {
576 s = get_token(s, tok1, false);
577 if (ISEMPTY(tok1)) {
578 break;
579 }
580 m = record_id(tok1);
581 if (UNDEFINED != m) { /* detect use of array by name */
582 Record_List[m].used = true;
583 }
584 }
585 break;
586 case DALGEBRA_KIND :
587 case IALGEBRA_KIND :
588 case ALGEBRA_KIND :
589 case CONST_KIND :
590 case DC_KIND :
591 case TEST_KIND :
592 for (;;) {
593 s = get_token(s, tok1, true);
594 if (ISEMPTY(tok1)) {
595 break;
596 }
597 m = record_id(tok1);
598 if (UNDEFINED != m) { /* detect use of array by name */
599 Record_List[m].used = true;
600 }
601 }
602 break;
603 default:
604 break;
605 }
606 }
607 for (out = 0L; out < Num_Records; out++) {
608 s1 = Record_List[out].list1;
609 for (;;) {
610 s1 = get_sign_and_token(s1, sgn, tok1);
611 if (ISEMPTY(tok1)) {
612 break;
613 }
614 m = var_id(tok1);
615 if (UNDEFINED != m) {
616 Var_List[m].used = true;
617 }
618 }
619 }
620 Pointer_Flag = false;
621 for (out = 0L; out < Num_Records; out++) {
622 if (Record_List[out].used) {
623 Pointer_Flag = true;
624 break;
625 }
626 }
627 return;
628}
629
630
632 long d;
633 if ((0 >= Num_Directives) || (Cmdline_Flag)) { /* no directive in netlist, or standalone simulator */
634 return;
635 }
636 mark_directives(); /* inspect napa netlist for macro usage */
637 for (d = 0L; d < Num_Directives; d++) { /* directives used in the C file produced by NAPA */
638 if ((0 == strcmp(Directive_List[d].name, "TIME_OFFSET" )) || (0 == strcmp(Directive_List[d].name, "JITTER" ))
639 || (0 == strcmp(Directive_List[d].name, "STRICTLY_NO_BANNER")) || (0 == strcmp(Directive_List[d].name, "NO_BANNER"))
640 || (0 == strcmp(Directive_List[d].name, "NO_TIME_OUTPUT" )) || (0 == strcmp(Directive_List[d].name, "VERBOSE" ))
641 || (0 == strcmp(Directive_List[d].name, "NAPA_EXIT_STATUS" )) ) {
642 Directive_List[d].used = true;
643 continue;
644 }
645 if (Assert_Flag) {
646 if (0 == strcmp(Directive_List[d].name, "NO_ASSERT" )) {
647 Directive_List[d].used = true;
648 continue;
649 }
650 }
651 if (Dump_Flag) {
652 if ((0 == strcmp(Directive_List[d].name, "DUMP" )) || (0 == strcmp(Directive_List[d].name, "NO_GLOBAL" ))
653 || (0 == strcmp(Directive_List[d].name, "NO_ARRAY" )) || (0 == strcmp(Directive_List[d].name, "NO_VAR" ))
654 || (0 == strcmp(Directive_List[d].name, "NO_NODE" ))) {
655 Directive_List[d].used = true;
656 continue;
657 }
658 }
659 if (Directive_List[d].function) { /* this is a macro function, not a true directive */
660 Directive_List[d].used = true;
661 continue;
662 }
663 Directive_Flag = true;
664 }
665 return;
666}
667
668
669/* Scan and collect the definition of export variables */
670
672 long e, n, m;
673 long first;
674 char *str = (char*) NULL;
675 char tok1[STRLENGTH] = {'\0'};
676 char tok2[STRLENGTH] = {'\0'};
677 char sgn[2] = {'\0'};
678 if (!Export_Flag) {
679 return;
680 }
681 first = true;
682 (void) strcpy(E_Format, ""); /* set E_Format with empty string */
683 (void) strcpy(V_Format, ""); /* set V_Format with empty string */
684 for (e = 0L; e < Num_Exports; e++) { /* scan each export instruction to collect names */
685 str = Export_List[e].name;
686 for (;;) { /* scan export list, identifier after identifier */
687 str = get_sign_and_token(str, sgn, tok1);
688 if (ISEMPTY(tok1)) {
689 break; /* end of list */
690 }
691 if (!is_an_identifier(tok1)) {
692 print_error_location("export", Export_List[e].mline, Export_List[e].mfile );
693 (void) fprintf(STDERR, " export node or variable <%s> is not a NAPA identifier\n", tok1);
694 process_node_error(tok1);
696 return;
697 }
698 if (ISNOTEMPTY(sgn)) {
699 print_error_location("export", Export_List[e].mline, Export_List[e].mfile );
700 (void) fprintf(STDERR, " export node or variable <%s> cannot be signed\n", tok1);
701 return;
702 }
703 n = node_id(tok1);
704 if (UNDEFINED != n) { /* is it a node ? */
705 Node_List[n].used = true;
706 if (ANALOG_DATA_TYPE == Node_List[n].type) {
707 (void) strcat(E_Format, " ");
708 (void) strcat(E_Format, R_FORMAT_V);
709 if (first) {
710 (void) strcat(V_Format, R_FORMAT_V);
711 }
712 } else {
713 (void) strcat(E_Format, " ");
714 (void) strcat(E_Format, I_FORMAT_V);
715 if (first) {
716 (void) strcat(V_Format, I_FORMAT_V);
717 }
718 }
719 }
720 m = var_id(tok1); /* is it a variable ? */
721 if (UNDEFINED != m) {
722 Var_List[m].used = true;
723 if (ANALOG_DATA_TYPE == Var_List[m].type) {
724 (void) strcat(E_Format, " ");
725 (void) strcat(E_Format, R_FORMAT_V);
726 if (first) {
727 (void) strcat(V_Format, R_FORMAT_V);
728 }
729 } else if (DIGITAL_DATA_TYPE == Var_List[m].type) {
730 (void) strcat(E_Format, " ");
731 (void) strcat(E_Format, I_FORMAT_V);
732 if (first) {
733 (void) strcat(V_Format, I_FORMAT_V);
734 }
735 } else {
736 print_error_location("export", Export_List[e].mline, Export_List[e].mfile);
737 (void) fprintf(STDERR, " a string variable cannot be exported <%s>", tok1);
738 }
739 }
740 if ((UNDEFINED == n) && (UNDEFINED == m)) { /* an identifier known by NAPA */
741 if (DIGITAL_DATA_TYPE == get_type(tok1)) {
742 (void) strcat(E_Format, " ");
743 (void) strcat(E_Format, I_FORMAT_V);
744 if (first) {
745 (void) strcat(V_Format, I_FORMAT_V);
746 }
747 }
748 if (ANALOG_DATA_TYPE == get_type(tok1)) {
749 (void) strcat(E_Format, " ");
750 (void) strcat(E_Format, R_FORMAT_V);
751 if (first) {
752 (void) strcat(V_Format, R_FORMAT_V);
753 }
754 }
755 }
756 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), S_FORMAT_V, tok1);
757 (void) strcat(Export0_Head_String, tok2);
758 (void) build_name("", tok1, RIGHT_VALUE);
759 (void) strcat(Export0_List_String, tok1);
760 (void) strcat(Export0_List_String, ", ");
761 if (first) {
764 }
765 first = false;
766 }
767 }
768 Export0_List_String[LENGTH(Export0_List_String) - 2L] = '\0'; /* suppress last ", " */
769 Export1_List_String[LENGTH(Export1_List_String) - 2L] = '\0'; /* suppress last ", " */
770 return;
771}
772
773
774/* Fill empty definition with the corresponding variable definition */
775/* during the process, extract event condition */
776
778 long out;
779 long v;
780 char *str = (char*) NULL;
781 char *nam = (char*) NULL;
782 char *s = (char*) NULL;
783 char tok[STRLENGTH] = {'\0'};
784 int flag;
785 for (out = 0L; out < Num_Updates; out++) {
786 nam = Update_List[out].name; /* search also for alias */
787 if ((0 == strncmp(nam, "$call$", (size_t) 6))
788 || (0 == strncmp(nam, "$null$", (size_t) 6))
789 || (0 == strncmp(nam, "$restart$", (size_t) 9))) {
790 strcpy_alloc(&(Update_List[out].condition), "", Update_List[out].mline, Update_List[out].mfile);
791 continue;
792 }
793 if ((UNDEFINED == var_id(nam)) && (0 != strncmp(nam, "$assert$", (size_t) 8))) {
794 print_error_location("update", Update_List[out].mline, Update_List[out].mfile);
795 (void) fprintf(STDERR, " variable to be updated <%s> does not exist!\n", nam );
797 continue;
798 }
799 if (STRING_DATA_TYPE == Var_List[var_id(nam)].type) {
800 print_error_location("update", Update_List[out].mline, Update_List[out].mfile);
801 (void) fprintf(STDERR, " string <%s>: a string cannot be updated!", nam );
802 continue;
803 }
804 str = Update_List[out].value;
805 do {
806 s = str; /* remember location of 'when' token */
807 str = get_token(str, tok, true);
808 if (0 == strcmp(tok, "when")) {
809 if (Update_List[out].event) {
810 print_error_location("event", Update_List[out].mline, Update_List[out].mfile);
811 (void) fprintf(STDERR, " an event cannot be conditioned\n");
812 continue;
813 }
814 break;
815 }
816 } while (ISNOTEMPTY(tok));
817 flag = process_condition(str, Update_List[out].mline, Update_List[out].mfile);
818 *(s) = '\0'; /* split in value and condition */
819
820 if (flag) {
821 strcpy_alloc(&(Update_List[out].condition), str, Update_List[out].mline, Update_List[out].mfile);
822 } else {
823 strcpy_alloc(&(Update_List[out].condition), "", Update_List[out].mline, Update_List[out].mfile);
824 }
825 clean_line(Update_List[out].value);
826 /* if update value is empty, use the definition of the corresponding variable */
827 if (ISEMPTY(Update_List[out].value)) {
828 v = var_id(Update_List[out].name);
829 if (UNDEFINED != v) {
830 strcpy_realloc(&(Update_List[out].value), Var_List[v].value, Update_List[out].mline, Update_List[out].mfile);
831 } else { /* should never occur */
832 print_error_location("update", Update_List[out].mline, Update_List[out].mfile);
833 (void) fprintf(STDERR, " no update expansion, as variable to be updated does not exist\n");
834 }
835 }
836 }
837 return;
838}
839
840
841/* IO definitions may be completed by a "when" keyword followed by a combination of events */
842/* This function expands this definition */
843
845 long out;
846 char *str = (char*) NULL;
847 char *s = (char*) NULL;
848 char tok[STRLENGTH] = {'\0'};
849 int flag;
850 for (out = 0L; out < Num_IOs; out++) {
851 if (INPUT_TYPE == IO_List[out].type) {
852 str = IO_List[out].element;
853 do {
854 str = get_token(str, tok, true);
855 if (0 == strcmp(tok, "when")) {
856 print_error_location("input", IO_List[out].mline, IO_List[out].mfile);
857 (void) fprintf(STDERR, " this instruction cannot be conditioned by an event\n");
858 break;
859 }
860 } while (ISNOTEMPTY(tok));
861 continue;
862 }
863 if (OUTPUT_TYPE == IO_List[out].type) {
864 str = IO_List[out].element;
865 do {
866 s = str; /* remember location of 'when' token */
867 str = get_token(str, tok, true);
868 if (0 == strcmp(tok, "when")) {
869 break;
870 }
871 } while (ISNOTEMPTY(tok));
872 flag = process_condition(str, IO_List[out].mline, IO_List[out].mfile);
873 *(s) = '\0'; /* split in value and condition */
874 if (flag) {
875 strcpy_alloc(&(IO_List[out].condition), str, IO_List[out].mline, IO_List[out].mfile);
876 } else {
877 strcpy_alloc(&(IO_List[out].condition), "", IO_List[out].mline, IO_List[out].mfile);
878 }
879 }
880 }
881 return;
882}
883
884
885/* "dump" may be completed by a "when" keyword followed by a combination of events. This function expands this definition. */
886
888 char *str = (char*) NULL;
889 char tok[STRLENGTH] = {'\0'};
890 if (!Dump_Flag) {
891 return;
892 }
893 str = Dump_List.condition;
894 if (0 == strcmp(str, "false")) {
895 strcpy_alloc(&(Dump_List.condition), "false", Dump_List.mline, Dump_List.mfile);
896 return;
897 }
898 if ((0 == strcmp(str, "true")) || ISEMPTY(str)) {
899 strcpy_alloc(&(Dump_List.condition), "true", Dump_List.mline, Dump_List.mfile);
900 return;
901 }
902 str = get_token(str, tok, true);
903 if (ISEMPTY(tok) || (0 != strcmp(tok, "when"))) {
904 print_error_location("dump", Dump_List.mline, Dump_List.mfile);
905 (void) fprintf(STDERR, " this instruction must be conditioned by an event\n");
906 return;
907 }
908 (void) process_condition(str, Dump_List.mline, Dump_List.mfile);
909 strcpy_alloc(&(Dump_List.condition), str, Dump_List.mline, Dump_List.mfile);
910 return;
911}
912
913
914/* This function analyses and processes condition following a "when" keyword. It is called by the two functions above. */
915
916long process_condition(char *str, const unsigned long *mlin, const unsigned long *mfil) {
917 long in;
918 char *s = (char*) NULL;
919 char sgn[2] = {'\0'};
920 char brc[3] = {'\0'};
921 char tok[LINLENGTH] = {'\0'};
922 int cond;
923 cond = false;
924 if (ISEMPTY(str)) {
925 return false;
926 }
927 C_syntax_checker(str, mlin, mfil);
928 while (ISNOTEMPTY(str)) {
929 s = str;
930 str = get_token_between_braces(str, brc, tok);
931 if ((0 == strcmp(brc, "()")) && (0 == strcmp(tok, "new"))) {
932 str = s;
933 }
934 str = get_sign_and_token(str, sgn, tok);
935 in = node_id(tok);
936 if (UNDEFINED != in) {
937 print_error_location("condition", mlin, mfil);
938 (void) fprintf(STDERR, "<%s> cannot be a node but an event\n", tok);
939 break;
940 }
941 in = var_id(tok);
942 if ((UNDEFINED == in) && (isalpha((int) *tok))) {
943 print_error_location("condition", mlin, mfil);
944 (void) fprintf(STDERR, "<%s>? Only events and operators on boolean are allowed in a condition\n", tok);
945 break;
946 }
947 if ((UNDEFINED != in) && (!Var_List[in].event)) {
948 print_error_location("condition", mlin, mfil);
949 (void) fprintf(STDERR, " <%s> cannot be a variable but an event\n", tok);
950 break;
951 }
952 cond = true;
953 }
954 return cond;
955}
956
957
958void build_condition(char *cond, const unsigned long *mlin, const unsigned long *mfil) {
959 long in;
960 char sgn[2] = {'\0'};
961 char tok[STRLENGTH] = {'\0'};
962 char buf1[LINLENGTH] = {'\0'};
963 char buf2[LINLENGTH] = {'\0'};
964 char *str = (char*) NULL;
965 str = cond;
966 if (ISEMPTY(str)) {
967 print_error_location("condition", mlin, mfil);
968 (void) fprintf(STDERR, " syntax error in condition <%s>, event is missing\n", str);
969 return;
970 }
971 (void) fprintf(STDOUT, " if ( ");
972 while (ISNOTEMPTY(str)) {
973 str = get_sign_and_token(str, sgn, tok);
974 in = var_id(tok);
975 if (UNDEFINED == in) {
976 (void) strcpy(buf1, buf2);
977 if ((0 == strcmp("&&", tok)) || (0 == strcmp("||", tok))) {
978 (void) snprintf(buf2, (size_t) (LINLENGTH-1L), "%s %s ", buf1, tok);
979 } else {
980 (void) snprintf(buf2, (size_t) (LINLENGTH-1L), "%s%s", buf1, tok);
981 }
982 continue;
983 }
984 (void) strcpy(buf1, buf2);
985 (void) build_name(sgn, tok, RIGHT_VALUE);
986 (void) snprintf(buf2, (size_t) (LINLENGTH-1L), "%s%s", buf1, tok);
987 }
988 clean_parentheses(buf2);
989 (void) fprintf(STDOUT, "%s", buf2);
990 (void) fprintf(STDOUT, " ) {\n");
991 return;
992}
993
994
995/* "build_to_be_delayed_node_list" makes node list including a delay for special processing */
996/* this procedure makes a list of node ID's which are inputs for delayed nodes. */
997
999 long in;
1000 long out;
1001 long k;
1002 char sgn[2] = {'\0'};
1003 char tok[STRLENGTH] = {'\0'};
1004 char *str = (char*) NULL;
1005 for (out = 0L; out < Num_Nodes; out++) {
1006 k = Node_List[out].kind;
1007 if ((DELAY1_KIND == k) || (DELAY2_KIND == k) || (DELAY3_KIND == k) || (DELAY_KIND == k)) {
1008 str = Node_List[out].value; /* get the unprocessed node_value */
1009 str = get_sign_and_token(str, sgn, tok); /* skip delay number */
1010 str = get_sign_and_token(str, sgn, tok); /* input_node name */
1011 in = node_id(tok);
1013 Num_Delays++;
1014 }
1015 }
1016 return;
1017}
1018
1019
1020/* Simulation loop is running at a multiple of the user defined sampling frequency as interpolation and decimation have to be */
1021/* handled properly. This function returns the minimum factor by which we have to multiply the nominal sampling frequency to */
1022/* obtain the frequency to run the simulation. During parsing, the data are stored as they are obtained, i.e as relative numbers, */
1023/* the function here establishes absolute quantities. All data are double float to avoid overflow. */
1024
1026 double numerator[MAXSEGMENTS];
1027 double denominator[MAXSEGMENTS];
1028 double gcd, lcm;
1029 long nseg;
1030 /* First segment (could be empty) is always running as specified by the instruction NAPA 'fs' sampling frequency */
1031 numerator[0L] = 1.0;
1032 denominator[0L] = 1.0;
1033 /* Determination of the rate of each segment */
1034 for (nseg = 1L; nseg < Num_Segments; nseg++) {
1035 if (INTERPOLATE_SEGMENT_TYPE == Segment_List[nseg].type) {
1036 if (0L == Segment_List[nseg].ref) { /* increase referred to previous segment rate */
1037 numerator[nseg] = numerator[nseg-1L] * Segment_List[nseg].rate;
1038 denominator[nseg] = denominator[nseg-1L];
1039 } else { /* increase referred to global sampling rate */
1040 numerator[nseg] = Segment_List[nseg].rate;
1041 denominator[nseg] = 1.0;
1042 }
1043 }
1044 if (DECIMATE_SEGMENT_TYPE == Segment_List[nseg].type) {
1045 if (0L == Segment_List[nseg].ref) { /* decrease referred to previous segment rate */
1046 numerator[nseg] = numerator[nseg-1L];
1047 denominator[nseg] = denominator[nseg-1L] * Segment_List[nseg].rate;
1048 } else { /* decrease referred to global sampling rate */
1049 numerator[nseg] = 1.0;
1050 denominator[nseg] = Segment_List[nseg].rate;
1051 }
1052 }
1053 if (NOMINAL_SEGMENT_TYPE == Segment_List[nseg].type) {
1054 numerator[nseg] = 1.0;
1055 denominator[nseg] = 1.0;
1056 }
1057 if (DROP_SEGMENT_TYPE == Segment_List[nseg].type) { /* no change but a conditional execution */
1058 numerator[nseg] = numerator[nseg-1L];
1059 denominator[nseg] = denominator[nseg-1L];
1060 }
1061 gcd = GCD(numerator[nseg], denominator[nseg]);
1062 numerator[nseg] /= gcd;
1063 denominator[nseg] /= gcd;
1064 }
1065 /* search for the lowest frequency for the simulation loop */
1066 lcm = 1.0;
1067 for (nseg = 0L; nseg < Num_Segments; nseg++) {
1068 if (!((Segment_List[nseg].used1) || (Segment_List[nseg].used2))) {
1069 continue;
1070 }
1071 lcm = LCM(lcm, numerator[nseg]);
1072 }
1073 Simulation_Rate = lcm;
1074 return;
1075}
1076
1077
1078/* Each segment should run at its own pace relative to main loop simulation rate 'Simulation_Rate' */
1079
1081 double rn, sn;
1082 long nseg;
1083 Segment_List[0].frequency = Sampling_List.frequency; /* the 'fs' frequency */
1084 Segment_List[0].offset = 0.0;
1085 Segment_List[0].rate = Simulation_Rate;
1086 for (nseg = 1L; nseg < Num_Segments; nseg++) {
1087 rn = Segment_List[nseg].rate;
1088 sn = Segment_List[nseg].offset;
1089 if (NOMINAL_SEGMENT_TYPE == Segment_List[nseg].type) { /* referred to global sampling rate */
1090 Segment_List[nseg].frequency = Segment_List[0].frequency;
1091 Segment_List[nseg].rate = Segment_List[0].rate;
1092 Segment_List[nseg].offset = Segment_List[0].offset;
1093 }
1094 if (DECIMATE_SEGMENT_TYPE == Segment_List[nseg].type) { /* 'decimate': decrease rate */
1095 if (0L == Segment_List[nseg].ref) { /* decreasing referred to previous segment rate */
1096 Segment_List[nseg].frequency = Segment_List[nseg-1L].frequency / rn;
1097 Segment_List[nseg].rate = Segment_List[nseg-1L].rate * rn;
1098 Segment_List[nseg].offset = Segment_List[nseg-1L].offset + (Segment_List[nseg-1L].rate * sn);
1099 } else { /* decreasing referred to main loop sampling rate */
1100 Segment_List[nseg].frequency = Segment_List[0].frequency / rn;
1101 Segment_List[nseg].rate = Segment_List[0].rate * rn;
1102 Segment_List[nseg].offset = Segment_List[0].offset + (Segment_List[0].rate * sn);
1103 }
1104 }
1105 if (INTERPOLATE_SEGMENT_TYPE == Segment_List[nseg].type) { /* 'interpolate': increase rate */
1106 if (0L == Segment_List[nseg].ref) { /* increasing referred to previous segment rate */
1107 Segment_List[nseg].frequency = Segment_List[nseg-1L].frequency * rn;
1108 Segment_List[nseg].rate = Segment_List[nseg-1L].rate / rn;
1109 Segment_List[nseg].offset = Segment_List[nseg-1L].offset;
1110 } else { /* increasing referred to main loop sampling rate */
1111 Segment_List[nseg].frequency = Segment_List[0].frequency * rn;
1112 Segment_List[nseg].rate = Segment_List[0].rate / rn;
1113 Segment_List[nseg].offset = Segment_List[0].offset;
1114 }
1115 }
1116 if (DROP_SEGMENT_TYPE == Segment_List[nseg].type) {
1117 if (0L == Segment_List[nseg].ref) { /* ignore condition, using previous segment rate */
1118 Segment_List[nseg].frequency = Segment_List[nseg-1L].frequency;
1119 Segment_List[nseg].rate = Segment_List[nseg-1L].rate;
1120 Segment_List[nseg].offset = Segment_List[nseg-1L].offset;
1121 } else { /* ignore condition, using main loop sampling rate */
1122 Segment_List[nseg].frequency = Segment_List[0].frequency;
1123 Segment_List[nseg].rate = Segment_List[0].rate;
1124 Segment_List[nseg].offset = Segment_List[0].offset;
1125 }
1126 }
1127 }
1128 for (nseg = 1L; nseg < Num_Segments; nseg++) {
1129 Segment_List[nseg].offset = fmod(Segment_List[nseg].offset, Segment_List[nseg].rate);
1130 }
1131 return;
1132}
1133
1134
1135void determine_output_segment_rate(void) { /* determine the processing rate in function of the nodes and variables to be output */
1136 int ok, always, first, atleastone;
1137 long out, seg;
1138 long d, m, n, u;
1139 long s;
1140 long seglist[MAXSEGMENTS];
1141 char sgn[2] = {'\0'};
1142 char lst[LINLENGTH] = {'\0'};
1143 char cnd1[LINLENGTH] = {'\0'};
1144 char cnd2[LINLENGTH] = {'\0'};
1145 char tok[STRLENGTH] = {'\0'};
1146 char *str = (char*) NULL;
1147 for (out = 0L; out < Num_IOs; out++) { /* process output after output */
1148 if (OUTPUT_TYPE != IO_List[out].type) {
1149 continue;
1150 }
1151 for (s = 0L; s < MAXSEGMENTS; s++) {
1152 seglist[s] = -1L;
1153 }
1154 atleastone = false; /* to detect at least one non constant parameter */
1155 always = false;
1156 first = true;
1157 ok = false;
1158 (void) strcpy(lst, IO_List[out].element);
1159 str = lst;
1160 for (;;) { /* scan token after token in the output list */
1161 seg = 0L;
1162 str = get_sign_and_token(str, sgn, tok);
1163 if (ISEMPTY(tok)) {
1164 break;
1165 }
1166 m = 0L;
1167 for (;;) { /* consider only each updated variables */
1168 m++;
1169 u = update_id(tok, m); /* consider all the updates of a variable */
1170 if (UNDEFINED != u) {
1171 seg = Update_List[u].segment;
1172 ok = true;
1173 } else {
1174 break;
1175 }
1176 if (!ok) {
1177 continue;
1178 }
1179 atleastone = true;
1180 if (ISEQUAL(1.0, Segment_List[seg].rate)) {
1181 always = true; /* one of the output is full rate */
1182 break; /* therefore the output rate is at max frequency */
1183 }
1184 if (seglist[seg] != seg) { /* avoid repetition */
1185 if (first) {
1186 (void) snprintf(cnd2, (size_t) (LINLENGTH-1L), "%s_%ld", "napa_segment_run", seg);
1187 first = false;
1188 } else {
1189 (void) strcpy(cnd1, cnd2);
1190 (void) snprintf(cnd2, (size_t) (LINLENGTH-1L), "%s || %s_%ld", cnd1, "napa_segment_run", seg);
1191 }
1192 seglist[seg] = seg; /* record identified segment */
1193 }
1194 }
1195 }
1196
1197 ok = false;
1198 (void) strcpy(lst, IO_List[out].element);
1199 str = lst;
1200 for (;;) { /* scan token after token in the output list */
1201 seg = 0L;
1202 str = get_sign_and_token(str, sgn, tok);
1203 if (ISEMPTY(tok)) {
1204 break;
1205 }
1206 n = node_id(tok);
1207 if (UNDEFINED != n) {
1208 if ((DC_KIND != Node_List[n].kind) && (CONST_KIND != Node_List[n].kind)) { /* ignore constants */
1209 seg = Node_List[n].segment;
1210 ok = true;
1211 }
1212 }
1213 if (!ok) {
1214 continue;
1215 }
1216 atleastone = true;
1217 if (ISEQUAL(1.0, Segment_List[seg].rate)) {
1218 always = true; /* one of the output is full rate */
1219 break;
1220 }
1221 if (seglist[seg] != seg) { /* avoid repetition */
1222 if (first) {
1223 (void) snprintf(cnd2, (size_t) (LINLENGTH-1L), "%s_%ld", "napa_segment_run", seg);
1224 first = false;
1225 } else {
1226 (void) strcpy(cnd1, cnd2);
1227 (void) snprintf(cnd2, (size_t) (LINLENGTH-1L), "%s || %s_%ld", cnd1, "napa_segment_run", seg);
1228 }
1229 }
1230 seglist[seg] = seg; /* record identified segment */
1231 }
1232 if (!atleastone) {
1233 (void) strcpy(cnd2, " 0LL == ABS_LOOP_INDEX "); /* only constants are output */
1234 }
1235 if (ISEMPTY(IO_List[out].condition)) {
1236 if (always) { /* at least one output is evaluated 'full rate' */
1237 (void) strcpy(cnd1, "true");
1238 } else {
1239 (void) strcpy(cnd1, cnd2);
1240 }
1241 } else {
1242 if (always) { /* at least one output is evaluated 'full rate' */
1243 (void) snprintf(cnd1, (size_t) (LINLENGTH-1L), "%s", IO_List[out].condition);
1244 } else {
1245 (void) snprintf(cnd1, (size_t) (LINLENGTH-1L), "(%s) && %s", cnd2, IO_List[out].condition);
1246 }
1247 }
1248 strcpy_realloc(&(IO_List[out].condition), cnd1, IO_List[out].mline, IO_List[out].mfile);
1249 IO_List[out].segment = 0L; /* assign segment 0 to output */
1251 Segment_List[Num_Segments].ref = 0L; /* referred to main sampling frequency */
1252 Segment_List[Num_Segments].frequency = 0.0;
1253 Segment_List[Num_Segments].rate = 1.0;
1254 Segment_List[Num_Segments].offset = 0.0;
1255 Segment_List[Num_Segments].used1 = false;
1256 Segment_List[Num_Segments].used2 = false;
1257 Segment_List[Num_Segments].used3 = true; /* this new segment contains an output */
1258 Segment_List[Num_Segments].periodic = true;
1259 for (d = 0L; d < MAXDEPTH; d++) {
1260 Segment_List[Num_Segments].mline[d] = IO_List[out].mline[d];
1261 Segment_List[Num_Segments].mfile[d] = IO_List[out].mfile[d];
1262 }
1263 increment_segment_number("output");
1264 }
1265 return;
1266}
1267
1268
1269/* Due to netlist structure, it may happen that several segments are running under the same conditions. We will regroup all */
1270/* elements in a minimum of segments to optimize the simulation. Process just after full segment conditon determination. */
1271/* Do not process segment 0 as it contains the sampling frequency defined by user. */
1272
1274 long newseg[MAXSEGMENTS];
1275 long nseg, nseg1, nseg2;
1276 long n;
1277 for (nseg = 0L; nseg < MAXSEGMENTS; nseg++) { /* default: new number is the current one */
1278 if (nseg < Num_Segments) {
1279 newseg[nseg] = nseg;
1280 } else {
1281 newseg[nseg] = 0L; /* initialize all remaining potential segments */
1282 }
1283 }
1284 for (nseg2 = 1L; nseg2 < Num_Segments; nseg2++) { /* renumber duplicate segment when identified */
1285 if (DROP_SEGMENT_TYPE == Segment_List[nseg2].type) {
1286 continue;
1287 }
1288 for (nseg1 = 0L; nseg1 < nseg2; nseg1++) { /* search for candidate in a previous segment */
1289 if ((ISEQUAL(Segment_List[nseg2].offset, Segment_List[nseg1].offset ))
1290 && (ISEQUAL(Segment_List[nseg2].rate, Segment_List[nseg1].rate ))
1291 && (ISEQUAL(Segment_List[nseg2].frequency, Segment_List[nseg1].frequency))) {
1292 Segment_List[nseg1].used1 = Segment_List[nseg1].used1 || Segment_List[nseg2].used1; /* combine usage */
1293 Segment_List[nseg1].used2 = Segment_List[nseg1].used2 || Segment_List[nseg2].used2;
1294 Segment_List[nseg1].used3 = Segment_List[nseg1].used3 || Segment_List[nseg2].used3;
1295 newseg[nseg2] = nseg1; /* assign a new number to this segment */
1296 Segment_List[nseg2].used1 = false; /* old number is no more used */
1297 Segment_List[nseg2].used2 = false; /* but data are not erased as they will used */
1298 Segment_List[nseg2].used3 = false; /* to document the C file */
1299 break;
1300 }
1301 }
1302 }
1303 for (n = 0L; n < Num_IOs; n++) { /* actualize the segment for each element */
1304 IO_List[n].segment = newseg[IO_List[n].segment];
1305 }
1306 for (n = 0L; n < Num_Nodes; n++) {
1307 Node_List[n].segment = newseg[Node_List[n].segment];
1308 }
1309 for (n = 0L; n < Num_Vars; n++) {
1310 Var_List[n].segment = newseg[Var_List[n].segment];
1311 }
1312 for (n = 0L; n < Num_Updates; n++) {
1313 Update_List[n].segment = newseg[Update_List[n].segment];
1314 }
1315 for (n = 0L; n < Num_UserTools; n++) {
1316 UserTool_List[n].segment = newseg[UserTool_List[n].segment];
1317 }
1318 for (n = 0L; n < Num_Posts; n++) {
1319 Post_List[n].segment = newseg[Post_List[n].segment];
1320 }
1321 Dump_List.segment = newseg[ Dump_List.segment];
1322 Gateway_List.segment = newseg[ Gateway_List.segment];
1323 Sampling_List.segment = newseg[Sampling_List.segment];
1324 return;
1325}
1326
1327
1329 long i, j, id;
1330 char tok[STRLENGTH] = {'\0'};
1331 char *s = (char*) NULL;
1332 /* nodes and variables */
1333 for (i = 0L; i < Num_Aliases; i++) {
1334 s = Alias_List[i].aliasof; /* node or variable target of the alias */
1335 (void) snprintf(tok, (size_t) (STRLENGTH-1L), "%s", s);
1336 id = node_id(tok);
1337 if (UNDEFINED != id) {
1338 if (Node_List[id].aliased) { /* alias != name */
1339 print_error_location("alias", Alias_List[i].mline, Alias_List[i].mfile);
1340 (void) fprintf(STDERR, " <%s> cannot be an alias of node <%s>,", Alias_List[i].name, tok );
1341 (void) fprintf(STDERR, " as <%s> is already an alias\n", Node_List[id].name1 );
1342 continue;
1343 }
1344 Node_List[id].aliased = true;
1345 strcpy_realloc(&(Node_List[id].name1), Alias_List[i].name, Alias_List[i].mline, Alias_List[i].mfile);
1346 continue;
1347 }
1348 id = var_id(tok);
1349 if (UNDEFINED != id) {
1350 if (Var_List[id].aliased) { /* alias != name */
1351 print_error_location("alias", Alias_List[i].mline, Alias_List[i].mfile);
1352 (void) fprintf(STDERR, " <%s> cannot be an alias of variable <%s>,", Alias_List[i].name, tok);
1353 (void) fprintf(STDERR, " as <%s> is already an alias\n", Var_List[id].name1 );
1354 continue;
1355 }
1356 Var_List[id].aliased = true;
1357 strcpy_realloc(&(Var_List[id].name1), Alias_List[i].name, Alias_List[i].mline, Alias_List[i].mfile);
1358 continue;
1359 }
1360 print_error_location("alias", Alias_List[i].mline, Alias_List[i].mfile);
1361 (void) fprintf(STDERR, " no node and no variable correspond to target <%s> of alias <%s>\n", tok, Alias_List[i].name);
1362 process_node_error(tok);
1364 }
1365 /* command_line */
1366 for (i = 0L; i < Num_Cmdlines; i++) { /* rework the line of parms */
1367 j = var_id(Cmdline_List[i].parms);
1368 if (UNDEFINED != j) {
1369 strcpy_realloc(&(Cmdline_List[i].parms), Var_List[j].name1, Cmdline_List[i].mline, Cmdline_List[i].mfile);
1370 }
1371 }
1372 return;
1373}
1374
1375
1376/* Greater Common Divider function. Recursive function ! */
1377
1378double GCD(double a, double b) {
1379 if (a < b) {
1380 return GCD(b, a);
1381 }
1382 if (_SMALL_ >= b) {
1383 return a;
1384 } else {
1385 return GCD(b, fmod(a, b));
1386 }
1387}
1388
1389
1390/* Least Common Multiple function. Use the recursive function GCD ! */
1391
1392double LCM(double n1, double n2) {
1393 return ((n1 / GCD(n1, n2)) * n2); /* ordered operation to avoid possible overflow ! */
1394}
1395
1396
1397/* Specific test to verify that the platform supports right shifts. It is normal that verification software flags this code, */
1398/* as it is, on purpose, a non portable code ! */
1399
1400int verify_rshift(void) {
1401 long n1, n2;
1402 n1 = -0X0500L;
1403 n2 = n1 >> 2; /* "Shifting a negative value is undefined behavior" : this is exactly the trick here to verify the platform ! */
1404 return ((0L != n2) ? true : false);
1405}
1406
1407
1408/* During file expansion, comments and blank lines are dropped */
1409/* Only comments placed on single lines are ignored ! */
1410
1411void cat_file(const char *fnam, const char *type, long command, const unsigned long *mlin, const unsigned long *mfil) {
1412 FILE *fp = (FILE*) NULL;
1413 char lin1[LINLENGTH+2L] = {'\0'};
1414 char lin2[LINLENGTH+2L] = {'\0'};
1415 long i, j;
1416 int flag1, flag2;
1417 flag1 = false;
1418 flag2 = false;
1419 if ((FILE*) NULL == (fp = fopen(fnam, "r"))) {
1420 print_error_location("file", mlin, mfil);
1421 (void) fprintf(STDERR, " OUCH!- (%s) can't find or access file <\"%s\">\n", type, fnam);
1423 }
1424 if (EXPAND == command) { /* file expansion is requested */
1425 while ((char*) NULL != (fgets(lin1, LINLENGTH, fp))) {
1426 flag1 = true;
1427 j = 0L;
1428 for (i = 0L; i < LENGTH(lin1); i++) { /* ignore comment area */
1429 if ((flag1) && ('/' == lin1[i]) && ('*' == lin1[i+1L])) {
1430 i++;
1431 flag1 = false;
1432 continue;
1433 }
1434 if (flag1) {
1435 lin2[j] = lin1[i];
1436 j++;
1437 }
1438 if ((!flag1) && ('*' == lin1[i-1L]) && ('/' == lin1[i])) {
1439 flag1 = true;
1440 continue;
1441 }
1442 }
1443 if (flag1) {
1444 lin2[j] = '\0';
1445 (void) strcpy(lin1, lin2);
1446 }
1447 flag2 = false;
1448 for (i = 0L; i < LENGTH(lin1); i++) {
1449 if (!isspace((int) lin1[i])) {
1450 flag2 = true; /* line contents non blank element */
1451 }
1452 }
1453 if (flag2) { /* do not copy blank or all comment lines */
1454 (void) fprintf(STDOUT, "%s", lin1);
1455 }
1456 }
1457 }
1458 if (EOF == fclose(fp)) {
1459 print_error_location("file", mlin, mfil);
1460 (void) fprintf(STDERR, " OUCH!- (%s) can't close file <\"%s\"> opened for verification\n", type, fnam);
1462 }
1463 return;
1464}
1465
1466
1468 (void) f1flush((FILE*) NULL);
1469 if (0 != Error_Flag) {
1471 }
1472 return;
1473}
1474
1475
1476void print_error_location(const char *type, const unsigned long *mlin, const unsigned long *mfil) {
1477 print_problem_location(type, mlin, mfil, "Error" );
1478 (void) fprintf(STDERR, "\n");
1479 Error_Flag++;
1480 return;
1481}
1482
1483
1484void print_warning_location(const char *type, const unsigned long *mlin, const unsigned long *mfil) {
1485 print_problem_location(type, mlin, mfil, "Warning");
1486 Warning_Flag = true;
1487 return;
1488}
1489
1490
1491void print_info_location(const char *type, const unsigned long *mlin, const unsigned long *mfil) {
1492 print_problem_location(type, mlin, mfil, "Note" );
1493 return;
1494}
1495
1496
1497void print_problem_location(const char *type, const unsigned long *mlin, const unsigned long *mfil, const char *kind) {
1498 char tok[STRLENGTH] = {'\0'};
1499 if (0 == strcmp(type, "")) {
1500 (void) strcpy(tok, "");
1501 } else {
1502 (void) snprintf(tok, (size_t) (STRLENGTH-1L), " (%s)", type);
1503 }
1504 (void) fprintf(STDERR, "\nNAPA %s: %s\n", kind, tok);
1505 print_location(mlin, mfil);
1506 return;
1507}
1508
1509
1510void print_location(const unsigned long *mlin, const unsigned long *mfil) {
1511 long d;
1512 if (((unsigned long*) NULL == mlin) || ((unsigned long*) NULL == mfil)) {
1513 return;
1514 }
1515 if (0UL == mlin[0]) {
1516 return;
1517 }
1518 (void) fprintf(STDERR, " -> at line %3lu of main netlist\n", mlin[0]);
1519 for (d = 1L; d < MAXDEPTH; d++) {
1520 if (0UL == mlin[d]) {
1521 (void) fprintf(STDERR, " ");
1522 return;
1523 }
1524 (void) fprintf(STDERR, " -> at line %3lu of file \"%s\"\n", mlin[d], Record_Cell_File_Table[mfil[d]]);
1525 }
1526 (void) f1flush((FILE*) NULL); /* flush ALL stream outputs */
1527 return;
1528}
1529
1530
1531/* Danny Cohen introduced the terms Little-Endian and Big-Endian for byte ordering in an article published */
1532/* by the Internet Engineering Task Force (IETF) in 1980.[1][2] In this technical and political examination */
1533/* of byte ordering issues, the endian names were drawn from Jonathan Swift's 1726 satire, Gulliver's Travels, */
1534/* in which civil war erupts over whether the big end or the little end of a boiled egg is the proper end to crack open. */
1535/* Intel x86, for example, is using LITTLE_ENDIAN. */
1536
1538 short int word = (short int) 0X0001LL;
1539 char *byte = (char*) &word;
1540 return byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN;
1541}
1542
1543
1544void wall_clock(void) {
1545 NAPA_Compile_Stop = ((double) clock())/((double) CLOCKS_PER_SEC);
1546 (void) fprintf(STDERR, "\n wall clock: %6.3f s\n\n", (NAPA_Compile_Stop - NAPA_Compile_Start));
1547 (void) f1flush((FILE*) NULL); /* flush ALL stream outputs */
1548 return;
1549}
1550
1551
1552void last_message(void) { /* this function is registered with 'atexit' */
1553 if (0 != Error_Flag) {
1554 (void) fprintf(STDERR, "\n ****\n" );
1555 (void) fprintf(STDERR, " **** NAPA Compilation Error(s)\n");
1556 (void) fprintf(STDERR, " ****\n\n\n");
1557 }
1558 (void) f1flush((FILE*) NULL); /* flush ALL stream outputs */
1559 return;
1560}
1561
1562
1563/* ****************************************************************************************************************************** */
1564/* end of file */
int verify_rshift(void)
Definition fc.c:1400
void check_record_usage(void)
Definition fc.c:560
void print_info_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1491
void print_location(const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1510
void cat_file(const char *fnam, const char *type, long command, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1411
double LCM(double n1, double n2)
Definition fc.c:1392
void process_error_if_any(void)
Definition fc.c:1467
void compact_segment(void)
Definition fc.c:1273
void expand_string_variables(void)
Definition fc.c:323
void build_condition(char *cond, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:958
void print_warning_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1484
long process_condition(char *str, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:916
void determine_segment_processing_rate(void)
Definition fc.c:1080
void complete_directives(void)
Definition fc.c:310
void print_error_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1476
void print_problem_location(const char *type, const unsigned long *mlin, const unsigned long *mfil, const char *kind)
Definition fc.c:1497
long f2printf(FILE *fp1, FILE *fp2, char *fmt,...)
Definition fc.c:157
void check_array_usage(void)
Definition fc.c:503
void build_to_be_delayed_node_list(void)
Definition fc.c:998
void expand_records(void)
Definition fc.c:377
int test_endianness(void)
Definition fc.c:1537
void determine_output_segment_rate(void)
Definition fc.c:1135
void last_message(void)
Definition fc.c:1552
void check_directive_usage(void)
Definition fc.c:631
void expand_update_definitions(void)
Definition fc.c:777
double GCD(double a, double b)
Definition fc.c:1378
void expand_dump_definitions(void)
Definition fc.c:887
void print_limits(void)
Definition fc.c:56
char * get_a_line(char *buf, unsigned long *nl, FILE *fp, unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:100
void collect_export_definitions(void)
Definition fc.c:671
void expand_IO_definitions(void)
Definition fc.c:844
void wall_clock(void)
Definition fc.c:1544
void process_aliases(void)
Definition fc.c:1328
void default_control_variables(void)
Definition fc.c:184
void determine_simulation_rate(void)
Definition fc.c:1025
long get_type(char *identifier)
Definition id.c:1190
long update_id(const char *identifier, long num)
Definition id.c:807
void strcpy_alloc(char **dest, const char *sour, const unsigned long *mlin, const unsigned long *mfil)
Definition id.c:114
long array_id(const char *identifier)
Definition id.c:635
long directive_id(const char *identifier)
Definition id.c:707
void increment_directive_number(const char *kind)
Definition id.c:267
long array_name_id(const char *identifier)
Definition id.c:646
long node_id(const char *identifier)
Definition id.c:718
long var_id(const char *identifier)
Definition id.c:855
void increment_segment_number(const char *kind)
Definition id.c:479
long record_id(const char *identifier)
Definition id.c:796
void strcpy_realloc(char **dest, const char *sour, const unsigned long *mlin, const unsigned long *mfil)
Definition id.c:129
void process_node_error(const char *tok1)
Definition mp.c:259
void process_variable_error(const char *tok1)
Definition mp.c:331
#define MAXEXPORTS
Definition napa.h:213
EXTERN int Interpolate_Flag
Definition napa.h:863
#define DELAY2_KIND
Definition napa.h:255
EXTERN long Num_Injects
Definition napa.h:820
#define DECIMATE_SEGMENT_TYPE
Definition napa.h:351
#define DROP_SEGMENT_TYPE
Definition napa.h:353
#define RIGHT_VALUE
Definition napa.h:416
#define MAXVARS
Definition napa.h:187
EXTERN int Synchro_Flag
Definition napa.h:879
EXTERN long Num_Voids
Definition napa.h:837
#define MAXDEPTH
Definition napa.h:212
EXTERN long Num_Groups
Definition napa.h:817
EXTERN long Num_Aliases
Definition napa.h:799
EXTERN RANDOMSEED_TYPE Seed_List
Definition napa.h:979
EXTERN long Num_Macros
Definition napa.h:823
EXTERN VAR_TYPE Var_List[2047L]
Definition napa.h:970
EXTERN int Error_Flag
Definition napa.h:853
EXTERN char I_String_Format[2047L]
Definition napa.h:902
EXTERN int Interlude_Flag3
Definition napa.h:870
EXTERN RECORD_TYPE Record_List[127L]
Definition napa.h:965
EXTERN long Num_Consts
Definition napa.h:807
#define MAXINSTANCES
Definition napa.h:190
EXTERN long Num_Debugs
Definition napa.h:809
EXTERN long Num_Calls
Definition napa.h:802
EXTERN int Post_Flag
Definition napa.h:876
EXTERN char Condition_Assign[16383L]
Definition napa.h:947
#define _SMALL_
Definition napa.h:146
EXTERN int Stuck_Flag
Definition napa.h:878
EXTERN long Num_Functions
Definition napa.h:815
EXTERN long Num_Vars
Definition napa.h:836
EXTERN ARRAY_TYPE Array_List[63L]
Definition napa.h:950
#define LENGTH(s)
Definition napa.h:397
#define BIG_ENDIAN
Definition napa.h:97
EXTERN int Array_Flag
Definition napa.h:843
EXTERN char V_Format[2047L]
Definition napa.h:899
EXTERN char E_Format[2047L]
Definition napa.h:895
EXTERN int Load_Flag
Definition napa.h:865
EXTERN int Directive_Flag
Definition napa.h:850
#define UNDEFINED
Definition napa.h:331
EXTERN int Drop_Flag
Definition napa.h:851
EXTERN long Num_Records
Definition napa.h:828
EXTERN char S_Format[2047L]
Definition napa.h:898
EXTERN long Num_Updates
Definition napa.h:834
#define S_FORMAT_V
Definition napa.h:170
#define ROM2_KIND
Definition napa.h:304
EXTERN char R_Format[2047L]
Definition napa.h:897
EXTERN long Num_Arrays
Definition napa.h:800
EXTERN int Function_Flag
Definition napa.h:858
EXTERN char Last_Postprocess[2047L]
Definition napa.h:893
EXTERN POST_TYPE Post_List[63L]
Definition napa.h:964
#define STDERR
Definition napa.h:105
EXTERN double NAPA_Compile_Start
Definition napa.h:988
EXTERN int Ts_Flag
Definition napa.h:884
#define MAXPARMS
Definition napa.h:200
EXTERN int Title_Flag
Definition napa.h:881
#define MAXINJECTS
Definition napa.h:210
EXTERN NODE_TYPE Node_List[4095L]
Definition napa.h:962
EXTERN int Hierarchy_Flag
Definition napa.h:860
EXTERN char S_String_Format[2047L]
Definition napa.h:904
EXTERN int Update_Flag
Definition napa.h:886
EXTERN long Num_UserTools
Definition napa.h:835
EXTERN long Max_Depth
Definition napa.h:797
EXTERN int Dump_Flag
Definition napa.h:852
EXTERN USERTOOL_TYPE UserTool_List[511L]
Definition napa.h:969
EXTERN EXPORT_TYPE Export_List[31L]
Definition napa.h:956
#define CONST_KIND
Definition napa.h:246
#define DELAY3_KIND
Definition napa.h:256
EXTERN int Fs_Flag
Definition napa.h:856
EXTERN int Delayed_Flag
Definition napa.h:849
#define INPUT_TYPE
Definition napa.h:358
EXTERN long Num_Restarts
Definition napa.h:830
#define EXPAND
Definition napa.h:413
#define ANALOG_DATA_TYPE
Definition napa.h:338
EXTERN int Export_Flag
Definition napa.h:855
EXTERN SAMPLING_TYPE Sampling_List
Definition napa.h:978
EXTERN int Tool_Index_Flag
Definition napa.h:882
#define MAXOPTIONS
Definition napa.h:196
EXTERN int Tool_Flag
Definition napa.h:883
#define MAXCOMMENTS
Definition napa.h:203
EXTERN char R_String_Format[2047L]
Definition napa.h:903
#define NAPA_ANALOG_TYPE
Definition napa.h:130
#define DEFAULT_S_FORMAT
Definition napa.h:176
EXTERN char Export0_Head_String[16383L]
Definition napa.h:919
EXTERN long Num_Headers
Definition napa.h:818
EXTERN char X_String_Format[2047L]
Definition napa.h:905
EXTERN long Num_Redefs
Definition napa.h:829
EXTERN char * Record_Cell_File_Table[511L]
Definition napa.h:940
EXTERN ALIAS_TYPE Alias_List[127L]
Definition napa.h:949
EXTERN DIRECTIVE_TYPE Directive_List[255L]
Definition napa.h:955
#define MAXDECLARES
Definition napa.h:189
EXTERN long Num_Declares
Definition napa.h:810
#define INTERPOLATE_SEGMENT_TYPE
Definition napa.h:352
#define IUSER_KIND
Definition napa.h:280
EXTERN long Num_Asserts
Definition napa.h:801
EXTERN int Cmdline_Flag
Definition napa.h:846
#define LINLENGTH
Definition napa.h:216
#define MAXFUNCTIONS
Definition napa.h:195
#define DUSER_KIND
Definition napa.h:261
#define TEST_KIND
Definition napa.h:316
EXTERN long Num_Nodes
Definition napa.h:824
#define MAXPOSTS
Definition napa.h:206
#define DELAY1_KIND
Definition napa.h:254
EXTERN char X_Format[2047L]
Definition napa.h:900
EXTERN int Ts_Ext_Flag
Definition napa.h:885
#define MAXARRAYS
Definition napa.h:202
EXTERN int Debug_Flag
Definition napa.h:848
#define RAM_KIND
Definition napa.h:298
#define I_FORMAT_V
Definition napa.h:155
EXTERN long Num_Tools
Definition napa.h:833
EXTERN long Num_Exports
Definition napa.h:813
#define MAXFILECELLS
Definition napa.h:191
EXTERN int Warning_Flag
Definition napa.h:890
EXTERN INTERLUDE_TYPE Interlude_List
Definition napa.h:974
EXTERN long Num_Directives
Definition napa.h:812
#define LITTLE_ENDIAN
Definition napa.h:98
EXTERN long Num_Delays
Definition napa.h:811
EXTERN long Num_Inits
Definition napa.h:819
#define STDOUT
Definition napa.h:104
EXTERN int Interlude_Flag1
Definition napa.h:868
EXTERN char Comment_String[63L][16383L]
Definition napa.h:925
#define MAXDECLARECOMMONS
Definition napa.h:193
EXTERN int Comment_Flag
Definition napa.h:847
EXTERN long Num_Posts
Definition napa.h:827
#define DALGEBRA_KIND
Definition napa.h:251
#define MAXOPCODES
Definition napa.h:199
EXTERN char Export0_List_String[16383L]
Definition napa.h:921
EXTERN int Input_Flag
Definition napa.h:862
#define ROM_KIND
Definition napa.h:303
#define MAXFILES
Definition napa.h:204
#define DC_KIND
Definition napa.h:252
EXTERN int Option_Flag
Definition napa.h:871
EXTERN double NAPA_Compile_Stop
Definition napa.h:989
EXTERN long Num_FileCells
Definition napa.h:814
#define DEFAULT_R_FORMAT
Definition napa.h:175
#define MAXHEADERS
Definition napa.h:209
#define IALGEBRA_KIND
Definition napa.h:274
EXTERN char Export1_List_String[16383L]
Definition napa.h:922
#define ISEQUAL(x, y)
Definition napa.h:379
#define NOMINAL_SEGMENT_TYPE
Definition napa.h:350
EXTERN int UserTool_Flag
Definition napa.h:888
EXTERN long Num_IOs
Definition napa.h:822
#define MAXIOS
Definition napa.h:205
EXTERN char I_Format[2047L]
Definition napa.h:896
EXTERN double Simulation_Rate
Definition napa.h:982
#define MAXNODES
Definition napa.h:186
#define MAXUPDATES
Definition napa.h:188
EXTERN long Num_Nulls
Definition napa.h:825
EXTERN long Num_Segments
Definition napa.h:831
EXTERN GATEWAY_TYPE Gateway_List
Definition napa.h:973
EXTERN long Delay_Input[4095L]
Definition napa.h:984
EXTERN long Num_Comments
Definition napa.h:805
#define ISNOTEMPTY(s)
Definition napa.h:395
#define ITOOL_KIND
Definition napa.h:279
#define DTOOL_KIND
Definition napa.h:260
EXTERN int Inject_Flag
Definition napa.h:861
#define RAM2_KIND
Definition napa.h:299
#define MAX(x, y)
Definition napa.h:377
#define R_FORMAT_V
Definition napa.h:165
EXTERN long Num_Instances
Definition napa.h:821
EXTERN int Fs_Ext_Flag
Definition napa.h:857
EXTERN CMDLINE_TYPE Cmdline_List[63L]
Definition napa.h:951
#define MAXRECORDS
Definition napa.h:198
#define MAXUSERTOOLS
Definition napa.h:192
EXTERN long Num_Cmdlines
Definition napa.h:804
EXTERN long Num_Creates
Definition napa.h:808
EXTERN char Title_String[2 *2047L]
Definition napa.h:927
EXTERN int User_Flag
Definition napa.h:887
EXTERN int Terminate_Flag
Definition napa.h:880
EXTERN SEGMENT_TYPE Segment_List[127L]
Definition napa.h:966
EXTERN int Pointer_Flag
Definition napa.h:875
#define MAXALIASES
Definition napa.h:197
#define STRLENGTH
Definition napa.h:217
EXTERN int Multdelay_Flag
Definition napa.h:867
EXTERN long Num_Opcodes
Definition napa.h:826
EXTERN int Assert_Flag
Definition napa.h:844
EXTERN long Num_Cells
Definition napa.h:803
EXTERN long Num_Stucks
Definition napa.h:832
#define NAPA_DIGITAL_TYPE
Definition napa.h:129
#define MAXCMDLINES
Definition napa.h:207
#define ISEMPTY(s)
Definition napa.h:394
#define STRING_DATA_TYPE
Definition napa.h:339
EXTERN int Seed_Flag
Definition napa.h:877
EXTERN int Antithetic_Flag
Definition napa.h:842
#define DELAY_KIND
Definition napa.h:253
EXTERN int Ping_Flag
Definition napa.h:874
#define ALGEBRA_KIND
Definition napa.h:227
EXTERN char Cmdline_String[2047L]
Definition napa.h:924
EXTERN char Export1_Head_String[16383L]
Definition napa.h:920
#define DEFAULT_I_FORMAT
Definition napa.h:173
EXTERN long Num_Generators
Definition napa.h:816
EXTERN int Gateway_Flag
Definition napa.h:859
EXTERN int Output_Flag
Definition napa.h:872
#define UNKNOWN_KIND
Definition napa.h:224
EXTERN int Call_Flag
Definition napa.h:845
EXTERN DUMP_TYPE Dump_List
Definition napa.h:972
#define OUTPUT_TYPE
Definition napa.h:359
#define MAXSEGMENTS
Definition napa.h:201
EXTERN char Short_Title_String[2 *2047L]
Definition napa.h:926
EXTERN char Last_Instruction[2047L]
Definition napa.h:892
EXTERN IO_TYPE IO_List[63L]
Definition napa.h:961
EXTERN int Loop_Flag
Definition napa.h:866
EXTERN long Num_Declare_Commons
Definition napa.h:806
#define DIGITAL_DATA_TYPE
Definition napa.h:337
#define MAXDIRS
Definition napa.h:194
EXTERN int Interlude_Flag2
Definition napa.h:869
EXTERN UPDATE_TYPE Update_List[2047L]
Definition napa.h:968
EXTERN int Periodic_Flag
Definition napa.h:873
#define DEFAULT_X_FORMAT
Definition napa.h:174
#define MAXSTUCKS
Definition napa.h:211
void print_error_banner_and_exit(void)
Definition pr.c:5482
char * get_token(char *str, char *tok, long keep_quotes)
Definition tk.c:1210
void clean_line(char *str)
Definition tk.c:1397
char * build_name(const char *sgn, char *tok, long lr_type)
Definition tk.c:69
void clean_parentheses(char *tok)
Definition tk.c:403
void mark_directives(void)
Definition rd.c:1478
int f1flush(FILE *fp)
Definition tk.c:1843
void expand_iterative_identifiers(char *str, unsigned long *mlin, const unsigned long *mfil)
Definition tk.c:796
int is_an_identifier(const char *tok)
Definition tk.c:1327
char * get_token_between_braces(char *str, char *brc, char *tok)
Definition tk.c:1110
void expand_indirections(char *str)
Definition tk.c:717
char * get_sign_and_token(char *str, char *sgn, char *tok)
Definition tk.c:1188
void C_syntax_checker(char *str, const unsigned long *mlin, const unsigned long *mfil)
Definition sx.c:1896