1 /* Copyright (c) 1991-2007 Pragmatic C Software Corp. */
2
3 /*
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
17
18 We are selling our new Verilog compiler that compiles to X86 Linux
19 assembly language. It is at least two times faster for accurate gate
20 level designs and much faster for procedural designs. The new
21 commercial compiled Verilog product is called CVC. For more information
22 on CVC visit our website at www.pragmatic-c.com/cvc.htm or contact
23 Andrew at avanvick@pragmatic-c.com
24
25 */
26
27
28 /*
29 * second source module for statement reading and expressions parsing
30 * tasks in src 3
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <math.h>
37
38 #ifdef __DBMALLOC__
39 #include "../malloc.h"
40 #endif
41
42 #include "v.h"
43 #include "cvmacros.h"
44
45 /* local prototypes */
46 static struct st_t *rd_block(int32, int32);
47 static struct st_t *convert_to_fork(struct st_t *);
48 static int32 rd_lstofsts(int32, struct st_t **, int32, int32);
49 static struct st_t *rd_namblock(int32, int32, int32, int32);
50 static struct st_t *rd_if(void);
51 static struct st_t *rd_case(int32);
52 static struct st_t *rd_loop(int32);
53 static struct st_t *rd_for(void);
54 static struct st_t *rd_cause(void);
55 static struct st_t *rd_disable(void);
56 static struct expr_t *find_bldxpr_tfsy(char *, int32);
57 static struct st_t *rd_wireassign(int32);
58 static struct st_t *rd_wiredeassign(int32);
59 static struct st_t *rd_taske_or_proc_assign(void);
60 static struct st_t *rd_dctrl_st(void);
61 static struct expr_t *rd_delctrl(int32 *, int32 *);
62 static int32 col2_lval(void);
63 static int32 col_dctrl_xmr(void);
64 static int32 col_evctrlexpr(void);
65 static void init_gref(struct gref_t *, char *);
66 static struct expr_t *parse_qcexpr(void);
67 static void xskip_toend(void);
68 static struct expr_t *parse_boolorop(void);
69 static struct expr_t *parse_boolandop(void);
70 static struct expr_t *parse_borop(void);
71 static struct expr_t *parse_bxorop(void);
72 static struct expr_t *parse_bandop(void);
73 static struct expr_t *parse_eqop(void);
74 static struct expr_t *parse_ltgtop(void);
75 static struct expr_t *parse_shop(void);
76 static struct expr_t *parse_addop(void);
77 static struct expr_t *parse_mulop(void);
78 static struct expr_t *parse_unopterm(void);
79 static void skip_3valend(void);
80 static int32 is_unop(word32);
81 static struct expr_t *parse_term(void);
82 static int32 decl_id_inexpr(struct expr_t *, struct expridtab_t *);
83 static struct expr_t *parse_concat(void);
84 static struct expr_t *parse_select(struct expr_t *);
85 static struct expr_t *parse_glbref(struct expr_t *, struct expridtab_t *);
86 static struct expr_t *bld_1cmp_global(struct expr_t *, struct expridtab_t *);
87 static char *alloc_glbndp_tostr(struct expr_t *);
88 static void grow_grtab(void);
89 static struct expr_t *parse_fcall(struct expr_t *, struct expridtab_t *, int32);
90 static int32 chk_decl_func(int32 *, struct expr_t *, struct expridtab_t *);
91 static void cnvt_forw_tfcall_1cmpglb(struct expr_t *, char *, int32, int32);
92 static struct expr_t *parse_evexpr(void);
93 static void grow_exprtab(void);
94 static struct expr_t *my_xndalloc(void);
95 static struct expr_t *alloc_xtnd(int32);
96 static void set2_opempty(struct expr_t *);
97 static char *to_xndnam(char *, int32 xndi);
98 static word32 get_hash(word32 *, word32 *, int32);
99
100 /* extern prototypes (maybe defined in this module) */
101 extern char *__pv_stralloc(char *);
102 extern char *__my_malloc(int32);
103 extern char *__my_realloc(char *, int32, int32);
104 extern char *__msgexpr_tostr(char *, struct expr_t *);
105 extern char *__prt_vtok(void);
106 extern char *__prt_kywrd_vtok(void);
107 extern struct sy_t *__get_sym_env(char *);
108 extern struct sy_t *__get_sym(char *, struct symtab_t *);
109 extern struct sy_t *__decl_sym(char *, struct symtab_t *);
110 extern struct net_t *__add_net(struct sy_t *);
111 extern char *__to_idnam(struct expr_t *);
112 extern char *__to_sytyp(char *, word32);
113 extern struct st_t *__alloc_stmt(int32);
114 extern char *__get_vkeynam(char *, int32);
115 extern void __find_matchendblk(int32, int32);
116 extern void __find_matchendcase(void);
117 extern int32 __col_caseexpr(void);
118 extern struct exprlst_t *__alloc_xprlst(void);
119 extern struct csitem_t *__alloc_csitem(void);
120 extern char *__to_opname(word32);
121 extern struct paramlst_t *__alloc_pval(void);
122 extern char *__regab_tostr(char *, word32 *, word32 *, int32, int32, int32);
123 extern char *__bld_lineloc(char *, word32, int32);
124 extern struct gref_t *__bld_glbref(struct expr_t *, int32, int32);
125 extern struct expr_t *__alloc_newxnd(void);
126 extern void __get_vtok(void);
127 extern void __unget_vtok(void);
128 extern int32 __vskipto_any(int32);
129 extern int32 __vskipto2_any(int32, int32);
130 extern int32 __vskipto3_any(int32, int32, int32);
131 extern int32 __vskipto4_any(int32, int32, int32, int32);
132 extern int32 __bld_tsk(char *, int32);
133 extern int32 __rd_tfdecls(char *);
134 extern void __set_xtab_errval(void);
135 extern void __bld_xtree(int32);
136 extern void __bld_evxtree(void);
137 extern int32 __col_parenexpr(int32);
138 extern int32 __col_lval(void);
139 extern int32 __col_comsemi(int32);
140 extern void __resolve_glbnam(struct gref_t *);
141 extern void __fill_grp_targu_fld(struct gref_t *);
142 extern void __set_opempty(int32);
143 extern int32 __col_connexpr(int32);
144 extern int32 __bld_expnode(void);
145 extern void __init_xnd(struct expr_t *);
146 extern void __set_numval(struct expr_t *, word32, word32, int32);
147 extern void __my_free(char *, int32);
148 extern void __free2_xtree(struct expr_t *);
149 extern struct st_t *__rd_tskenable(char *, struct expr_t *, int32);
150 extern void __setup_contab(void);
151 extern int32 __alloc_shareable_cval(word32, word32, int32);
152 extern int32 __alloc_shareable_rlcval(double);
153 extern int32 __alloc_is_cval(int32);
154 extern int32 __allocfill_cval_new(word32 *, word32 *, int32);
155 extern char *__alloc_vval_to_cstr(word32 *, int32, int32, int32);
156 extern void __grow_contab(int32);
157 extern struct expridtab_t *__alloc_expridnd(char *);
158 extern struct expr_t *__alloc_exprnd(void);
159
160 extern void __pv_ferr(int32, char *, ...);
161 extern void __pv_fwarn(int32, char *, ...);
162 extern void __gferr(int32, word32, int32, char *, ...);
163 extern void __dbg_msg(char *, ...);
164 extern void __my_fprintf(FILE *, char *, ...);
165 extern void __fterr(int32, char *, ...);
166 extern void __arg_terr(char *, int32);
167 extern void __case_terr(char *, int32);
168 extern void __misc_terr(char *, int32);
169 extern void __misc_fterr(char *, int32);
170 extern void __ia_err(int32 id_num, char *s, ...);
171
172 extern struct opinfo_t __opinfo[];
173 extern word32 __masktab[];
174
175 /*
176 * STATEMENT PROCESSING ROUTINES
177 */
178
179 /*
180 * read statement
181 * expects 1st token read and reads ending ; or end or del. ctrl.
182 * statement routines allocate and return statement - caller links it in
183 *
184 * this routine cannot skip, but if it calls rd_stmt must handle skipping
185 */
__rd_stmt(void)186 extern struct st_t *__rd_stmt(void)
187 {
188 struct st_t *stp;
189
190 __saverr_cnt = __pv_err_cnt;
191 stp = NULL;
192 /* statement routines for bracketed statements will have skipped to end */
193 switch ((byte) __toktyp) {
194 case IF:
195 if ((stp = rd_if()) == NULL) return(NULL);
196 break;
197 case Begin:
198 /* will have skipped to block end on error */
199 /* if possible this returns list of statements instead of block */
200 if ((stp = rd_block(Begin, END)) == NULL) return(NULL);
201 break;
202 case FORK:
203 if ((stp = rd_block(FORK, JOIN)) == NULL) return(NULL);
204 break;
205 case SEMI:
206 stp = __alloc_stmt(S_NULL);
207 break;
208 case CASE: case CASEX: case CASEZ:
209 if ((stp = rd_case(__toktyp)) == NULL) return(NULL);
210 break;
211 case FOREVER: case WHILE: case WAIT: case REPEAT:
212 /* notice no repeat form del ctrls since repeat keyword indicates stmt */
213 if ((stp = rd_loop(__toktyp)) == NULL) return(NULL);
214 break;
215 case FOR:
216 if ((stp = rd_for()) == NULL) return(NULL);
217 break;
218 case SHARP: case AT:
219 if ((stp = rd_dctrl_st()) == NULL) return(NULL);
220 break;
221 case DISABLE:
222 if ((stp = rd_disable()) == NULL) return(NULL);
223 break;
224 case CAUSE:
225 if ((stp = rd_cause()) == NULL) return(NULL);
226 break;
227 case ASSIGN:
228 if ((stp = rd_wireassign(ASSIGN)) == NULL) return(NULL);
229 break;
230 case DEASSIGN:
231 if ((stp = rd_wiredeassign(DEASSIGN)) == NULL) return(NULL);
232 break;
233 case FORCE:
234 if ((stp = rd_wireassign(FORCE)) == NULL) return(NULL);
235 break;
236 case RELEASE:
237 if ((stp = rd_wiredeassign(RELEASE)) == NULL) return(NULL);
238 break;
239 /* these are resync error conditions - must handle out of sync to end */
240 case ENDTASK:
241 case ENDFUNCTION:
242 case ENDSPECIFY:
243 __pv_ferr(1060, "module item end bracket problem - %s read",
244 __prt_vtok());
245 /* SJM 01/18/1999 - must stay at module level end to try to finish */
246 /* item gracefully */
247 /* ??? __get_vtok(); */
248 __syncto_class = SYNC_MODLEVEL;
249 return(NULL);
250 case ENDCASE:
251 case END:
252 case JOIN:
253 __syncto_class = SYNC_STMT;
254 bad_struct:
255 __pv_ferr(1061, "statement structure end bracket problem - %s read",
256 __prt_vtok());
257 __get_vtok();
258 return(NULL);
259 case ENDMODULE:
260 case ENDPRIMITIVE:
261 case ENDTABLE:
262 __syncto_class = SYNC_FLEVEL;
263 goto bad_struct;
264
265 /* non keyword - only 2 possibilities */
266 case ID: case LCB:
267 /* exactly 2 things can start proc lhs [id (glb ref)] = , {...} = */
268 /* also task enable [id (glb ref)](... legal - nothing else */
269 if ((stp = rd_taske_or_proc_assign()) == NULL) return(NULL);
270 break;
271 default:
272 __pv_ferr(1062, "statement starting token expected - %s read",
273 __prt_vtok());
274 /* must advance one token here else end = uu; never advances */
275 __get_vtok();
276 __vskipto_any(SEMI);
277 return(NULL);
278 }
279 return(stp);
280 }
281
282 /*
283 * read a sequential or fork/join block
284 * begin/fork read, reads end
285 * notice for unnamed begin-end block will return list of stmts
286 * with first have unb head turned on
287 */
rd_block(int32 btok,int32 endbtok)288 static struct st_t *rd_block(int32 btok, int32 endbtok)
289 {
290 int32 slcnt, sfnind;
291 struct st_t *stp, *hdstp;
292
293 slcnt = __lin_cnt;
294 sfnind = __cur_fnam_ind;
295 __get_vtok();
296 if (__toktyp == COLON)
297 {
298 if (__iact_state)
299 {
300 /* cannot catch this later because no declarations in interactive */
301 __pv_err_cnt++;
302 __ia_err(1431, "named blocks illegal in interactive mode");
303 return(NULL);
304 }
305 /* task without params embedded in statement list */
306 __cur_declobj = TASK;
307 stp = rd_namblock(btok, endbtok, slcnt, sfnind);
308 __cur_declobj = MODULE;
309 return(stp);
310 }
311 /* first step is to read list of statements in block */
312 /* if all statements in error will look like empty statement */
313 if (!rd_lstofsts(endbtok, &hdstp, __lin_cnt, __cur_fnam_ind)) return(NULL);
314 if (btok == Begin)
315 {
316 if (hdstp != NULL)
317 {
318 hdstp->st_unbhead = TRUE;
319 /* correct to line of begin */
320 /* ---
321 hdstp->stfnam_ind = sfnind;
322 hdstp->stlin_cnt = slcnt;
323 -- */
324 }
325 return(hdstp);
326 }
327 /* this can never return nil */
328 stp = convert_to_fork(hdstp);
329 /* correct to line of fork */
330 /* SJM ??? UNDO FOR RELEASE ---
331 stp->stfnam_ind = sfnind;
332 stp->stlin_cnt = slcnt;
333 --- */
334 return(stp);
335 }
336
337 /*
338 * convert a statement list to a fork-join statement
339 *
340 * at this point st nxt fields point to next in list
341 * converts to table where nexts all empty and nil at end of table
342 */
convert_to_fork(struct st_t * hdstp)343 static struct st_t *convert_to_fork(struct st_t *hdstp)
344 {
345 register int32 fji;
346 register struct st_t *stp;
347 int32 num_fjs;
348 struct st_t *stp2, *fjstp;
349
350 /* first count how many */
351 for (num_fjs = 0, stp = hdstp; stp != NULL; stp = stp->stnxt)
352 {
353 /* SJM 09/24/01 - for assign followed by for pair count as one */
354 if (stp->stmttyp == S_FORASSGN) continue;
355 num_fjs++;
356 }
357
358 /* know this is fork-join (never named) */
359 fjstp = __alloc_stmt(S_UNFJ);
360 /* one extra for nil fence at end */
361 fjstp->st.fj.fjstps = (struct st_t **)
362 __my_malloc((num_fjs + 1)*sizeof(struct st_t *));
363 fjstp->st.fj.fjlabs = (int32 *) __my_malloc((num_fjs + 1)*sizeof(int32));
364
365 /* fill table of ptrs to stmts */
366 /* for now leaving begin-end as unnamed block - not making st. list */
367 /* even if empty (because of error) need body as NULL statement */
368 for (stp = hdstp, fji = 0; fji < num_fjs; fji++)
369 {
370 /* SJM 09/24/01 - for for need both S FOR ASSIGN and for as one "block" */
371 /* since unnamed begin end blocks are just lists, works */
372 /* notice other setup inserted not inserted by here so can ignore */
373 if (stp->stmttyp == S_FORASSGN)
374 {
375 stp2 = stp->stnxt->stnxt;
376 fjstp->st.fj.fjstps[fji] = stp;
377 fjstp->st.fj.fjlabs[fji] = -1;
378 stp->stnxt->stnxt = NULL;
379 }
380 else
381 {
382 stp2 = stp->stnxt;
383 fjstp->st.fj.fjstps[fji] = stp;
384 fjstp->st.fj.fjlabs[fji] = -1;
385 /* fork-join is exactly one statement - unnamed block if begin-end */
386 stp->stnxt = NULL;
387 }
388 stp = stp2;
389 }
390 /* set ending fence */
391 fjstp->st.fj.fjstps[num_fjs] = NULL;
392 fjstp->st.fj.fjlabs[num_fjs] = -1;
393 return(fjstp);
394 }
395
396 /*
397 * read a statement list ending with block end token
398 * for contents of block, know block begin and optional label read
399 * reads block end token
400 * must use local variables since recursively nested blocks legal
401 */
rd_lstofsts(int32 endbtok,struct st_t ** stpp,int32 slcnt,int32 sfnind)402 static int32 rd_lstofsts(int32 endbtok, struct st_t **stpp, int32 slcnt,
403 int32 sfnind)
404 {
405 struct st_t *stp, *last_stp, *unbstp;
406
407 /* block body statements may be missing i.e begin end ok */
408 last_stp = NULL;
409 if (__toktyp == endbtok)
410 {
411 stp = __alloc_stmt(S_STNONE);
412 stp->stfnam_ind = sfnind;
413 stp->stlin_cnt = slcnt;
414 *stpp = stp;
415 return(TRUE);
416 }
417 for (*stpp = NULL;;)
418 {
419 /* on error, this attempts to read to 1 before next statement token */
420 /* this expects 1st token of statement to have been read */
421 if ((stp = __rd_stmt()) == NULL)
422 {
423 if (__syncto_class == SYNC_STMT || __syncto_class == SYNC_TARG)
424 {
425 __get_vtok();
426 if (__toktyp == TEOF)
427 { __syncto_class = SYNC_FLEVEL; return(FALSE); }
428 continue;
429 }
430 /* know hit module or file level thing - think unresyncable */
431 return(FALSE);
432 }
433 /* if statement is unnamed block, change normal list to unnamed block */
434 /* need since in list next already used */
435 /* but need lists for blocks normally so can insert gotos, etc. */
436 if (stp->st_unbhead)
437 {
438 unbstp = __alloc_stmt(S_UNBLK);
439 unbstp->st.sbsts = stp;
440 unbstp->stfnam_ind = sfnind;
441 unbstp->stlin_cnt = slcnt;
442 stp = unbstp;
443 }
444 /* try to parse as much as possible even if errors */
445 if (last_stp == NULL) *stpp = stp; else last_stp->stnxt = stp;
446 /* for returns 2 statement list - since reading list just 1 longer */
447 if (stp->stmttyp == S_FORASSGN) last_stp = stp->stnxt;
448 else last_stp = stp;
449 __get_vtok();
450 if (__toktyp == endbtok) break;
451 }
452 return(TRUE);
453 }
454
455 /*
456 * read a named block
457 * know : read and reads block end token
458 * notice named block linked on task list and from stmt
459 * also notice body is pointer to statement that may or may not be list
460 */
rd_namblock(int32 btok,int32 endbtok,int32 slcnt,int32 sfnind)461 static struct st_t *rd_namblock(int32 btok, int32 endbtok, int32 slcnt,
462 int32 sfnind)
463 {
464 struct task_t *sav_cur_tsk;
465 struct st_t *hdstp, *stp;
466
467 __get_vtok();
468 if (__toktyp != ID)
469 {
470 __pv_ferr(1063, "block label expected - %s read - skipped",
471 __prt_kywrd_vtok());
472 /* here just assume left out */
473 strcpy(__token, "**filler**");
474 __toktyp = ID;
475 __unget_vtok();
476 }
477 /* save cur. task - since recursively called and on stack nesting, works */
478 sav_cur_tsk = __cur_tsk;
479
480 /* this increments top sti and changes current task */
481 /* if error here, must give up - find like level end */
482 if (!__bld_tsk(__token, btok))
483 {
484 __find_matchendblk(btok, endbtok);
485 return(NULL);
486 }
487 /* illegal I/O decls here caught later */
488 __get_vtok();
489 /* allocate even though wasted if error since need line no. */
490 stp = __alloc_stmt(S_NAMBLK);
491 /* correct to line of begin */
492 stp->stlin_cnt = slcnt;
493 stp->stfnam_ind = sfnind;
494
495 /* statement has a task body as it data */
496 stp->st.snbtsk = __cur_tsk;
497 /* also fill back ptr to the one location named block task in */
498 __cur_tsk->st_namblkin = stp;
499
500 /* continues through all decls - even if error, if F then must give up */
501 /* T possible on error if hit statement */
502 if (!__rd_tfdecls("named block"))
503 {
504 __find_matchendblk(btok, endbtok);
505 bad_end:
506 __top_sti--;
507 __cur_tsk = sav_cur_tsk;
508 return(NULL);
509 }
510 /* according to grammar this must be a statement list */
511 /* format is begin/fork : [name] [decls?] [stmt list] end/join */
512 /* this will have sync to end of block - or mod/file level thing */
513 /* SJM 10/19/05 - line count and file arguments name were reversed */
514 if (!rd_lstofsts(endbtok, &hdstp, slcnt, sfnind)) goto bad_end;
515 __cur_tsk->tsk_last_lini = __lin_cnt;
516 __cur_tsk->tsk_last_ifi = __cur_fnam_ind;
517
518 /* symbols no longer accessible */
519 __top_sti--;
520 if (btok == Begin) __cur_tsk->tskst = hdstp;
521 else __cur_tsk->tskst = convert_to_fork(hdstp);
522
523 /* must link named block on task list */
524 if (__end_tbp == NULL) __inst_mod->mtasks = __cur_tsk;
525 else __end_tbp->tsknxt = __cur_tsk;
526 __end_tbp = __cur_tsk;
527
528 __cur_tsk = sav_cur_tsk;
529 /* statement here is the pointer to the task */
530 return(stp);
531 }
532
533 /*
534 * find a matching end block (end or join)
535 */
__find_matchendblk(int32 btok,int32 endbtok)536 extern void __find_matchendblk(int32 btok, int32 endbtok)
537 {
538 int32 blklev = 0;
539
540 for (;;)
541 {
542 if (__syncto_class != SYNC_STMT) return;
543 if (__vskipto2_any(btok, endbtok))
544 {
545 if (__toktyp == endbtok) { if (blklev <= 0) return; blklev--; }
546 else blklev++;
547 }
548 }
549 }
550
551 /*
552 * read if statement - if keyword read, reads statement end token
553 */
rd_if(void)554 static struct st_t *rd_if(void)
555 {
556 struct st_t *stp, *thenstp, *elsestp;
557 struct expr_t *ifxnd;
558 int32 slcnt, sfnind;
559
560 slcnt = __lin_cnt;
561 sfnind = __cur_fnam_ind;
562 __get_vtok();
563 if (__toktyp != LPAR)
564 {
565 __pv_ferr(1064, "if not followed by required left parenthesis - %s read",
566 __prt_vtok());
567 sync_xpr:
568 __vskipto3_any(RPAR, ELSE, SEMI);
569 if (__syncto_class == SYNC_TARG)
570 {
571 __set_xtab_errval();
572 __bld_xtree(0);
573 ifxnd = __root_ndp;
574 if (__toktyp == RPAR) goto rd_then;
575 thenstp = __alloc_stmt(S_NULL);
576 if (__toktyp == ELSE) goto rd_else;
577 /* skipped to ; */
578 goto maybe_else;
579 }
580 if (__syncto_class == SYNC_STMT)
581 {
582 __set_xtab_errval();
583 __bld_xtree(0);
584 ifxnd = __root_ndp;
585 goto rd_then;
586 }
587 /* something completely out of place */
588 __get_vtok();
589 return(NULL);
590 }
591 __get_vtok();
592 /* collection routines that fail must emit error */
593 if (!__col_parenexpr(-1))
594 {
595 goto sync_xpr;
596 }
597 /* need to build and save expr */
598 __bld_xtree(0);
599 ifxnd = __root_ndp;
600
601 rd_then:
602 __get_vtok();
603 if ((thenstp = __rd_stmt()) == NULL)
604 {
605 if (__syncto_class == SYNC_STMT || (__syncto_class == SYNC_TARG
606 && __toktyp == SEMI))
607 {
608 thenstp = __alloc_stmt(S_NULL);
609 goto maybe_else;
610 }
611 /* anything else - return and caller syncs */
612 return(NULL);
613 }
614 maybe_else:
615 __get_vtok();
616 if (__toktyp == ELSE)
617 {
618 rd_else:
619 __get_vtok();
620 if ((elsestp = __rd_stmt()) == NULL) return(NULL);
621 }
622 /* should try to get rid of this unget */
623 else
624 {
625 /* unget needed because routines expect to read 1st st. token */
626 if (__iact_state)
627 {
628 __pv_err_cnt++;
629 __ia_err(1432, "interactive if statement required else missing");
630 return(NULL);
631 }
632 __unget_vtok();
633 elsestp = NULL;
634 }
635 stp = __alloc_stmt(S_IF);
636 /* correct to line of if */
637 stp->stlin_cnt = slcnt;
638 stp->stfnam_ind = sfnind;
639
640 stp->st.sif.condx = ifxnd;
641 stp->st.sif.thenst = thenstp;
642 stp->st.sif.elsest = elsestp;
643 return(stp);
644 }
645
646 /*
647 * know case/casex,casez keyword read and reads endcase
648 */
rd_case(int32 casttyp)649 static struct st_t *rd_case(int32 casttyp)
650 {
651 struct st_t *casp, *dflsp, *stp;
652 struct csitem_t *cip, *last_cip, *csihdr, *dflt_csip;
653 struct expr_t *csndp;
654 struct exprlst_t *csixhdr, *xplp, *last_xplp;
655 int32 slcnt, sfnind;
656
657 slcnt = __lin_cnt;
658 sfnind = __cur_fnam_ind;
659
660 __get_vtok();
661 if (__toktyp != LPAR)
662 {
663 __pv_ferr(1065,
664 "case statement selection expression left parenthesis expected - %s read",
665 __prt_vtok());
666 bad_csx:
667 if (__vskipto2_any(RPAR, SEMI)) { __set_xtab_errval(); goto bld_csx; }
668 return(NULL);
669 }
670 __get_vtok();
671 if (!__col_parenexpr(-1)) goto bad_csx;
672 bld_csx:
673 __bld_xtree(0);
674 csndp = __root_ndp;
675 for (last_cip = NULL, csihdr = NULL, dflsp = NULL;;)
676 {
677 __get_vtok();
678 switch ((byte) __toktyp) {
679 case ENDCASE: goto bld_case;
680 case DEFAULT:
681 do_dflt:
682 __get_vtok();
683 if (__toktyp == COLON) __get_vtok();
684 if (dflsp != NULL)
685 __pv_ferr(1067, "more than one case default item not permitted");
686 if ((dflsp = __rd_stmt()) == NULL)
687 {
688 if (__vskipto_any(SEMI)) continue;
689 /* here must skip to endcase of right level and return */
690 give_up:
691 __find_matchendcase();
692 return(NULL);
693 }
694 continue;
695 default:
696 /* expr. collection will fail if not required one expr. */
697 for (last_xplp = NULL, csixhdr = NULL;;)
698 {
699 more_xprs:
700 if (!__col_caseexpr())
701 {
702 if (__vskipto3_any(COLON, SEMI, COMMA))
703 {
704 if (__toktyp == SEMI) goto nxt_case;
705 __set_xtab_errval();
706 }
707 else goto give_up;
708 }
709 __bld_xtree(0);
710 /* allocate and link in the expression list item */
711 xplp = __alloc_xprlst();
712 xplp->xp = __root_ndp;
713 if (last_xplp == NULL) csixhdr = xplp; else last_xplp->xpnxt = xplp;
714 last_xplp = xplp;
715
716 if (__toktyp != COMMA) break;
717 __get_vtok();
718 }
719 if (__toktyp != COLON)
720 {
721 __pv_ferr(1068, "case item expression list colon expected - %s read",
722 __prt_vtok());
723 if (__vskipto3_any(COLON, SEMI, COMMA))
724 {
725 if (__toktyp == SEMI) continue;
726 if (__toktyp == COLON) goto do_cstmt;
727 goto more_xprs;
728 }
729 else goto give_up;
730 }
731 do_cstmt:
732 __get_vtok();
733 /* ; null statement ok here */
734 if ((casp = __rd_stmt()) == NULL)
735 {
736 if (__vskipto2_any(SEMI, DEFAULT))
737 {
738 if (__toktyp == DEFAULT) goto do_dflt;
739 continue;
740 }
741 else goto give_up;
742 }
743 /* allocate and link in the case item element */
744 cip = __alloc_csitem();
745 cip->csixlst = csixhdr;
746 cip->csist = casp;
747 if (last_cip == NULL) csihdr = cip; else last_cip->csinxt = cip;
748 last_cip = cip;
749 }
750 nxt_case:;
751 }
752 bld_case:
753 stp = __alloc_stmt(S_CASE);
754 /* correct to line of case */
755 stp->stlin_cnt = slcnt;
756 stp->stfnam_ind = sfnind;
757
758 stp->st.scs.castyp = casttyp;
759 stp->st.scs.csx = csndp;
760
761 /* SJM 08/27/99 - change so no default in case rec but first on item list */
762 dflt_csip = __alloc_csitem();
763 dflt_csip->csixlst = NULL;
764 /* no default: indicated by first nil */
765 if (dflsp != NULL) dflt_csip->csist = dflsp; else dflt_csip->csist = NULL;
766
767 /* link onto front of list */
768 dflt_csip->csinxt = csihdr;
769 stp->st.scs.csitems = dflt_csip;
770 return(stp);
771 }
772
773 /*
774 * find a matching endcase
775 */
__find_matchendcase(void)776 extern void __find_matchendcase(void)
777 {
778 int32 caselev = 0;
779 for (;;)
780 {
781 if (__syncto_class != SYNC_STMT) return;
782 if (__vskipto4_any(ENDCASE, CASE, CASEX, CASEZ))
783 {
784 if (__toktyp == ENDCASE) { if (caselev <= 0) return; caselev--; }
785 else caselev++;
786 }
787 else return;
788 }
789 }
790
791 /*
792 * allocate an expression list element
793 */
__alloc_xprlst(void)794 extern struct exprlst_t *__alloc_xprlst(void)
795 {
796 struct exprlst_t *xplp;
797
798 xplp = (struct exprlst_t *) __my_malloc(sizeof(struct exprlst_t));
799 xplp->xp = NULL;
800 xplp->xpnxt = NULL;
801 return(xplp);
802 }
803
804 /*
805 * allocate a case item - case statement is list of case items
806 */
__alloc_csitem(void)807 extern struct csitem_t *__alloc_csitem(void)
808 {
809 struct csitem_t *cip;
810
811 cip = (struct csitem_t *) __my_malloc(sizeof(struct csitem_t));
812 cip->csixlst = NULL;
813 cip->csist = NULL;
814 cip->csinxt = NULL;
815 return(cip);
816 }
817
818 /*
819 * read a simple (non for) loop statement
820 */
rd_loop(int32 ttyp)821 static struct st_t *rd_loop(int32 ttyp)
822 {
823 struct st_t *stp, *repstp;
824 struct expr_t *loopx;
825 char s1[RECLEN];
826
827 /* notice this is done at 1st statement so no line number fix up */
828 if (ttyp == REPEAT) stp = __alloc_stmt(S_REPEAT);
829 else if (ttyp == WAIT) stp = __alloc_stmt(S_WAIT);
830 else stp = __alloc_stmt(S_WHILE);
831 loopx = NULL;
832 repstp = NULL;
833
834 switch ((byte) ttyp) {
835 case FOREVER:
836 /* first build proc assign */
837 stp->stmttyp = S_FOREVER;
838 loopx = NULL;
839 __get_vtok();
840 if ((repstp = __rd_stmt()) == NULL) return(NULL);
841 break;
842 case REPEAT:
843 stp->stmttyp = S_REPEAT;
844 goto get_expr;
845 case WHILE:
846 stp->stmttyp = S_WHILE;
847 goto get_expr;
848 case WAIT:
849 stp->stmttyp = S_WAIT;
850 /* here because wait expression globals need special xmrtype fields */
851 get_expr:
852 __get_vtok();
853 if (__toktyp != LPAR)
854 {
855 __pv_ferr(1070,
856 "%s loop statement conditional expression not preceded by left parenthesis - %s read",
857 __get_vkeynam(s1, ttyp), __prt_vtok());
858 sync_lpx:
859 if (__vskipto2_any(SEMI, RPAR))
860 {
861 if (__toktyp == RPAR) { __set_xtab_errval(); goto bldx; }
862 __syncto_class = SYNC_STMT;
863 }
864 /* here have synced to beginning of next statement */
865 return(NULL);
866 }
867 __get_vtok();
868 if (!__col_parenexpr(-1)) goto sync_lpx;
869 bldx:
870 __bld_xtree(0);
871 loopx = __root_ndp;
872 __get_vtok();
873 if ((repstp = __rd_stmt()) == NULL) return(NULL);
874 break;
875 default: __case_terr(__FILE__, __LINE__);
876 }
877 /* repeat tmp per inst. storage filed not set till preparation phase */
878 if (stp->stmttyp == S_REPEAT)
879 { stp->st.srpt.repx = loopx; stp->st.srpt.repst = repstp; }
880 else if (stp->stmttyp == S_WAIT)
881 { stp->st.swait.lpx = loopx; stp->st.swait.lpst = repstp; }
882 else { stp->st.swh.lpx = loopx; stp->st.swh.lpst = repstp; }
883 return(stp);
884 }
885
886 /*
887 * read a for statement
888 * know for token read and reads end of for body
889 * notice this returns 2 statement short list (since unnamed begin
890 * returns list - this always is ok)
891 */
rd_for(void)892 static struct st_t *rd_for(void)
893 {
894 struct for_t *frs;
895 struct st_t *stp, *inita, *inca, *forbd;
896 struct expr_t *lhsndp, *rhsndp, *stopndp;
897 int32 slcnt, sfnind;
898
899 slcnt = __lin_cnt;
900 sfnind = __cur_fnam_ind;
901
902 /* must read expressions separately for assigns */
903 /* first build initialization assign */
904 __get_vtok();
905 if (__toktyp != LPAR)
906 {
907 __pv_ferr(1071,
908 "for statement left parenthesis expected - %s read", __prt_vtok());
909 bad_for:
910 if (__vskipto2_any(RPAR, SEMI))
911 {
912 if (__toktyp == SEMI) { inita = __alloc_stmt(S_NULL); goto bldtrmx; }
913 }
914 rd_forst:
915 /* if module or file level item, just return caller will resync */
916 if (__syncto_class == SYNC_STMT || __syncto_class == SYNC_TARG)
917 {
918 __get_vtok();
919 __rd_stmt();
920 }
921 return(NULL);
922 }
923 __get_vtok();
924 /* collect lhs to = */
925 if (!__col_lval()) goto bad_for;
926 __bld_xtree(0);
927 lhsndp = __root_ndp;
928 __get_vtok();
929 if (!__col_comsemi(-1)) goto bad_for;
930 if (__toktyp != SEMI)
931 {
932 __pv_ferr(1076,
933 "for statement initial assignment ending semicolon expected - %s read",
934 __prt_vtok());
935 __vskipto_any(RPAR);
936 goto rd_forst;
937 }
938
939 __bld_xtree(0);
940 rhsndp = __root_ndp;
941 /* build proc assign */
942 inita = __alloc_stmt(S_FORASSGN);
943 inita->st.spra.lhsx = lhsndp;
944 inita->st.spra.rhsx = rhsndp;
945
946 /* build termination expression */
947 bldtrmx:
948 __get_vtok();
949 if (!__col_comsemi(-1))
950 {
951 if (__vskipto2_any(RPAR, SEMI))
952 {
953 if (__toktyp == SEMI) { __set_xtab_errval(); goto bldcondx; }
954 }
955 goto rd_forst;
956 }
957 if (__toktyp != SEMI)
958 {
959 __pv_ferr(1078,
960 "for statement termination expression ending semicolon expected - %s read",
961 __prt_vtok());
962 __vskipto_any(RPAR);
963 goto rd_forst;
964 }
965
966 bldcondx:
967 __bld_xtree(0);
968 stopndp = __root_ndp;
969
970 /* collect assignment ending in ) */
971 __get_vtok();
972 /* collect lhs to = - this can only end with = */
973 if (!__col_lval())
974 {
975 bad2_for:
976 if (__vskipto_any(RPAR)) { inca = __alloc_stmt(S_NULL); goto do_body; }
977 goto rd_forst;
978 }
979
980 __bld_xtree(0);
981 lhsndp = __root_ndp;
982 __get_vtok();
983 if (!__col_parenexpr(-1)) goto bad2_for;
984 __bld_xtree(0);
985 rhsndp = __root_ndp;
986
987 /* build proc assign */
988 inca = __alloc_stmt(S_PROCA);
989 inca->st.spra.lhsx = lhsndp;
990 inca->st.spra.rhsx = rhsndp;
991
992 do_body:
993 __get_vtok();
994 if ((forbd = __rd_stmt()) == NULL) return(NULL);
995
996 stp = __alloc_stmt(S_FOR);
997 /* correct to line of for */
998 stp->stlin_cnt = slcnt;
999 stp->stfnam_ind = sfnind;
1000
1001 frs = stp->st.sfor;
1002 frs->forassgn = inita;
1003 frs->fortermx = stopndp;
1004 frs->forinc = inca;
1005 frs->forbody = forbd;
1006 /* notice for assign (initializer) inserted before for but for assgn */
1007 /* still points back to it */
1008 inita->stnxt = stp;
1009 return(inita);
1010 }
1011
1012 /*
1013 * read a -> cause statement, know -> read and read ending ;
1014 */
rd_cause(void)1015 static struct st_t *rd_cause(void)
1016 {
1017 struct st_t *stp;
1018 struct sy_t *syp;
1019
1020 __get_vtok();
1021 if (!__col_comsemi(-1))
1022 {
1023 skp_end:
1024 __vskipto_any(SEMI);
1025 return(NULL);
1026 }
1027 if (__toktyp != SEMI)
1028 {
1029 __pv_ferr(1072, "cause statement semicolon expected - %s read",
1030 __prt_vtok());
1031 goto skp_end;
1032 }
1033 __bld_xtree(0);
1034 /* this error does not effect synchronization */
1035 if (__root_ndp->optyp != ID && __root_ndp->optyp != GLBREF)
1036 __pv_ferr(1073, "cause statement event name expected");
1037 if (__toktyp == ID)
1038 {
1039 syp = __root_ndp->lu.sy;
1040 /* if net wire and not declared, convert to event wire */
1041 if (syp->sytyp == SYM_N && !syp->sydecl) syp->el.enp->ntyp = N_EVENT;
1042 /* declaration errors caught later */
1043 }
1044 stp = __alloc_stmt(S_CAUSE);
1045 stp->st.scausx = __root_ndp;
1046 return(stp);
1047 }
1048
1049 /*
1050 * read a disable statement - must be check later
1051 * know disable read
1052 */
rd_disable(void)1053 static struct st_t *rd_disable(void)
1054 {
1055 struct st_t *stp;
1056 struct expr_t *dsxndp;
1057 struct expridtab_t *xidp;
1058
1059 __get_vtok();
1060 if (!__col_comsemi(-1))
1061 {
1062 __vskipto_any(SEMI);
1063 return(NULL);
1064 }
1065 if (__toktyp != SEMI)
1066 {
1067 __pv_ferr(1129, "disable statement semicolon expected - %s read",
1068 __prt_vtok());
1069 return(NULL);
1070 }
1071 /* tricky code for simple local just ID task/named block disable */
1072 /* can not parse because will be found incorrectly as local wire */
1073 /* this is side effect of stupid xmr as expression new feature */
1074 /* ending fence undef not yet added because bld xtree not called */
1075 if (__last_xtk == 0 && __exprtab[0]->optyp == ID)
1076 {
1077 /* must allocate name of task or fixup if previously used */
1078 xidp = __expr_idtab[0];
1079 if ((dsxndp = find_bldxpr_tfsy(xidp->idnam, UNDEF)) == NULL) return(NULL);
1080
1081 /* also can't disable funcs - because run in no time but caught later */
1082 stp = __alloc_stmt(S_DSABLE);
1083 stp->st.sdsable.dsablx = dsxndp;
1084 return(stp);
1085 }
1086 /* this must be xmr - because xmr now expressions must parse to construct */
1087 __bld_xtree(0);
1088 dsxndp = __root_ndp;
1089 if (dsxndp->optyp != GLBREF)
1090 {
1091 __pv_ferr(1074,
1092 "disable statement hierarchical named block or task name reference expected - %s read",
1093 __msgexpr_tostr(__xs, dsxndp));
1094 return(NULL);
1095 }
1096 stp = __alloc_stmt(S_DSABLE);
1097 stp->st.sdsable.dsablx = dsxndp;
1098 return(stp);
1099 }
1100
1101 /*
1102 * find (and maybe add) task symbol - only called for enable/disable
1103 * know definition at top mod level and non gref
1104 * may get here on named block disable (tfsytyp UNDEF) or enable
1105 */
find_bldxpr_tfsy(char * nam,int32 tfsytyp)1106 static struct expr_t *find_bldxpr_tfsy(char *nam, int32 tfsytyp)
1107 {
1108 struct expr_t *enable_ndp;
1109 struct sy_t *syp;
1110
1111 /* if id declared in currently accessible name evironment use it */
1112 if ((syp = __get_sym_env(nam)) != NULL)
1113 {
1114 /* if disable must check in disable statement fixup */
1115 if (tfsytyp != UNDEF)
1116 {
1117 /* error if declared or used as non task */
1118 /* illegal to enable or disable a function */
1119 switch ((byte) syp->sytyp) {
1120 case SYM_F: case SYM_I: case SYM_M: case SYM_PRIM: case SYM_UDP:
1121 case SYM_N: case SYM_DEF:
1122 {
1123 char s1[RECLEN], s2[RECLEN];
1124
1125 if (syp->sydecl) strcpy(s1, "declared"); else strcpy(s1, "used");
1126 __to_sytyp(s2, syp->sytyp);
1127 __pv_ferr(963, "task or named block %s previously %s as %s at %s",
1128 syp->synam, s1, s2, __bld_lineloc(__xs, syp->syfnam_ind,
1129 syp->sylin_cnt));
1130 return(NULL);
1131 }
1132 }
1133 }
1134 /* rest of fields gets filled later - notice no width not in expr */
1135 enable_ndp = __alloc_newxnd();
1136 enable_ndp->optyp = ID;
1137 enable_ndp->lu.sy = syp;
1138 return(enable_ndp);
1139 }
1140 /* error if not declared in interactive command input */
1141 if (__iact_state)
1142 {
1143 __pv_err_cnt++;
1144 __ia_err(1435, "task or named block %s undeclared", nam);
1145 return(NULL);
1146 }
1147
1148 enable_ndp = __alloc_newxnd();
1149 enable_ndp->optyp = ID;
1150
1151 /* here building the enable so just need to pass place holder - for fcall */
1152 /* need the parsed expr where its insides are changed to xmr */
1153 cnvt_forw_tfcall_1cmpglb(enable_ndp, nam, __cur_fnam_ind, __lin_cnt);
1154 return(enable_ndp);
1155 }
1156
1157 /*
1158 * read proc. quasi-cont assign - normal wire assign but only enable when
1159 * time token moves here, force for wires and 2nd level of qc assign
1160 */
rd_wireassign(int32 qcattyp)1161 static struct st_t *rd_wireassign(int32 qcattyp)
1162 {
1163 struct st_t *stp;
1164 struct expr_t *lhsndp, *rhsndp;
1165
1166 /* allocate at top (wastes storage on error) to get line no. right */
1167 stp = __alloc_stmt(S_QCONTA);
1168 /* collect lhs to = */
1169 __get_vtok();
1170 if (!__col_lval())
1171 {
1172 bad_qassgn:
1173 __vskipto_any(SEMI);
1174 return(NULL);
1175 }
1176 __bld_xtree(0);
1177 /* must check later to make sure lvalue */
1178 lhsndp = __root_ndp;
1179
1180 __get_vtok();
1181 if (!__col_comsemi(-1)) goto bad_qassgn;
1182 if (__toktyp != SEMI)
1183 {
1184 char s1[RECLEN];
1185
1186 if (qcattyp == FORCE) strcpy(s1, "force");
1187 else if (qcattyp == ASSIGN) strcpy(s1, "quasi-continuous assign");
1188 else __case_terr(__FILE__, __LINE__);
1189
1190 __pv_ferr(1076, "%s statement ending semicolon expected - %s read", s1,
1191 __prt_vtok());
1192 goto bad_qassgn;
1193 }
1194 __bld_xtree(0);
1195 rhsndp = __root_ndp;
1196
1197 /* build quasi cont. assign */
1198 stp->st.sqca->qcatyp = qcattyp;
1199 /* assume reg. form - requried for assign/deassign */
1200 stp->st.sqca->regform = TRUE;
1201 stp->st.sqca->qclhsx = lhsndp;
1202 stp->st.sqca->qcrhsx = rhsndp;
1203 stp->st.sqca->rhs_qcdlstlst = NULL;
1204 return(stp);
1205 }
1206
1207 /*
1208 * read wire deassign/release (difference is force arg. can be wire)
1209 * form is deassign/release [lvalue];
1210 */
rd_wiredeassign(int32 qcdeattyp)1211 static struct st_t *rd_wiredeassign(int32 qcdeattyp)
1212 {
1213 struct st_t *stp;
1214
1215 /* allocate at top (wastes storage on error) to get line no. right */
1216 stp = __alloc_stmt(S_QCONTDEA);
1217 /* collect lhs to = */
1218 __get_vtok();
1219 if (!__col_comsemi(-1))
1220 {
1221 skp_end:
1222 __vskipto_any(SEMI);
1223 return(NULL);
1224 }
1225 if (__toktyp == COMMA)
1226 {
1227 char s1[RECLEN];
1228
1229 __pv_ferr(1077, "%s statement ending semicolon expected - %s read",
1230 __get_vkeynam(s1, qcdeattyp), __prt_vtok());
1231 goto skp_end;
1232 }
1233 __bld_xtree(0);
1234
1235 /* build quasi cont. assign */
1236 stp->st.sqcdea.qcdatyp = qcdeattyp;
1237 /* assume reg. form */
1238 stp->st.sqcdea.regform = TRUE;
1239 stp->st.sqcdea.qcdalhs = __root_ndp;
1240 return(stp);
1241 }
1242
1243 /*
1244 * read and build task enable or procedural assignment statement
1245 *
1246 * expects 1st lhs element (ID or '{')to have been read
1247 * reads stmt ending ;
1248 *
1249 * for assign builds blocking or non blocking rhs del ctrl assign
1250 * uses 1st token as location for both delay control and action stmt
1251 *
1252 * notice for assign not read here - lhs and rhs read separately
1253 * notice recovery here can just be skip to ; [if correct must appear]
1254 */
rd_taske_or_proc_assign(void)1255 static struct st_t *rd_taske_or_proc_assign(void)
1256 {
1257 int32 dtyp, is_nb, slcnt, sfnind, is_evctl_impl;
1258 struct st_t *stp, *dcstp;
1259 struct expr_t *lhsndp, *rhsndp, *delxndp, *repcntx;
1260 struct delctrl_t *dctp;
1261 struct paramlst_t *pmp;
1262 char s1[IDLEN];
1263
1264 slcnt = __lin_cnt;
1265 sfnind = __cur_fnam_ind;
1266
1267 /* collect lhs to '=' or '(' or ';' (for task enable) else fails */
1268 if (!col2_lval())
1269 {
1270 bad_assgn:
1271 __vskipto_any(SEMI);
1272 return(NULL);
1273 }
1274 /* case 1: ID task enable, not parsed need special task sy decl */
1275 if (__toktyp == LPAR || __toktyp == SEMI)
1276 {
1277 if (__last_xtk != 0 || __exprtab[0]->optyp != ID) goto try_parsing;
1278 /* on error returns nil and that is also returned from here */
1279 /* notice must copy expr idtab value because overwritten by parsing */
1280 strcpy(s1, __expr_idtab[0]->idnam);
1281 stp = __rd_tskenable(s1, NULL, FALSE);
1282 return(stp);
1283 }
1284
1285 try_parsing:
1286 __bld_xtree(0);
1287 lhsndp = __root_ndp;
1288 /* case 1a: xmr task enable */
1289 if (__toktyp == LPAR || __toktyp == SEMI)
1290 {
1291 /* error if enable anything but xmr */
1292 if (lhsndp->optyp != GLBREF)
1293 {
1294 __pv_ferr(1086,
1295 "attempted task enable of %s - maybe assignment = missing",
1296 __msgexpr_tostr(__xs, lhsndp));
1297 goto bad_assgn;
1298 }
1299 stp = __rd_tskenable(NULL, lhsndp, TRUE);
1300 return(stp);
1301 }
1302
1303 /* case 2: assign */
1304 /* for now block procedural assignment not supported */
1305 if (__toktyp == RELLE) is_nb = TRUE; else is_nb = FALSE;
1306 /* must check later to make sure lvalue */
1307
1308 __get_vtok();
1309
1310 /* handle optional rhs delay control */
1311 /* 10/27/00 SJM - add support for rhs repeat delay control forms */
1312 repcntx = NULL;
1313 if (__toktyp == REPEAT)
1314 {
1315 __get_vtok();
1316 /* surrounding parentheses required by syntax */
1317 if (__toktyp != LPAR)
1318 {
1319 __pv_ferr(3413,
1320 "repeat event control count expression beginning left parenthesis expected - %s read",
1321 __prt_vtok());
1322 goto bad_assgn;
1323 }
1324 __get_vtok();
1325 /* this read trailing left parenthsis - here syncing only to ; */
1326 if (!__col_parenexpr(-1)) goto bad_assgn;
1327
1328 __bld_xtree(0);
1329 repcntx = __root_ndp;
1330 /* read the delay control so can sync to normal rhs event control case */
1331 __get_vtok();
1332 if (__toktyp != AT)
1333 {
1334 __pv_ferr(3414,
1335 "repeat event control count expression not followed by event control at sign - %s read",
1336 __prt_vtok());
1337 goto bad_assgn;
1338 }
1339 /* set flag and fall thru - now same as normal rhs event control */
1340 }
1341
1342 dtyp = DC_NONE;
1343 if (__toktyp == SHARP || __toktyp == AT)
1344 {
1345 /* know this reads one past end of delay control */
1346 if ((delxndp = rd_delctrl(&dtyp, &is_evctl_impl)) == NULL)
1347 {
1348 if (dtyp == DC_EVENT && is_evctl_impl)
1349 {
1350 __pv_ferr(3427,
1351 "right hand side event control implicit form @(*) illegal");
1352 }
1353 goto bad_assgn;
1354 }
1355 if (dtyp == DC_EVENT) dtyp = DC_RHSEVENT;
1356 else if (dtyp == DC_DELAY) dtyp = DC_RHSDELAY;
1357 }
1358 else delxndp = NULL;
1359
1360 /* this reads end ; */
1361 if (!__col_comsemi(-1)) goto bad_assgn;
1362 if (__toktyp != SEMI)
1363 {
1364 __pv_ferr(1078,
1365 "assignment statement ending semicolon expected - %s read", __prt_vtok());
1366 goto bad_assgn;
1367 }
1368
1369 __bld_xtree(0);
1370 rhsndp = __root_ndp;
1371
1372 /* first build proc assign */
1373 if (!is_nb)
1374 {
1375 if (dtyp == DC_RHSEVENT || dtyp == DC_RHSDELAY)
1376 stp = __alloc_stmt(S_RHSDEPROCA);
1377 else stp = __alloc_stmt(S_PROCA);
1378 }
1379 else stp = __alloc_stmt(S_NBPROCA);
1380 stp->st.spra.lhsx = lhsndp;
1381 stp->st.spra.rhsx = rhsndp;
1382 stp->stlin_cnt = slcnt;
1383 stp->stfnam_ind = sfnind;
1384
1385 if (delxndp == NULL) return(stp);
1386
1387 dcstp = __alloc_stmt(S_DELCTRL);
1388 dcstp->stlin_cnt = slcnt;
1389 dcstp->stfnam_ind = sfnind;
1390
1391 dctp = dcstp->st.sdc;
1392 dctp->dctyp = dtyp;
1393 dctp->dc_delrep = DT_CMPLST;
1394 pmp = __alloc_pval();
1395 pmp->plxndp = delxndp;
1396 dctp->dc_du.pdels = pmp;
1397 /* 10/28/00 SJM - only indication of rep form is repeat cnt expr non nil */
1398 dctp->repcntx = repcntx;
1399 /* 06/11/02 SJM - need to indicate non blocking rhs ev ctrl in dc evnt */
1400 if (is_nb) dctp->dc_nblking = TRUE;
1401
1402 dctp->dceschd_tevs = NULL;
1403
1404 dctp->actionst = stp;
1405 return(dcstp);
1406 }
1407
1408 /*
1409 * read a task enable (call) statement
1410 *
1411 * '(' or ';' (if no args read and reads ending ;
1412 * need special parsing for system task since ,, form legal there
1413 */
__rd_tskenable(char * tknam,struct expr_t * glbndp,int32 is_glbenable)1414 extern struct st_t *__rd_tskenable(char *tknam, struct expr_t *glbndp,
1415 int32 is_glbenable)
1416 {
1417 register int32 i;
1418 int32 rd_semi, nd_glb_conv;
1419 struct sy_t *syp;
1420 struct st_t *stp;
1421 struct tskcall_t *tkcp;
1422 struct expr_t *last_fcomxp, *lop;
1423 struct expr_t *enable_ndp;
1424 struct systsk_t *stbp;
1425
1426 rd_semi = FALSE;
1427 nd_glb_conv = FALSE;
1428 stbp = NULL;
1429 /* case 1: parsed global ref enable */
1430 if (is_glbenable)
1431 {
1432 stp = __alloc_stmt(S_TSKCALL);
1433 tkcp = &(stp->st.stkc);
1434 /* notice there is no tkexp lu. sy here */
1435 tkcp->tsksyx = glbndp;
1436 tknam = glbndp->ru.grp->gnam;
1437 goto get_args;
1438 }
1439
1440 /* DBG remove --- */
1441 if (tknam == NULL) __arg_terr(__FILE__, __LINE__);
1442 /* --- */
1443 /* case 2 simple ID enable - not parsed */
1444 if (*tknam == '$')
1445 {
1446 /* look up in special system func. and task symbol table */
1447 if ((syp = __get_sym(tknam, __syssyms)) == NULL)
1448 {
1449 /* this is completely unknown case */
1450 __pv_ferr(1083,
1451 "task enable of unknown system task or undefined PLI task \"%s\"",
1452 tknam);
1453 goto err_end;
1454 }
1455 stbp = syp->el.esytbp;
1456 if (syp->sytyp != SYM_STSK)
1457 {
1458 __pv_ferr(1080, "task enable of system function \"%s\" illegal",
1459 syp->synam);
1460 goto err_end;
1461 }
1462 /* systam task table inconsistent - value is 0 */
1463 if (stbp->stsknum == 0) __misc_fterr(__FILE__, __LINE__);
1464
1465 /* need location for xmr type setting */
1466 switch (stbp->stsknum) {
1467 case STN_MONITOR: case STN_MONITORB: case STN_MONITORH: case STN_MONITORO:
1468 if (__iact_state && __optimized_sim)
1469 {
1470 opt_dbg_illegal:
1471 /* SJM 01/02/03 - can't call $dumpvars system task from iact */
1472 /* from interactive debugger if -O on */
1473 __pv_ferr(2901,
1474 "system task %s can't be called from debugger when optimizer on - run without -O",
1475 syp->synam);
1476 goto err_end;
1477 }
1478 break;
1479 /* these can have module/inst. ending xmrs */
1480 case STN_DUMPVARS:
1481 if (__iact_state && __optimized_sim) goto opt_dbg_illegal;
1482 nd_glb_conv = TRUE;
1483 break;
1484 case STN_SDF_ANNOTATE:
1485 case STN_PRINTTIMESCALE: case STN_SCOPE: case STN_LIST:
1486 nd_glb_conv = TRUE;
1487 break;
1488 default:
1489 /* PLI system tasks/functions always allow XMR's */
1490 if (stbp->stsknum >= BASE_VERIUSERTFS
1491 && (int32) stbp->stsknum <= __last_systf) nd_glb_conv = TRUE;
1492 break;
1493 }
1494 enable_ndp = __alloc_newxnd();
1495 enable_ndp->optyp = ID;
1496 enable_ndp->lu.sy = syp;
1497 }
1498 else
1499 {
1500 /* if user task not declared must add to symbol table */
1501 /* return of NULL to here on error - message already written */
1502 if ((enable_ndp = find_bldxpr_tfsy(tknam, SYM_TSK)) == NULL)
1503 {
1504 err_end:
1505 __vskipto_any(SEMI);
1506 return(NULL);
1507 }
1508 }
1509 /* build the task enable statement */
1510 stp = __alloc_stmt(S_TSKCALL);
1511 tkcp = &(stp->st.stkc);
1512 tkcp->tsksyx = enable_ndp;
1513
1514 get_args:
1515 tkcp->targs = NULL;
1516 /* no arguments */
1517 if (__toktyp == SEMI) goto done;
1518
1519 /* build argument expressions in a list */
1520 __get_vtok();
1521 /* at this point ,, form ok (legal for system tasks? */
1522 for (last_fcomxp = NULL, i = 0;; i++)
1523 {
1524 /* ,, or ,) need to be check/fixed later */
1525 /* for display and other system task legal, but for user task error */
1526 if (__toktyp == COMMA || __toktyp == RPAR)
1527 {
1528 /* for xmr task enable, point to gnam - need for sys task testing */
1529 /* error messages */
1530 if (*tknam != '$')
1531 {
1532 __pv_ferr(1081,
1533 "user task %s enable empty '()' or ',,' argument form illegal (pos. %d)",
1534 tknam, i + 1);
1535 /* if error build rhs x, cannot be op empty for non system task */
1536 __set_xtab_errval();
1537 }
1538 else { __last_xtk = 0; __set_opempty(0); }
1539 goto do_parse;
1540 }
1541 /* by case code to allow special forms, made globals here */
1542 if (nd_glb_conv)
1543 {
1544 switch (stbp->stsknum) {
1545 /* for dumpvars all but 1st argument can be special form */
1546 case STN_DUMPVARS:
1547 if (i != 0) __allow_scope_var = TRUE;
1548 break;
1549 case STN_SDF_ANNOTATE:
1550 if (i == 1) __allow_scope_var = TRUE;
1551 break;
1552 /* case where all inst. forms */
1553 case STN_SCOPE: case STN_LIST: case STN_PRINTTIMESCALE:
1554 __allow_scope_var = TRUE;
1555 break;
1556 default:
1557 /* any argument to PLI system task can be xmr */
1558 if (stbp->stsknum >= BASE_VERIUSERTFS
1559 && (int32) stbp->stsknum <= __last_systf)
1560 {
1561 __allow_scope_var = TRUE;
1562 }
1563 else __case_terr(__FILE__, __LINE__);
1564 }
1565 }
1566 /* either path here turns off allowing scope var */
1567 if (!__col_connexpr(-1))
1568 {
1569 __allow_scope_var = FALSE;
1570 if (__vskipto3_any(COMMA, RPAR, SEMI))
1571 { if (__toktyp == SEMI) rd_semi = TRUE; }
1572 else goto err_end;
1573 /* if error build rhs x, then parse */
1574 __set_xtab_errval();
1575 }
1576
1577 do_parse:
1578 __bld_xtree(0);
1579 /* parsing in bld xtree used this flag to allow inst. ending global */
1580 /* so now must turn off in case turned on */
1581 __allow_scope_var = FALSE;
1582
1583 /* first arg. done for dumpvars - rest special inst xmr or wire form */
1584 lop = __alloc_newxnd();
1585 lop->optyp = FCCOM;
1586 lop->ru.x = NULL;
1587 lop->lu.x = __root_ndp;
1588
1589 if (last_fcomxp == NULL) tkcp->targs = lop; else last_fcomxp->ru.x = lop;
1590 last_fcomxp = lop;
1591 /* some kind of error, seen ;, all done - probably more errors */
1592 if (__toktyp == rd_semi) goto done;
1593 if (__toktyp == RPAR) break;
1594 __get_vtok();
1595 }
1596 /* assume just left out */
1597 __get_vtok();
1598 if (__toktyp != SEMI)
1599 {
1600 __pv_ferr(1084,
1601 "task enable statement semicolon expected - %s read", __prt_vtok());
1602 }
1603 done:
1604 return(stp);
1605 }
1606
1607 /*
1608 * read a delay/event control statement (non rhs)
1609 */
rd_dctrl_st(void)1610 static struct st_t *rd_dctrl_st(void)
1611 {
1612 int32 dtyp, slcnt, sfnind, is_evctl_impl;
1613 struct st_t *dcstp, *stp;
1614 struct expr_t *delxndp;
1615 struct delctrl_t *dctp;
1616 struct paramlst_t *pmp;
1617
1618 slcnt = __lin_cnt;
1619 sfnind = __cur_fnam_ind;
1620 is_evctl_impl = FALSE;
1621 /* this reads one past one control or one past ending ) */
1622 /* only NULL error if cannot sync to following stmt */
1623 if ((delxndp = rd_delctrl(&dtyp, &is_evctl_impl)) == NULL)
1624 {
1625 /* SJM 06/01/04 - @(*) or @* forms - have nil delxndp but still bld */
1626 if (!is_evctl_impl) return(NULL);
1627 }
1628 dcstp = __alloc_stmt(S_DELCTRL);
1629 /* fix up so statement location starts with delay control not action stmt */
1630 dcstp->stlin_cnt = slcnt;
1631 dcstp->stfnam_ind = sfnind;
1632
1633 dctp = dcstp->st.sdc;
1634 dctp->dctyp = dtyp;
1635 dctp->dc_delrep = DT_CMPLST;
1636 pmp = __alloc_pval();
1637 pmp->plxndp = delxndp;
1638 dctp->dc_du.pdels = pmp;
1639 dctp->dceschd_tevs = NULL;
1640 /* SJM 06/01/04 - in this case del xndp nil - build ev list during fixup */
1641 dctp->implicit_evxlst = is_evctl_impl;
1642
1643 /* if begin-end block will return statement list */
1644 if ((stp = __rd_stmt()) == NULL) return(NULL);
1645 /* need some statement here even if it is only NULL statement */
1646 /* delay control on block turned into delay control on st. list */
1647 dctp->actionst = stp;
1648 return(dcstp);
1649 }
1650
1651 /*
1652 * read a delay control @ or # read - builds expression and type
1653 * know first token read and reads one past ending token
1654 *
1655 * this must have skipped past delay control to stmt if possible
1656 */
rd_delctrl(int32 * dtyp,int32 * ev_impl)1657 static struct expr_t *rd_delctrl(int32 *dtyp, int32 *ev_impl)
1658 {
1659 struct expr_t *ndp;
1660
1661 *ev_impl = FALSE;
1662 /* read one after except for non parenthesized ID because there need to */
1663 /* read one ahead to see if xmr */
1664 if (__toktyp == SHARP) *dtyp = DC_DELAY;
1665 else
1666 {
1667 *dtyp = DC_EVENT;
1668 __canbe_impl_evctrl = TRUE;
1669 }
1670 __get_vtok();
1671
1672 if (__toktyp == LPAR)
1673 {
1674 /* if @(* that looks like attribute to scanner - glb canbe impl evctrl */
1675 /* on will prevent seeing as atrribute since attrs illegal here */
1676 __get_vtok();
1677 __canbe_impl_evctrl = FALSE;
1678
1679 if (*dtyp == DC_DELAY)
1680 {
1681 /* undeclared names treated as wires - maybe changed to event later */
1682 /* need to surround with () in expr. so m:t:m parses ok */
1683 /* but need to use actual surrounding for parse indicators */
1684 __last_xtk = -1;
1685 ndp = __alloc_exprnd();
1686 ndp->optyp = LPAR;
1687 /* if no error, surround with parentheseses and parse as normal */
1688 if (!__col_parenexpr(0))
1689 {
1690 __pv_ferr(1278, "delay control expression error");
1691
1692 __vskipto_any(RPAR);
1693 if (__syncto_class == SYNC_TARG || __syncto_class == SYNC_STMT)
1694 {
1695 bad_dctrl:
1696 /* this is 1 bit x - cannot be op empty */
1697 __set_xtab_errval();
1698 __get_vtok();
1699 goto bld_evx;
1700 }
1701 __get_vtok();
1702 return(NULL);
1703 }
1704 ndp = __alloc_exprnd();
1705 ndp->optyp = RPAR;
1706 }
1707 else
1708 {
1709 if (__toktyp == TIMES)
1710 {
1711 __get_vtok();
1712 if (__toktyp != RPAR)
1713 {
1714 __pv_ferr(3428, "implicit @(*) event control form illegal - %s read",
1715 __prt_vtok());
1716 __vskipto_any(RPAR);
1717 if (__syncto_class == SYNC_TARG || __syncto_class == SYNC_STMT)
1718 return(NULL);
1719 else { __get_vtok(); return(NULL); }
1720 }
1721 *ev_impl = TRUE;
1722 __get_vtok();
1723 return(NULL);
1724 }
1725
1726 /* event control cannot have added surrounding () because of evor */
1727 if (!col_evctrlexpr())
1728 {
1729 __pv_ferr(1087, "event control expression error");
1730 /* if possible, now ready to read statement */
1731 __vskipto_any(RPAR);
1732 if (__syncto_class == SYNC_TARG || __syncto_class == SYNC_STMT)
1733 goto bad_dctrl;
1734 __get_vtok();
1735 return(NULL);
1736 }
1737 }
1738 /* on any non error surrounding () case, read one after end ) */
1739 __get_vtok();
1740 }
1741 else
1742 {
1743 /* turn off glb to prevent seeing @(* as scanner attribute */
1744 __canbe_impl_evctrl = FALSE;
1745
1746 /* simple case can be one name form */
1747 /* should really check to see if next token can start stmt */
1748 __last_xtk = -1;
1749 /* this declares ID as wire - maybe later declared to be event */
1750 /* LOOKATME - could collect xmr without surrounding () by */
1751 /* looking for each .ID(optional [...]) after first */
1752 switch ((byte) __toktyp) {
1753 case NUMBER: case REALNUM: case ID: break;
1754 /* only create IS number at param assign */
1755 case TIMES:
1756 /* AIV 07/21/04 - handle @* without () */
1757 *ev_impl = TRUE;
1758 __get_vtok();
1759 return(NULL);
1760 case ISNUMBER: case ISREALNUM:
1761 /* here on error, assume right structure but 1 thing wrong */
1762 __arg_terr(__FILE__, __LINE__);
1763 break;
1764 default:
1765 /* one token after delay/event control case - no sync possible */
1766 __pv_ferr(1088,
1767 "non parenthesized delay/event control not identifier or number - %s read",
1768 __prt_vtok());
1769 goto bad_dctrl;
1770 }
1771 if (__toktyp == ID)
1772 {
1773 /* even if simple ID (i.e. always) this reads one past end */
1774 if (!col_dctrl_xmr()) goto bad_dctrl;
1775 }
1776 else
1777 {
1778 if (!__bld_expnode()) goto bad_dctrl;
1779 __get_vtok();
1780 }
1781 }
1782 bld_evx:
1783 if (*dtyp == DC_EVENT) __bld_evxtree(); else __bld_xtree(0);
1784 return(__root_ndp);
1785 }
1786
1787 /*
1788 * collect a delay or event control variable
1789 *
1790 * know @ or # and following ID read - done unless part of XMR
1791 * after ID can have optional select [..] then if not dot done else read
1792 * next component - collected XMR later parsed into glbref
1793 *
1794 * know ID read and reads one past end of XMR (if not simple ID)
1795 * also emits error on non ID or GLBREF - select at end illegal - need ()
1796 */
col_dctrl_xmr(void)1797 static int32 col_dctrl_xmr(void)
1798 {
1799 int32 sblevel;
1800
1801 __last_xtk = -1;
1802 if (!__bld_expnode()) goto bad_end;
1803 for (;;)
1804 {
1805 /* each time hear know ID read and added to exprtab */
1806 __get_vtok();
1807 if (__toktyp == LSB)
1808 {
1809 if (!__bld_expnode()) goto bad_end;
1810 for (sblevel = 0;;)
1811 {
1812 __get_vtok();
1813 if (__toktyp == TEOF || __toktyp == SEMI)
1814 {
1815 __pv_ferr(1082,
1816 "illegal token %s in delay or event control global variable",
1817 __prt_vtok());
1818 goto bad_end;
1819 }
1820 if (__toktyp == LSB) sblevel++;
1821 else if (__toktyp == RSB)
1822 {
1823 if (sblevel <= 0) break;
1824 sblevel--;
1825 }
1826 if (!__bld_expnode()) goto bad_end;
1827 }
1828 if (!__bld_expnode()) goto bad_end;
1829 __get_vtok();
1830 if (__toktyp != DOT)
1831 {
1832 __pv_ferr(1075,
1833 "delay or event control global variable contains select - must surround with parentheses");
1834 goto bad_end;
1835 }
1836 }
1837 /* anything after component but dot ends and not collected */
1838 /* works because this reads one past end */
1839 if (__toktyp != DOT) return(TRUE);
1840 if (!__bld_expnode()) goto bad_end;
1841 /* read required ID after DOT */
1842 __get_vtok();
1843 if (__toktyp != ID)
1844 {
1845 __pv_ferr(1058,
1846 "delay/event control hierarchical reference identifier must follow dot - %s read",
1847 __prt_kywrd_vtok());
1848 }
1849 if (!__bld_expnode()) goto bad_end;
1850 }
1851
1852 bad_end:
1853 __set_xtab_errval();
1854 return(FALSE);
1855 }
1856
1857 /*
1858 * EXPRESSION COLLECTION ROUTINES
1859 * these return FALSE and 1'bx on error - caller must emit err
1860 */
1861
1862 /*
1863 * collect delay expr. make 0 if error - will never make it to fixup so ok
1864 * this collects and adds surrounding parenthesis - need for possible
1865 * min:typ:max with surrounding ()
1866 * but otherwise is identical to collect connecting expr.
1867 * expects 1st token to have been read
1868 */
__col_delexpr(void)1869 extern int32 __col_delexpr(void)
1870 {
1871 struct expr_t *ndp;
1872
1873 __last_xtk = -1;
1874 ndp = __alloc_exprnd();
1875 ndp->optyp = LPAR;
1876 /* if no error, surround with parentheseses and parse as normal */
1877 if (!__col_connexpr(0))
1878 {
1879 bad_del:
1880 __set_xtab_errval();
1881 /* need constant 32 bit 0 here */
1882 __exprtab[0]->szu.xclen = WBITS;
1883 __exprtab[0]->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
1884 return(FALSE);
1885 }
1886 /* if col conn T, then know at least 1 token */
1887 if (__last_xtk == 1 && __exprtab[1]->optyp == OPEMPTY)
1888 {
1889 __pv_ferr(1095, "empty delay expression illegal");
1890 goto bad_del;
1891 }
1892 ndp = __alloc_exprnd();
1893 ndp->optyp = RPAR;
1894 return(TRUE);
1895 }
1896
1897
1898 /*
1899 * collect parm or specparam rhs parameter value
1900 * this collects and adds surrounding parenthesis
1901 * needed for possible min:typ:max with surrounding ()
1902 * but otherwise is identical to collect comsemi
1903 * expects 1st token to have been read
1904 *
1905 * on error sets value to 0 not x - is this right?
1906 * if this is used where only ; can end, caller must check for and emit err
1907 */
__col_paramrhsexpr(void)1908 extern int32 __col_paramrhsexpr(void)
1909 {
1910 struct expr_t *ndp;
1911
1912 __last_xtk = -1;
1913 ndp = __alloc_exprnd();
1914 ndp->optyp = LPAR;
1915 /* if no error, surround with parentheseses and parse as normal */
1916 if (!__col_comsemi(0))
1917 {
1918 __set_xtab_errval();
1919 /* need constant 32 bit 0 here */
1920 __exprtab[0]->szu.xclen = WBITS;
1921 __exprtab[0]->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
1922 return(FALSE);
1923 }
1924 ndp = __alloc_exprnd();
1925 ndp->optyp = RPAR;
1926 return(TRUE);
1927 }
1928
1929 /*
1930 * collect paren surround expression and leave tree in __exprtab[0]
1931 * expects 1st expr. token to have been read (after '(') reads end token
1932 * need to reuse or move nodes here to tree
1933 * surrounding parentheses not included
1934 */
__col_parenexpr(int32 start_xtk)1935 extern int32 __col_parenexpr(int32 start_xtk)
1936 {
1937 int32 parlevel;
1938
1939 /* this is illegal () case */
1940 if (__toktyp == RPAR)
1941 {
1942 __pv_ferr(1089, "empty parentheses ending expression illegal");
1943 bad_end:
1944 /* notice cannot free here since in __exprtab (links just overwritten) */
1945 /* also make look like empty expr. */
1946 __set_xtab_errval();
1947 return(FALSE);
1948 }
1949 parlevel = 0;
1950 if (__toktyp == LPAR) parlevel++;
1951
1952 for (__last_xtk = start_xtk;;)
1953 {
1954 if (!__bld_expnode()) goto bad_end;
1955 __get_vtok();
1956 if (__toktyp == LPAR) parlevel++;
1957 else if (__toktyp == RPAR)
1958 {
1959 if (parlevel > 0) parlevel--; else break;
1960 }
1961 else if (__toktyp == TEOF || __toktyp == SEMI)
1962 {
1963 if (__pv_err_cnt <= __saverr_cnt)
1964 __pv_ferr(1090, "illegal token %s in parenthesis ending expression",
1965 __prt_vtok());
1966 goto bad_end;
1967 }
1968 }
1969 return(TRUE);
1970 }
1971
1972 /*
1973 * collect event expr - for new VER 2001 , as alternative to evor legal
1974 * same as collect paren expr except commas allowed and special
1975 * ev or comma token substituted
1976 *
1977 * expects 1st expr. token to have been read (after '(') reads end token
1978 *
1979 * know implicit @* and @(*) never seen here
1980 * need to reuse or move nodes here to tree
1981 */
col_evctrlexpr(void)1982 static int32 col_evctrlexpr(void)
1983 {
1984 int32 parlevel, catlevel;
1985
1986 __last_xtk = -1;
1987 /* this is illegal () case */
1988 if (__toktyp == RPAR)
1989 {
1990 __pv_ferr(1089, "empty parentheses ending expression illegal");
1991 bad_end:
1992 /* notice cannot free here since in __exprtab (links just overwritten) */
1993 /* also make look like empty expr. */
1994 __set_xtab_errval();
1995 return(FALSE);
1996 }
1997 parlevel = catlevel = 0;
1998 if (__toktyp == LPAR) parlevel++;
1999 /* AIV 09/27/06 - catlevel was off for first case LCB */
2000 /* was incorrectly handling @({a, b}) */
2001 if (__toktyp == LCB) catlevel++;
2002
2003 for (;;)
2004 {
2005 /* SJM 06/01/04 - this is unusual ',' just like event "or" but different */
2006 /* expr node op typ */
2007 /* bld expnode can't see comma because mashes error recovery */
2008 if (__toktyp == COMMA && catlevel == 0) __toktyp = OPEVCOMMAOR;
2009 if (!__bld_expnode()) goto bad_end;
2010
2011 __get_vtok();
2012 switch ((byte) __toktyp) {
2013 case LCB: catlevel++; break;
2014 case RCB: catlevel--; break;
2015 case LPAR: parlevel++; break;
2016 case RPAR:
2017 /* only non nested rpar can cause correct exit */
2018 if (parlevel > 0) { parlevel--; break; }
2019 goto done;
2020 default:
2021 if (__toktyp == TEOF || __toktyp == SEMI)
2022 {
2023 if (__pv_err_cnt <= __saverr_cnt)
2024 {
2025 __pv_ferr(1090, "illegal token %s in parenthesis ending expression",
2026 __prt_vtok());
2027 }
2028 goto bad_end;
2029 }
2030 }
2031 }
2032 done:
2033 return(TRUE);
2034 }
2035
2036 /*
2037 * collect a range expression
2038 * expects first token ([) to have been read and reads ending ] token
2039 * includes ] in expression
2040 */
__col_rangeexpr(void)2041 extern int32 __col_rangeexpr(void)
2042 {
2043 int32 brklevel;
2044 struct expr_t *ndp;
2045
2046 /* must add dummy symbol so range parses as x[cexpr:cexpr] */
2047 __last_xtk = -1;
2048 ndp = __alloc_exprnd();
2049 ndp->optyp = ID;
2050 /* need dummy to fill id table - not used and overwritten each time */
2051 /* this checked for during term parsing and not decled */
2052 __alloc_expridnd("[]");
2053 /* node for already read [ */
2054 if (!__bld_expnode()) goto bad_end;
2055
2056 for (brklevel = 0;;)
2057 {
2058 __get_vtok();
2059 if (__toktyp == LSB) brklevel++;
2060 else if (__toktyp == RSB)
2061 {
2062 if (brklevel <= 0)
2063 {
2064 if (__last_xtk == 1)
2065 {
2066 __pv_ferr(1097, "select range empty form ([]) illegal");
2067 goto bad_end;
2068 }
2069 /* ending ] must be part of expression */
2070 if (!__bld_expnode()) goto bad_end;
2071 break;
2072 }
2073 else brklevel--;
2074 }
2075 else if (__toktyp == TEOF || __toktyp == SEMI)
2076 {
2077 if (__pv_err_cnt <= __saverr_cnt)
2078 __pv_ferr(1091, "illegal token %s in select range expression",
2079 __prt_vtok());
2080
2081 bad_end:
2082 /* must be 1 bit x not unc. */
2083 __set_xtab_errval();
2084 __last_xtk = 0;
2085 return(FALSE);
2086 }
2087 if (!__bld_expnode()) goto bad_end;
2088 }
2089 return(TRUE);
2090 }
2091
2092 /*
2093 * collect an inst., port header, function call, delay, cat expr. or
2094 * instance pound parameter list
2095 *
2096 * expects 1st token to be read and read ending token
2097 * ends with ) or ,
2098 * allows full expressions but also used for param subset exprs.
2099 * need start_xtk for delay params where min:typ:max does not need (),
2100 * scheme adds surrounding () and then calls normal bld_xtree
2101 * for each comma sep. * piece
2102 * normal start of expr. is -1
2103 */
__col_connexpr(int32 start_xtk)2104 extern int32 __col_connexpr(int32 start_xtk)
2105 {
2106 int32 parlevel, catlevel;
2107
2108 /* ,, or ,) form ok here - if not caller will check */
2109 if (__toktyp == COMMA || __toktyp == RPAR)
2110 { __last_xtk = start_xtk + 1; __set_opempty(__last_xtk); return(TRUE); }
2111
2112 for (__last_xtk = start_xtk, parlevel = 0, catlevel = 0;;)
2113 {
2114 switch ((byte) __toktyp) {
2115 case LPAR: parlevel++; break;
2116 case LCB: catlevel++; break;
2117 case RPAR:
2118 if (parlevel <= 0 && catlevel <= 0) return(TRUE); else parlevel--;
2119 break;
2120 case RCB:
2121 catlevel--;
2122 break;
2123 case COMMA:
2124 if (parlevel <= 0 && catlevel <= 0) return(TRUE);
2125 break;
2126 case TEOF:
2127 case SEMI:
2128 if (__pv_err_cnt <= __saverr_cnt)
2129 __pv_ferr(1092, "illegal token %s in expression list", __prt_vtok());
2130 goto bad_end;
2131 }
2132 if (!__bld_expnode()) goto bad_end;
2133 __get_vtok();
2134 }
2135
2136 bad_end:
2137 __set_xtab_errval();
2138 return(FALSE);
2139 }
2140
2141 /*
2142 * collect something from an assignment list rhs
2143 * expects 1st token of assignment rhs expr to have been read
2144 * rhs expr. can have (..) function calls and concatenates
2145 * also (..) delay triples
2146 *
2147 * reads trailing , or ;
2148 * empty here will not collect - error
2149 */
__col_comsemi(int32 last_xti)2150 extern int32 __col_comsemi(int32 last_xti)
2151 {
2152 int32 parlevel, catlevel;
2153
2154 __last_xtk = last_xti;
2155 for (parlevel = 0, catlevel = 0;;)
2156 {
2157 switch ((byte) __toktyp) {
2158 case LPAR: parlevel++; break;
2159 case RPAR: parlevel--; break;
2160 case LCB: catlevel++; break;
2161 case RCB: catlevel--; break;
2162 case SEMI:
2163 chk_empty:
2164 /* empty = ; form illegal */
2165 if (__last_xtk == last_xti)
2166 {
2167 __pv_ferr(1106, "right hand side expression missing");
2168 goto bad_end;
2169 }
2170 return(TRUE);
2171 case COMMA:
2172 if (parlevel <= 0 && catlevel <= 0) goto chk_empty;
2173 break;
2174 case TEOF:
2175 if (__pv_err_cnt <= __saverr_cnt)
2176 __pv_ferr(1093, "illegal token %s in right hand side expression",
2177 __prt_vtok());
2178 goto bad_end;
2179 }
2180 if (!__bld_expnode()) goto bad_end;
2181 __get_vtok();
2182 }
2183
2184 bad_end:
2185 /* replace entire expression with 1 bit x - not op empty */
2186 __set_xtab_errval();
2187 return(FALSE);
2188 }
2189
2190 /*
2191 * new parameter format collect param (not specify) rhs expr
2192 *
2193 * expects 1st token of assignment rhs expr to have been read
2194 * and reads one past end , or ;
2195 *
2196 * for mismatched nesting parse will catch error
2197 */
__col_newparamrhsexpr(void)2198 extern int32 __col_newparamrhsexpr(void)
2199 {
2200 int32 parlevel, catlevel;
2201 struct expr_t *ndp;
2202
2203 __last_xtk = -1;
2204 ndp = __alloc_exprnd();
2205 ndp->optyp = LPAR;
2206 for (parlevel = 0, catlevel = 0;;)
2207 {
2208 switch ((byte) __toktyp) {
2209 case LPAR: parlevel++; break;
2210 case RPAR: parlevel--; break;
2211 case LCB: catlevel++; break;
2212 case RCB: catlevel--; break;
2213 case SEMI:
2214 chk_empty:
2215 /* empty = ; form illegal */
2216 if (__last_xtk == -1)
2217 {
2218 __pv_ferr(1106, "right hand side expression missing");
2219 goto bad_end;
2220 }
2221 ndp = __alloc_exprnd();
2222 ndp->optyp = RPAR;
2223 return(TRUE);
2224 case COMMA:
2225 if (parlevel <= 0 && catlevel <= 0) goto chk_empty;
2226 break;
2227 case TEOF:
2228 if (__pv_err_cnt <= __saverr_cnt)
2229 __pv_ferr(1093,
2230 "illegal token %s in parameter right hand side expression",
2231 __prt_vtok());
2232 goto bad_end;
2233 }
2234 if (!__bld_expnode()) goto bad_end;
2235 __get_vtok();
2236 }
2237
2238 bad_end:
2239 /* replace entire expression with 1 bit x - not op empty */
2240 __set_xtab_errval();
2241 return(FALSE);
2242 }
2243
2244 /*
2245 * ver 2001 #(list of param decls) form format collect param rhs expr
2246 *
2247 * expects 1st token of assignment rhs expr to have been read
2248 * and reads one past end , or )
2249 *
2250 * for mismatched nesting parse will catch error
2251 */
__col_lofp_paramrhsexpr(void)2252 extern int32 __col_lofp_paramrhsexpr(void)
2253 {
2254 int32 parlevel, catlevel;
2255 struct expr_t *ndp;
2256
2257 __last_xtk = -1;
2258 ndp = __alloc_exprnd();
2259 ndp->optyp = LPAR;
2260 for (parlevel = 0, catlevel = 0;;)
2261 {
2262 switch ((byte) __toktyp) {
2263 case LPAR: parlevel++; break;
2264 case LCB: catlevel++; break;
2265 case RCB: catlevel--; break;
2266 case RPAR:
2267 if (parlevel <= 0 && catlevel <= 0) goto chk_empty;
2268 else parlevel--;
2269 break;
2270 case COMMA:
2271 if (parlevel <= 0 && catlevel <= 0)
2272 {
2273 chk_empty:
2274 /* empty = ) form illegal */
2275 if (__last_xtk == -1)
2276 {
2277 __pv_ferr(1106, "right hand side expression missing");
2278 goto bad_end;
2279 }
2280 ndp = __alloc_exprnd();
2281 ndp->optyp = RPAR;
2282 return(TRUE);
2283 }
2284 break;
2285 case TEOF: case SEMI:
2286 if (__pv_err_cnt <= __saverr_cnt)
2287 __pv_ferr(1093,
2288 "illegal token %s in parameter right hand side expression",
2289 __prt_vtok());
2290 goto bad_end;
2291 }
2292 if (!__bld_expnode()) goto bad_end;
2293 __get_vtok();
2294 }
2295
2296 bad_end:
2297 /* replace entire expression with 1 bit x - not op empty */
2298 __set_xtab_errval();
2299 return(FALSE);
2300 }
2301
2302 /*
2303 * collect an lvalue (all but procedural assign lhs)
2304 * expects 1st token of assignment lhs expr to have been read and reads
2305 * trailing =
2306 *
2307 * must emit error on 1st extra right parenthesis or will get error line
2308 * wrong - also if returns F must emit error
2309 */
__col_lval(void)2310 extern int32 __col_lval(void)
2311 {
2312 int32 parlevel;
2313
2314 parlevel = 0;
2315 for (__last_xtk = -1;;)
2316 {
2317 switch ((byte) __toktyp) {
2318 case TEOF: case SEMI:
2319 {
2320 maybe_err:
2321 __pv_ferr(1094,
2322 "illegal token %s in lvalue - probable missing = or assign to function call",
2323 __prt_vtok());
2324 goto bad_end;
2325 }
2326 case EQ:
2327 if (__last_xtk == -1)
2328 {
2329 /* empty = ; form illegal */
2330 __pv_ferr(1096, "assignment lvalue missing");
2331 goto bad_end;
2332 }
2333 return(TRUE);
2334 case LPAR: parlevel++; break;
2335 case RPAR:
2336 if (--parlevel < 0) goto maybe_err;
2337 break;
2338 }
2339 if (!__bld_expnode()) goto bad_end;
2340 __get_vtok();
2341 }
2342
2343 bad_end:
2344 __set_xtab_errval();
2345 return(FALSE);
2346 }
2347
2348 /*
2349 * collect a procedural assignment lvalue (can end with <= non blocking
2350 * procedural assignment symbol or ( for task enable)
2351 *
2352 * expects 1st token of assignment lhs expr to have been read and reads
2353 * trailing '(' or ';' (no argumnet form), or '=' or '<=' for assign
2354 */
col2_lval(void)2355 static int32 col2_lval(void)
2356 {
2357 int32 sblevel, cblevel;
2358
2359 sblevel = cblevel = 0;
2360 /* set flag for bld expnode error recovery - must be off when done */
2361 __expr_is_lval = TRUE;
2362 for (__last_xtk = -1;;)
2363 {
2364 switch ((byte) __toktyp) {
2365 case TEOF:
2366 if (__pv_err_cnt <= __saverr_cnt)
2367 __pv_ferr(1099,
2368 "illegal token %s in procedural assign lvalue or task enable",
2369 __prt_vtok());
2370 goto bad_end;
2371 case EQ:
2372 /* = can not appear in lhs because relational never '=' */
2373 chk_emp:
2374 if (__last_xtk == -1)
2375 {
2376 /* empty lhs "= <rhs side>" form illegal */
2377 __pv_ferr(1117, "empty assignment or task enable lvalue illegal");
2378 goto bad_end;
2379 }
2380 __expr_is_lval = FALSE;
2381 return(TRUE);
2382 case SEMI:
2383 /* no argument task enable "$stop;" - must not be empty */
2384 /* ; is error correction marker - can not be nested in anything */
2385 goto chk_emp;
2386 case RELLE:
2387 if (sblevel == 0 && cblevel == 0) goto chk_emp;
2388 break;
2389 case LPAR:
2390 if (sblevel == 0 && cblevel == 0) goto chk_emp;
2391 break;
2392 case LSB: sblevel++; break;
2393 case RSB: sblevel--; break;
2394 case LCB: cblevel++; break;
2395 case RCB: cblevel--; break;
2396 }
2397 if (!__bld_expnode()) goto bad_end;
2398 __get_vtok();
2399 }
2400
2401 bad_end:
2402 __expr_is_lval = FALSE;
2403 __set_xtab_errval();
2404 return(FALSE);
2405 }
2406
2407 /*
2408 * read a case expression list that ends with : or ,
2409 * also reads DEFAULT and ENDCASE expressions
2410 * expects 1st token to be read and reads ending token
2411 * but it is not included
2412 */
__col_caseexpr(void)2413 extern int32 __col_caseexpr(void)
2414 {
2415 int32 parlevel, collevel, sblevel, cblevel;
2416
2417 parlevel = collevel = sblevel = cblevel = 0;
2418 for (__last_xtk = -1;;)
2419 {
2420 switch ((byte) __toktyp) {
2421 case QUEST: collevel++; break;
2422 case COLON:
2423 /* ? token must be followed by : for ?: expression */
2424 if (collevel > 0) collevel--;
2425 else if (sblevel <= 0) goto good_end;
2426 break;
2427 case LSB: sblevel++; break;
2428 case RSB: sblevel--; break;
2429 case LCB: cblevel++; break;
2430 case RCB: cblevel--; break;
2431 case LPAR: parlevel++; break;
2432 case RPAR: parlevel--; break;
2433 case COMMA:
2434 if (parlevel <= 0 && cblevel <= 0) goto good_end;
2435 break;
2436 case TEOF:
2437 case SEMI:
2438 if (__pv_err_cnt <= __saverr_cnt)
2439 __pv_ferr(1101, "illegal token %s in case item expression",
2440 __prt_vtok());
2441 bad_end:
2442 __set_xtab_errval();
2443 return(FALSE);
2444 }
2445 if (!__bld_expnode()) goto bad_end;
2446 __get_vtok();
2447 }
2448 good_end:
2449 if (__last_xtk == -1)
2450 {
2451 /* empty form illegal */
2452 __pv_ferr(1098, "case expression list missing");
2453 goto bad_end;
2454 }
2455 return(TRUE);
2456 }
2457
2458 /*
2459 * build an expression tree node from current token
2460 * always places it in next free place in __exprtab
2461 * reuses storage so bld_xtree must allocate nodes
2462 *
2463 * puts ID name in expr_idtab that is changed to symbol in
2464 * parse term routine (either ID or xmr component)
2465 *
2466 * 'or' in expression always evor
2467 * anything part of expression goes through here
2468 */
__bld_expnode(void)2469 extern int32 __bld_expnode(void)
2470 {
2471 int32 wlen;
2472 struct opinfo_t *oip;
2473 struct expr_t *ndp;
2474
2475 ndp = __alloc_exprnd();
2476 switch ((byte) __toktyp) {
2477 case ID:
2478 /* if can be inst. ref, assume global fix later */
2479 /* notice anthing in this case but id and glb wrong - caught later */
2480 if (strcmp(__token, "or") == 0) { ndp->optyp = OPEVOR; break; }
2481 ndp->optyp = ID;
2482 __alloc_expridnd(__token);
2483 break;
2484 case POSEDGE:
2485 ndp->optyp = OPPOSEDGE;
2486 break;
2487 case NEGEDGE:
2488 ndp->optyp = OPNEGEDGE;
2489 break;
2490 case OPEVCOMMAOR:
2491 ndp->optyp = OPEVCOMMAOR;
2492 break;
2493 case NUMBER:
2494 /* notice scanner only returns number */
2495 ndp->optyp = NUMBER;
2496 ndp->szu.xclen = __itoklen;
2497 if (__itoksized) ndp->unsiznum = FALSE; else ndp->unsiznum = TRUE;
2498
2499 /* only true for decimal without 'd even 'd[num] is word32 */
2500 /* SJM 10/02/03 - scanner sets if signed - depends on new 2001 LRM rules */
2501 if (__itok_signed) ndp->has_sign = TRUE;
2502
2503 ndp->ibase = (word32) __itokbase;
2504 ndp->sizdflt = (__itoksizdflt) ? TRUE : FALSE;
2505 /* Verilog values are really word32 bit patterns */
2506
2507 wlen = wlen_(__itoklen);
2508 if (__itoklen <= WBITS)
2509 {
2510 /* always sets value - if not sharable uses non sharable alloc cval */
2511 ndp->ru.xvi = __alloc_shareable_cval(__acwrk[0], __bcwrk[0], __itoklen);
2512 }
2513 else
2514 {
2515 ndp->ru.xvi = __allocfill_cval_new(__acwrk, __bcwrk, wlen);
2516 }
2517 break;
2518 case REALNUM:
2519 /* num storage pted to by a part - usually (except xstk) no b part */
2520 ndp->optyp = REALNUM;
2521 ndp->szu.xclen = REALBITS;
2522 ndp->ibase = BDBLE;
2523 ndp->is_real = TRUE;
2524 ndp->has_sign = TRUE;
2525 /* LOOKATME - SIZE assuming size of real is 8 bytes here */
2526 ndp->ru.xvi = __alloc_shareable_rlcval(__itok_realval);
2527 break;
2528 case LITSTR:
2529 /* string copied to alloced storage and filled */
2530 ndp->optyp = NUMBER;
2531 ndp->szu.xclen = __itoklen;
2532
2533 wlen = wlen_(__itoklen);
2534 ndp->ru.xvi = __allocfill_cval_new(__acwrk, __bcwrk, wlen);
2535 ndp->is_string = TRUE;
2536 ndp->unsiznum = FALSE;
2537 ndp->has_sign = FALSE;
2538 break;
2539 case TEOF:
2540 /* since no error recovery in interactive - this is finish path */
2541 /* caller sets to error expression */
2542 ndp->optyp = BADOBJ;
2543 return(FALSE);
2544 default:
2545 if (__toktyp > LASTOP)
2546 {
2547 /* keywords can not be in or end expressions */
2548 if (__pv_err_cnt <= __saverr_cnt)
2549 __pv_ferr(1104,
2550 "illegal token %s in expression - probable missing semicolon",
2551 __prt_vtok());
2552 return(FALSE);
2553 }
2554 /* build an operator node */
2555 oip = &(__opinfo[__toktyp]);
2556 if (oip->opclass == NOTANOP)
2557 {
2558 if (__pv_err_cnt <= __saverr_cnt)
2559 __pv_ferr(1105, "illegal punctuation %s in expression",
2560 __prt_vtok());
2561 return(FALSE);
2562 }
2563 /* build an operator node */
2564 ndp->optyp = __toktyp;
2565 }
2566 return(TRUE);
2567 }
2568
2569 #define HASHTABSIZ 3011 /* prime number size of consts hash table */
2570 #define HASHSEED 0x371546dc /* seed of first word of the hash table */
2571
2572
2573 /*
2574 * setup the constant tables
2575 *
2576 * allocate design wide constant table - so fixed constants at bottom
2577 * BEWARE - since constant table is design and reallocated must always ndx
2578 * allocate initial small constant table - grows when needed
2579 */
__setup_contab(void)2580 extern void __setup_contab(void)
2581 {
2582 register int32 i, j;
2583
2584 __contabwsiz = 400;
2585 __contab = (word32 *) __my_malloc(__contabwsiz*sizeof(word32));
2586 /* 0th and 1st unused - marker to catch errors */
2587 for (i = 0; i < 4; i++) __contab[i] = ALL1W;
2588 /* 3rd is one bit z */
2589 __contab[4] = 0;
2590 __contab[5] = 1;
2591 /* 4th is 1 bit x */
2592 __contab[6] = 1;
2593 __contab[7] = 1;
2594 /* 5th is 32 bit z */
2595 __contab[8] = 0;
2596 __contab[9] = ALL1W;
2597 /* 6th is 32 bit x */
2598 __contab[10] = ALL1W;
2599 __contab[11] = ALL1W;
2600
2601 for (i = 12, j = 0; i <= 12 + 2*128; i += 2, j++)
2602 {
2603 __contab[i] = j;
2604 __contab[i + 1] = 0;
2605 }
2606 /* also need build in special contab index for opempty */
2607 /* all rhs igen expr eval OP EMPTY nodes point to this */
2608 __opempty_contabi = 270;
2609 __contab[270] = ' ';
2610 __contab[271] = 0;
2611 __contabwi = 272;
2612
2613 __contab_hash = (struct contab_info_t **)
2614 __my_malloc(HASHTABSIZ*sizeof(struct contab_info_t *));
2615 memset(__contab_hash, 0, HASHTABSIZ*sizeof(struct contab_info_t *));
2616
2617 }
2618
2619 /* some local use only constant for fixed con table locations */
2620 #define FIXCON_1BITZ 4
2621 #define FIXCON_1BITX 6
2622 #define FIXCON_32BITZ 8
2623 #define FIXCON_32BITX 10
2624 #define NONXZ_CONBASE 12
2625
2626 /*
2627 * sharable (non IS form) any 32 bit or any 32 or less 0
2628 * plus some non x/z low values
2629 */
__alloc_shareable_cval(word32 aval,word32 bval,int32 bwid)2630 extern int32 __alloc_shareable_cval(word32 aval, word32 bval, int32 bwid)
2631 {
2632 int32 wi;
2633
2634 if (bwid == 1)
2635 {
2636 if (bval == 0) goto do_nonxz;
2637 if (aval == 0) return(FIXCON_1BITZ);
2638 return(FIXCON_1BITX);
2639 }
2640
2641 if (bval == ALL1W)
2642 {
2643 if (bwid != WBITS) goto do_alloc;
2644 if (aval == 0) return(FIXCON_32BITZ);
2645 if (aval == ALL1W) return(FIXCON_32BITX);
2646 goto do_alloc;
2647 }
2648 if (bval != 0) goto do_alloc;
2649 do_nonxz:
2650 if (aval <= 128) return(NONXZ_CONBASE + 2*aval);
2651
2652 do_alloc:
2653 aval &= __masktab[bwid];
2654 bval &= __masktab[bwid];
2655 wi = __allocfill_cval_new(&(aval), &(bval), 1);
2656 return(wi);
2657 }
2658
2659 /*
2660 * allocate a constant value in design wide constant table
2661 *
2662 * now only for IS forms where must allocate big region and can't use
2663 * hashing to share because each inst must be filled with mem copy
2664 *
2665 * wlen is really wlen times no. of instances in IS form - multiply by
2666 * 2 works since need b parts for each inst
2667 * know a and b parts contiguous
2668 */
__alloc_is_cval(int32 wlen)2669 extern int32 __alloc_is_cval(int32 wlen)
2670 {
2671 int32 wi;
2672
2673 if (__contabwi + 2*wlen >= __contabwsiz) __grow_contab(2*wlen);
2674 wi = __contabwi;
2675 __contabwi += 2*wlen;
2676 return(wi);
2677 }
2678
2679 /*
2680 * sharable (non IS form) for real constants
2681 * SJM 05/03/05 - now reals go into hashed part of contab
2682 */
__alloc_shareable_rlcval(double d1)2683 extern int32 __alloc_shareable_rlcval(double d1)
2684 {
2685 int32 wi;
2686 word32 rword[2];
2687
2688 memcpy(&(rword), &(d1), sizeof(double));
2689 /* notice word length is 1 since reals have no b part */
2690 wi = __allocfill_cval_new(&(rword[0]), &(rword[1]), 1);
2691 return(wi);
2692 }
2693
2694 /*
2695 * new version of allocate a constant value in design wide constant table
2696 * notice passing word len but need room for 2*wlen for b part
2697 *
2698 * that uses hashing to prevent too much growth of contab during
2699 * non blocking assign realloc and also just a better algorithm
2700 */
__allocfill_cval_new(word32 * ap,word32 * bp,int32 wlen)2701 extern int32 __allocfill_cval_new(word32 *ap, word32 *bp, int32 wlen)
2702 {
2703 register word32 hti;
2704 register struct contab_info_t *cip;
2705 int32 wi, bytsiz;
2706 word32 *wp;
2707
2708 hti = get_hash(ap, bp, wlen);
2709 bytsiz = wlen*WRDBYTES;
2710 if ((cip = __contab_hash[hti]) != NULL)
2711 {
2712 for (; cip != NULL; cip = cip->cnxt)
2713 {
2714 if (cip->cwid != wlen) continue;
2715
2716 wp = &(__contab[cip->xvi]);
2717 if (memcmp(wp, ap, bytsiz) == 0 && memcmp(&(wp[wlen]), bp, bytsiz) == 0)
2718 return(cip->xvi);
2719 }
2720 }
2721
2722 if (__contabwi + 2*wlen >= __contabwsiz) __grow_contab(2*wlen);
2723 wi = __contabwi;
2724 __contabwi += 2*wlen;
2725 memcpy(&(__contab[wi]), ap, bytsiz);
2726 memcpy(&(__contab[wi + wlen]), bp, bytsiz);
2727
2728 cip = (struct contab_info_t *) __my_malloc(sizeof(struct contab_info_t));
2729 cip->xvi = wi;
2730 cip->cwid = wlen;
2731 /* put on front */
2732 cip->cnxt = __contab_hash[hti];
2733 __contab_hash[hti] = cip;
2734 return(wi);
2735 }
2736
2737 /*
2738 * hash function
2739 */
get_hash(word32 * ap,word32 * bp,int32 wlen)2740 static word32 get_hash(word32 *ap, word32 *bp, int32 wlen)
2741 {
2742 register int32 wi;
2743 word32 hval;
2744
2745 hval = ap[0] * HASHSEED;
2746 for (wi = 1; wi < wlen; wi++)
2747 {
2748 hval ^= (ap[wi] ^ bp[wi]);
2749 }
2750 hval += wlen;
2751 return(hval % HASHTABSIZ);
2752 }
2753
2754 /*
2755 * grow design wide constant table
2756 *
2757 * when growing, grow with current needed words in case IS array large
2758 * all sizes are in words because need word32 alignment
2759 */
__grow_contab(int32 ndwrds)2760 extern void __grow_contab(int32 ndwrds)
2761 {
2762 int32 old_ctabsiz, obsize, nbsize;
2763
2764 old_ctabsiz = __contabwsiz;
2765 obsize = __contabwsiz*sizeof(word32);
2766 /* fibronacci growth */
2767 __contabwsiz = 3*(old_ctabsiz + ndwrds)/2;
2768 nbsize = __contabwsiz*sizeof(word32);
2769 __contab = (word32 *) __my_realloc((char *) __contab, obsize, nbsize);
2770 }
2771
2772
2773 /*
2774 * EXPRESSION PROCESSING CODE
2775 */
2776
2777 /*
2778 * operator table
2779 * SPECOP means requires separate case entry and special processing
2780 * BEWARE - this table requires operator number k to be on row k
2781 */
2782 struct opinfo_t __opinfo[] = {
2783 /* place holders since using token number used as index into op table */
2784 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "00E" },
2785 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "idE" },
2786 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "bnE" },
2787 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "nE" },
2788 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "inE" },
2789 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rE" },
2790 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "irE" },
2791 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "sE" },
2792 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "giE" },
2793 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" },
2794 /* 10 */
2795 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" },
2796 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" },
2797 /* notice ; now 12 */
2798 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, ";" },
2799 { SPECOP, NOTREALOP, NOTPTHOP, WIDSUM, "," },
2800 { SPECOP, NOTREALOP, PTHOP, WIDNONE, ":" },
2801 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "#" },
2802 /* left grouping operators treated specially */
2803 { BINOP, NOTREALOP, NOTPTHOP, WIDNONE, "(" }, /* ( function call op. */
2804 { SPECOP, NOTREALOP, PTHOP, WIDNONE, ")" }, /* ) RPAR */
2805 { SPECOP, NOTREALOP, PTHOP, WIDNONE, "[" }, /* [ LSB */
2806 { SPECOP, NOTREALOP, PTHOP, WIDNONE, "]" }, /* ] RSB */
2807 /* 20 */
2808 { BINOP, NOTREALOP, PTHOP, WIDSUM, "{" }, /* { LCB - empty rght but bin */
2809 { SPECOP, NOTREALOP, PTHOP, WIDNONE, "}" }, /* } RCB */
2810 { SPECOP, NOTREALOP, PTHOP, WIDNONE, "." }, /* . DOT */
2811 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "@" },
2812 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "->" },
2813 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "=" },
2814 /* unary ops */
2815 /* LOOKATME - this is not really self determined result context determines */
2816 /* but does not fit in pattern so always checked for */
2817 { UNOP, NOTREALOP, PTHOP, WIDMAX, "~" }, /* ~ BITNOT - self determine */
2818 { UNOP, REALOP, PTHOP, WIDONE, "!" }, /* ! NOT */
2819 { RUNOP, REALOP, NOTPTHOP, WIDONE, "!" }, /* ! REALNOT */
2820 /* both unary and binary */
2821 { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "^~" }, /* REDXNOR - must be ^~ */
2822 /* 30 */
2823 { BOTHOP, REALOP, NOTPTHOP, WIDMAX, "+" }, /* + PLUS */
2824 { BOTHOP, REALOP, NOTPTHOP, WIDMAX, "-" }, /* - MINUS (un fixed to self)*/
2825 { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "&" }, /* & BITREDAND */
2826 { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "|" }, /* | BITREDOR */
2827 { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "^" }, /* ^ BITREDXOR */
2828 { RBOTHOP, REALOP, NOTPTHOP, WIDMAX, "-" }, /* + REALINUS */
2829 /* binary operators */
2830 { BINOP, REALOP, NOTPTHOP, WIDMAX, "*" }, /* * TIMES */
2831 { BINOP, REALOP, NOTPTHOP, WIDMAX, "/" }, /* / DIV */
2832 { BINOP, NOTREALOP, NOTPTHOP, WIDMAX, "%" }, /* % MOD */
2833 { BINOP, REALOP, NOTPTHOP, WIDENONE, ">=" }, /* >= RELGE */
2834 /* 40 */
2835 { BINOP, REALOP, NOTPTHOP, WIDENONE, ">" }, /* > RELGT */
2836 { BINOP, REALOP, NOTPTHOP, WIDENONE, "<=" }, /* <= RELLE (not assgn) */
2837 { BINOP, REALOP, NOTPTHOP, WIDENONE, "<" }, /* < RELLT */
2838 { BINOP, NOTREALOP, NOTPTHOP, WIDENONE, "===" }, /* === RELCEQ */
2839 { BINOP, REALOP, PTHOP, WIDENONE, "==" }, /* == RELEQ */
2840 { BINOP, NOTREALOP, NOTPTHOP, WIDENONE, "!==" }, /* !== RELCNEQ */
2841 { BINOP, REALOP, PTHOP, WIDENONE, "!=" }, /* != RELNEQ */
2842 { BINOP, REALOP, PTHOP, WIDONE, "&&" }, /* && BOOLAND */
2843 { BINOP, REALOP, PTHOP, WIDONE, "||" }, /* || BOOLOR */
2844 { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, "<<" }, /* << SHIFTL */
2845 /* 50 */
2846 { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, "<<<" }, /* <<< ASHIFTL */
2847 { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, ">>" }, /* >> SHIFTR */
2848 { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, ">>>" }, /* >>> ASHIFTR */
2849 { BINOP, NOTREALOP, NOTPTHOP, WIDONE, "*>" }, /* *> FPTHCON */
2850 { BINOP, NOTREALOP, NOTPTHOP, WIDONE, "=>" }, /* => PPTHCON */
2851 { BINOP, NOTREALOP, NOTPTHOP, WIDONE, "&&&" }, /* TCHK &&& (cond. event) */
2852 { RBINOP, REALOP, NOTPTHOP, WIDMAX, "+" }, /* + REALPLUS */
2853 { RBINOP, REALOP, NOTPTHOP, WIDMAX, "*" }, /* * REALTIMES */
2854 { RBINOP, REALOP, NOTPTHOP, WIDMAX, "/" }, /* / REALDIV */
2855 { RBINOP, REALOP, NOTPTHOP, WIDENONE, ">" }, /* > REALRELGT */
2856 /* 60 */
2857 { RBINOP, REALOP, NOTPTHOP, WIDENONE, ">=" }, /* >= REALRELGE */
2858 { RBINOP, REALOP, NOTPTHOP, WIDENONE, "<" }, /* < REALRELLT */
2859 { RBINOP, REALOP, NOTPTHOP, WIDENONE, "<=" }, /* <= REALRELLE */
2860 { RBINOP, REALOP, NOTPTHOP, WIDENONE, "==" }, /* == REALRELEQ */
2861 { RBINOP, REALOP, NOTPTHOP, WIDENONE, "!=" }, /* != REALRELEQ */
2862 { RBINOP, REALOP, NOTPTHOP, WIDONE, "&&" }, /* && REALBOOLAND */
2863 { RBINOP, REALOP, NOTPTHOP, WIDONE, "||" }, /* != REALBOOLOR */
2864 /* tree will be left of : will be (cond)?(1st expr) and right will be */
2865 /* 2nd must be fixed, need for a[x?y:z:...] */
2866 /* width is max of operators (i.e. narrow must be padded) */
2867 { SPECOP, REALOP, PTHOP, WIDMAX, "?" }, /* ? QUEST (lhs part of ?:) */
2868 { SPECOP, NOTREALOP, PTHOP, WIDMAX, "?:" }, /* : QCOL (rhs part of ?:) */
2869 { SPECOP, NOTREALOP, PTHOP, WIDSELF, "PARTSEL" },/* [ PARTSEL (2 val sel) */
2870 /* 70 */
2871 { BINOP, NOTREALOP, PTHOP, WIDSUM, "CATCOMMA" }, /* , part of { } */
2872 /* probably should have real quad op. for these */
2873 { BINOP, NOTREALOP, PTHOP, WIDSELF, "CATREP" }, /* [num]{ } concat repeat */
2874 { BINOP, NOTREALOP, NOTPTHOP, WIDSELF, "FCALL OP" }, /* function call */
2875 { BINOP, NOTREALOP, NOTPTHOP, WIDSELF, "LIST COMMA" },/* , of fcall () list*/
2876 /* only legal in event expressions */
2877 { SPECOP, NOTREALOP, NOTPTHOP, WIDONE, "or" }, /* OR event or */
2878 { SPECOP, NOTREALOP, NOTPTHOP, WIDONE, "," }, /* , event or as comma */
2879 /* these are normal unaries except semantics only operand of evor */
2880 { UNOP, NOTREALOP, NOTPTHOP, WIDONE, "posedge " }, /* OPPOSEDGE ev prefix */
2881 { UNOP, NOTREALOP, NOTPTHOP, WIDONE, "negedge " }, /* OPNEGEDGE ev prefix */
2882 /* this do not use table - handle in code */
2883 { SPECOP, REALOP, NOTPTHOP, WIDMAX, "?" }, /* REALREALQUEST (lhs of ?:) */
2884 { SPECOP, REALOP, NOTPTHOP, WIDMAX, "?" }, /* REALREGQUEST (lhs of ?:) */
2885 /* 80 */
2886 { SPECOP, REALOP, NOTPTHOP, WIDMAX, "?:" }, /* REGREALQCOL (rhs of ?:) */
2887 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" }, /* GLBREF */
2888 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" }, /* GLBPATH */
2889 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "XMR ID" }, /* XMRID */
2890 { BINOP, NOTREALOP, NOTPTHOP, WIDSELF, "XMR LIST COMMA" },/* XMR comma */
2891 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "EXPR END" },
2892 { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "TEOF" },
2893 };
2894
2895 /*
2896 * convert expression table to expression tree
2897 * for specparam may start at 1 instead of 0 if not min:typ:max form
2898 */
__bld_xtree(int32 start_xndi)2899 extern void __bld_xtree(int32 start_xndi)
2900 {
2901 struct expr_t *ndp;
2902
2903 /* add end of expression fence */
2904 __has_top_mtm = FALSE;
2905 ndp = __alloc_exprnd();
2906 ndp->optyp = UNDEF;
2907 __xndi = start_xndi;
2908 __saverr_cnt = __pv_err_cnt;
2909 /* __xndi should point to last token which is added UNDEF fence */
2910 if ((__root_ndp = parse_qcexpr()) == NULL || __xndi != __last_xtk)
2911 {
2912 /* if for some reason, empty exprs (no error), emit some kind of err */
2913 if (__saverr_cnt == __pv_err_cnt)
2914 {
2915 if (__xndi > __last_xtk)
2916 __pv_ferr(1108, "expression missing required operator or operand");
2917 else if (__xndi < __last_xtk)
2918 {
2919 if (__exprtab[__xndi]->optyp == COMMA)
2920 __pv_ferr(1111,
2921 "expression list illegal - check for missing ')' or extra ','");
2922 else __pv_ferr(1109, "expression illegal token [%s]",
2923 to_xndnam(__xs, __xndi));
2924 }
2925 else
2926 {
2927 __pv_ferr(1110, "expression parse error at token [%s]",
2928 to_xndnam(__xs, __xndi));
2929 }
2930 }
2931 /* notice by here already moved to allocated nodes from exprtab */
2932 __root_ndp = __alloc_newxnd();
2933 __set_numval(__root_ndp, 1L, 1L, 1);
2934 }
2935 }
2936
2937 /*
2938 * EXPRESSION PARSING ROUTINES
2939 */
2940
2941 /*
2942 * parse an expression that can contain ?: operators
2943 *
2944 * ?: is lowest precedence - everything has stronger attraction
2945 */
parse_qcexpr(void)2946 static struct expr_t *parse_qcexpr(void)
2947 {
2948 struct expr_t *ndp, *qcndp, *tndp, *fndp;
2949
2950 /* handle most common cases without parsing */
2951 /* before parsing bld xtree always places end marker - undef at end */
2952 /* so last xtk here is one past end i.e. 1 for ID */
2953 /* also because not yet parsed part select operator still LSB */
2954 if (__last_xtk == 1
2955 || (__last_xtk == 3 && __exprtab[1]->optyp == LSB)
2956 || (__last_xtk == 6 && __exprtab[1]->optyp == LSB
2957 && __exprtab[3]->optyp == COLON))
2958 {
2959 qcndp = parse_term();
2960 return(qcndp);
2961 }
2962
2963 /* DBG need special case code, just set __last_xtk == 1 term */
2964 /* routine leaves __xndi at next place to look */
2965 if ((qcndp = parse_boolorop()) == NULL) return(NULL);
2966 ndp = __exprtab[__xndi];
2967 if (ndp->optyp == QUEST)
2968 {
2969 ndp = alloc_xtnd(__xndi);
2970 ndp->lu.x = qcndp;
2971 qcndp = ndp;
2972 __xndi++;
2973 /* this can be recursive since no left recursion problem for ?: */
2974 /* this forces right to left grouping since reduces right then backs */
2975 /* up recursion tree to build reduced pieces from left */
2976 if ((tndp = parse_qcexpr()) == NULL)
2977 {
2978 bad_qcexpr:
2979 if (__pv_err_cnt <= __saverr_cnt)
2980 __pv_ferr(1112, "?: parse error at token [%s]", to_xndnam(__xs,
2981 __xndi));
2982 /* move x ndi to end */
2983 xskip_toend();
2984
2985 /* on error here make a 1 bit x this is part of longer expr. */
2986 ndp = alloc_xtnd(__xndi);
2987 __set_numval(ndp, 1L, 1L, 1);
2988 return(ndp);
2989 }
2990 ndp = __exprtab[__xndi];
2991 if (ndp->optyp != COLON) goto bad_qcexpr;
2992 ndp = alloc_xtnd(__xndi);
2993 ndp->optyp = QCOL;
2994 qcndp->ru.x = ndp;
2995 ndp->lu.x = tndp;
2996 __xndi++;
2997 if ((fndp = parse_qcexpr()) == NULL) goto bad_qcexpr;
2998 ndp->ru.x = fndp;
2999 }
3000 return(qcndp);
3001 }
3002
3003 /*
3004 * skip past 1 expression node of node type ndtyp
3005 * this is needed
3006 */
xskip_toend(void)3007 static void xskip_toend(void)
3008 {
3009 struct expr_t *ndp;
3010
3011 for (;;__xndi++)
3012 {
3013 /* never skip past expr. ending fence */
3014 ndp = __exprtab[__xndi];
3015 if (ndp->optyp == UNDEF) break;
3016 }
3017 }
3018
3019 /*
3020 * parse boolean or (||) operators
3021 * precdence one up from lowest
3022 */
parse_boolorop(void)3023 static struct expr_t *parse_boolorop(void)
3024 {
3025 int32 savi;
3026 struct expr_t *ndp, *rhsndp, *leftopndp;
3027
3028 /* routine leaves __xndi at next place to look */
3029 if ((leftopndp = parse_boolandop()) == NULL) return(NULL);
3030 ndp = __exprtab[__xndi];
3031 for (;;)
3032 {
3033 if (ndp->optyp == BOOLOR)
3034 {
3035 savi = __xndi;
3036 __xndi++;
3037 /* treat [term [op] error] as term - could improve recovery here */
3038 if ((rhsndp = parse_boolandop()) == NULL) break;
3039 /* this makes sure optyp right */
3040 ndp = alloc_xtnd(savi);
3041 ndp->lu.x = leftopndp;
3042 ndp->ru.x = rhsndp;
3043 leftopndp = ndp;
3044 ndp = __exprtab[__xndi];
3045 }
3046 else break;
3047 }
3048 return(leftopndp);
3049 }
3050
3051 /*
3052 * parse boolean and (&&) operators
3053 */
parse_boolandop(void)3054 static struct expr_t *parse_boolandop(void)
3055 {
3056 int32 savi;
3057 struct expr_t *ndp, *rhsndp, *leftopndp;
3058
3059 /* routine leaves __xndi at next place to look */
3060 if ((leftopndp = parse_borop()) == NULL) return(NULL);
3061 ndp = __exprtab[__xndi];
3062 for (;;)
3063 {
3064 if (ndp->optyp == BOOLAND)
3065 {
3066 savi = __xndi;
3067 __xndi++;
3068 if ((rhsndp = parse_borop()) == NULL) break;
3069
3070 /* this makes sure optyp right */
3071 ndp = alloc_xtnd(savi);
3072 ndp->lu.x = leftopndp;
3073 ndp->ru.x = rhsndp;
3074 leftopndp = ndp;
3075 ndp = __exprtab[__xndi];
3076 }
3077 else break;
3078 }
3079 return(leftopndp);
3080 }
3081
3082 /*
3083 * parse bit wise or operators
3084 */
parse_borop(void)3085 static struct expr_t *parse_borop(void)
3086 {
3087 int32 savi;
3088 struct expr_t *ndp, *rhsndp, *leftopndp;
3089
3090 /* routine leaves __xndi at next place to look */
3091 if ((leftopndp = parse_bxorop()) == NULL) return(NULL);
3092 ndp = __exprtab[__xndi];
3093 for (;;)
3094 {
3095 if (ndp->optyp == BITREDOR)
3096 {
3097 /* fence and must check at binary bit wise | for following un red | */
3098 if (__exprtab[__xndi + 1]->optyp == BITREDOR)
3099 {
3100 __pv_fwarn(564,
3101 "[expr] | |[expr] invalid - unary should be surrounded by parentheses");
3102 }
3103 savi = __xndi;
3104 __xndi++;
3105 if ((rhsndp = parse_bxorop()) == NULL) break;
3106 /* this makes sure optyp right */
3107 ndp = alloc_xtnd(savi);
3108 ndp->lu.x = leftopndp;
3109 ndp->ru.x = rhsndp;
3110 leftopndp = ndp;
3111 ndp = __exprtab[__xndi];
3112 }
3113 else break;
3114 }
3115 return(leftopndp);
3116 }
3117
3118 /*
3119 * parse bit wise xor operators
3120 */
parse_bxorop(void)3121 static struct expr_t *parse_bxorop(void)
3122 {
3123 int32 savi;
3124 struct expr_t *ndp, *rhsndp, *leftopndp;
3125
3126 /* routine leaves __xndi at next place to look */
3127 if ((leftopndp = parse_bandop()) == NULL) return(NULL);
3128 ndp = __exprtab[__xndi];
3129 for (;;)
3130 {
3131 if (ndp->optyp == BITREDXOR || ndp->optyp == REDXNOR)
3132 {
3133 savi = __xndi;
3134 __xndi++;
3135 /* treat [term [op] error] as term */
3136 if ((rhsndp = parse_bandop()) == NULL) break;
3137 /* this makes sure optyp right */
3138 ndp = alloc_xtnd(savi);
3139 ndp->lu.x = leftopndp;
3140 ndp->ru.x = rhsndp;
3141 leftopndp = ndp;
3142 ndp = __exprtab[__xndi];
3143 }
3144 else break;
3145 }
3146 return(leftopndp);
3147 }
3148
3149 /*
3150 * parse bit wise and operators
3151 */
parse_bandop(void)3152 static struct expr_t *parse_bandop(void)
3153 {
3154 int32 savi;
3155 struct expr_t *ndp, *rhsndp, *leftopndp;
3156
3157 /* routine leaves __xndi at next place to look */
3158 if ((leftopndp = parse_eqop()) == NULL) return(NULL);
3159 ndp = __exprtab[__xndi];
3160 for (;;)
3161 {
3162 if (ndp->optyp == BITREDAND)
3163 {
3164 /* notice when see binary & must see if following unary red. & */
3165 /* know fence always present */
3166 if (__exprtab[__xndi + 1]->optyp == BITREDAND)
3167 {
3168 __pv_fwarn(564,
3169 "[expr] & &[expr] invalid - unary should be surrounded by parentheses");
3170 }
3171 savi = __xndi;
3172 __xndi++;
3173 if ((rhsndp = parse_eqop()) == NULL) break;
3174 /* this makes sure optyp right */
3175 ndp = alloc_xtnd(savi);
3176 ndp->lu.x = leftopndp;
3177 ndp->ru.x = rhsndp;
3178 leftopndp = ndp;
3179 ndp = __exprtab[__xndi];
3180 }
3181 else break;
3182 }
3183 return(leftopndp);
3184 }
3185
3186 /*
3187 * parse equal not equal operators
3188 */
parse_eqop(void)3189 static struct expr_t *parse_eqop(void)
3190 {
3191 int32 savi;
3192 struct expr_t *ndp, *rhsndp, *leftopndp;
3193
3194 /* routine leaves __xndi at next place to look */
3195 if ((leftopndp = parse_ltgtop()) == NULL) return(NULL);
3196 ndp = __exprtab[__xndi];
3197 for (;;)
3198 {
3199 if (ndp->optyp == RELEQ || ndp->optyp == RELNEQ || ndp->optyp == RELCEQ
3200 || ndp->optyp == RELCNEQ)
3201 {
3202 savi = __xndi;
3203 __xndi++;
3204 if ((rhsndp = parse_ltgtop()) == NULL) break;
3205 /* this makes sure optyp right */
3206 ndp = alloc_xtnd(savi);
3207 ndp->lu.x = leftopndp;
3208 ndp->ru.x = rhsndp;
3209 leftopndp = ndp;
3210 ndp = __exprtab[__xndi];
3211 }
3212 else break;
3213 }
3214 return(leftopndp);
3215 }
3216
3217 /*
3218 * parse a less than or greater than type op
3219 */
parse_ltgtop(void)3220 static struct expr_t *parse_ltgtop(void)
3221 {
3222 int32 savi;
3223 struct expr_t *ndp, *rhsndp, *leftopndp;
3224
3225 /* routine leaves __xndi at next place to look */
3226 if ((leftopndp = parse_shop()) == NULL) return(NULL);
3227 ndp = __exprtab[__xndi];
3228 for (;;)
3229 {
3230 if (ndp->optyp == RELLT || ndp->optyp == RELLE || ndp->optyp == RELGT
3231 || ndp->optyp == RELGE)
3232 {
3233 savi = __xndi;
3234 __xndi++;
3235 if ((rhsndp = parse_shop()) == NULL) break;
3236 /* this makes sure optyp right */
3237 ndp = alloc_xtnd(savi);
3238 ndp->lu.x = leftopndp;
3239 ndp->ru.x = rhsndp;
3240 leftopndp = ndp;
3241 ndp = __exprtab[__xndi];
3242 }
3243 else break;
3244 }
3245 return(leftopndp);
3246 }
3247
3248 /*
3249 * parse a shift type op
3250 */
parse_shop(void)3251 static struct expr_t *parse_shop(void)
3252 {
3253 int32 savi;
3254 struct expr_t *ndp, *rhsndp, *leftopndp;
3255
3256 /* routine leaves __xndi at next place to look */
3257 if ((leftopndp = parse_addop()) == NULL) return(NULL);
3258 ndp = __exprtab[__xndi];
3259 for (;;)
3260 {
3261 if (ndp->optyp == SHIFTL || ndp->optyp == SHIFTR
3262 || ndp->optyp == ASHIFTL || ndp->optyp == ASHIFTR)
3263 {
3264 savi = __xndi;
3265 __xndi++;
3266 if ((rhsndp = parse_addop()) == NULL) break;
3267 /* this makes sure optyp right */
3268 ndp = alloc_xtnd(savi);
3269 ndp->lu.x = leftopndp;
3270 ndp->ru.x = rhsndp;
3271 leftopndp = ndp;
3272 ndp = __exprtab[__xndi];
3273 }
3274 else break;
3275 }
3276 return(leftopndp);
3277 }
3278
3279 /*
3280 * parse a add type op
3281 */
parse_addop(void)3282 static struct expr_t *parse_addop(void)
3283 {
3284 int32 savi;
3285 /* struct expr_t *ndp, *lhsndp, *rhsndp, *opndp, *last_opndp; */
3286 struct expr_t *ndp, *rhsndp, *leftopndp;
3287
3288 /* routine leaves __xndi at next place to look */
3289 if ((leftopndp = parse_mulop()) == NULL) return(NULL);
3290 ndp = __exprtab[__xndi];
3291 /* last_opndp = NULL; */
3292 for (;;)
3293 {
3294 if (ndp->optyp == PLUS || ndp->optyp == MINUS)
3295 {
3296 savi = __xndi;
3297 __xndi++;
3298 if ((rhsndp = parse_mulop()) == NULL) break;
3299 /* this makes sure optyp right */
3300 ndp = alloc_xtnd(savi);
3301 ndp->lu.x = leftopndp;
3302 ndp->ru.x = rhsndp;
3303 leftopndp = ndp;
3304 ndp = __exprtab[__xndi];
3305 }
3306 else break;
3307 }
3308 return(leftopndp);
3309 }
3310
3311 /*
3312 * parse a mult/div type op
3313 */
parse_mulop(void)3314 static struct expr_t *parse_mulop(void)
3315 {
3316 int32 savi;
3317 struct expr_t *ndp, *rhsndp, *leftopndp;
3318
3319 /* routine leaves __xndi at next place to look */
3320 if ((leftopndp = parse_unopterm()) == NULL) return(NULL);
3321 ndp = __exprtab[__xndi];
3322 for (;;)
3323 {
3324 if (ndp->optyp == TIMES || ndp->optyp == DIV || ndp->optyp == MOD)
3325 {
3326 savi = __xndi;
3327 __xndi++;
3328 if ((rhsndp = parse_unopterm()) == NULL) break;
3329 /* this makes sure optyp right */
3330 ndp = alloc_xtnd(savi);
3331 ndp->lu.x = leftopndp;
3332 ndp->ru.x = rhsndp;
3333 leftopndp = ndp;
3334 ndp = __exprtab[__xndi];
3335 }
3336 else break;
3337 }
3338 return(leftopndp);
3339 }
3340
3341 /*
3342 * parse [un. op] <term>
3343 * expects __xndi to point to next place in expr. and moves to 1 after end
3344 *
3345 * parens here surround subexpressions not fcall
3346 */
parse_unopterm(void)3347 static struct expr_t *parse_unopterm(void)
3348 {
3349 int32 sav_xndi;
3350 struct expr_t *ndp, *ndp2, *unopndp, *lastndp;
3351
3352 lastndp = NULL;
3353 unopndp = NULL;
3354 ndp = __exprtab[__xndi];
3355 switch ((byte) ndp->optyp) {
3356 /* notice real number can not start with . (.33 illegal) */
3357 case ID: case NUMBER: case REALNUM: return(parse_term());
3358 case LPAR:
3359 do_parens:
3360 sav_xndi = __xndi++;
3361 if ((ndp2 = parse_qcexpr()) == NULL) return(NULL);
3362 ndp = __exprtab[__xndi];
3363 /* any time in ( expr. may be (expr:expr:expr) form */
3364 /* only parsable because all 3 required if : present */
3365 if (ndp->optyp == COLON)
3366 {
3367 struct expr_t *minxndp, *nomxndp;
3368
3369 minxndp = ndp2;
3370 __xndi++;
3371 if ((ndp2 = parse_qcexpr()) == NULL)
3372 {
3373 mintyp_err:
3374 if (__pv_err_cnt <= __saverr_cnt)
3375 __pv_ferr(1113, "mintypmax expression error at token [%s]",
3376 to_xndnam(__xs, __xndi));
3377 /* must skip one past 3 value form ending ) */
3378 skip_3valend();
3379 return(NULL);
3380 }
3381 nomxndp = ndp2;
3382 ndp = __exprtab[__xndi];
3383 if (ndp->optyp != COLON) goto mintyp_err;
3384 __xndi++;
3385 if ((ndp2 = parse_qcexpr()) == NULL) goto mintyp_err;
3386 ndp = __exprtab[__xndi];
3387 if (ndp->optyp != RPAR) goto mintyp_err;
3388 if (__mintypmax_sel == DEL_MIN) ndp2 = minxndp;
3389 else if (__mintypmax_sel == DEL_TYP) ndp2 = nomxndp;
3390 __xndi++;
3391 if (sav_xndi == 0) __has_top_mtm = TRUE;
3392 goto unop_ret;
3393 }
3394 /* either eox or ) seen or will not get here */
3395 if (ndp->optyp != RPAR)
3396 {
3397 __pv_ferr(1113,
3398 "expression primary or mintypmax expression ending ) expected - %s read",
3399 to_xndnam(__xs, __xndi));
3400 return(NULL);
3401 }
3402 __xndi++;
3403 goto unop_ret;
3404 }
3405 if (is_unop(ndp->optyp))
3406 {
3407 rep_unops:
3408 if (ndp->optyp != PLUS)
3409 {
3410 ndp = alloc_xtnd(__xndi);
3411 ndp->ru.x = NULL;
3412 if (lastndp == NULL) unopndp = ndp; else lastndp->lu.x = ndp;
3413 lastndp = ndp;
3414 }
3415
3416 ndp2 = __exprtab[++__xndi];
3417 if (ndp2->optyp == LPAR) goto do_parens;
3418 /* unary operator chain */
3419 if (is_unop(ndp2->optyp))
3420 {
3421 ndp = ndp2;
3422 goto rep_unops;
3423 }
3424
3425 if ((ndp2 = parse_term()) == NULL) return(NULL);
3426 /* add to end of possible linear unary operator chain */
3427 unop_ret:
3428 if (lastndp == NULL) unopndp = ndp2; else lastndp->lu.x = ndp2;
3429 return(unopndp);
3430 }
3431 return(parse_term());
3432 }
3433
3434 /*
3435 * on error in 3 value expression must skip to eox or 1 past same level )
3436 */
skip_3valend(void)3437 static void skip_3valend(void)
3438 {
3439 int32 paren_level;
3440
3441 for (paren_level = 0; __xndi <= __last_xtk; __xndi++)
3442 {
3443 switch ((byte) __exprtab[__xndi]->optyp) {
3444 case UNDEF: return;
3445 case LPAR: paren_level++; break;
3446 case RPAR:
3447 if (paren_level == 0) { __xndi++; return; }
3448 else paren_level--;
3449 }
3450 }
3451 }
3452
3453 /*
3454 * return T if expression node is a unary operator that does not require
3455 * special processing
3456 */
is_unop(word32 otyp)3457 static int32 is_unop(word32 otyp)
3458 {
3459 struct opinfo_t *opip;
3460
3461 opip = &(__opinfo[otyp]);
3462 if (opip->opclass == UNOP || opip->opclass == BOTHOP) return(TRUE);
3463 return(FALSE);
3464 }
3465
3466 /*
3467 * parse a terminal
3468 *
3469 * expects __xndi at current place and leaves __xndi index one
3470 * past end of terminal
3471 *
3472 * notice Verilog terminals need special routine - too complicated
3473 * to parse using grammar
3474 *
3475 * here can use expridtab and exprtab as arguments to routine because
3476 * these are not overwritten but globals that parsing marches through
3477 *
3478 * no error recovery because already have collected only expr
3479 */
parse_term(void)3480 static struct expr_t *parse_term(void)
3481 {
3482 struct expr_t *ndp, *ndp2, *idndp, *glbndp;
3483 struct sy_t *syp;
3484 struct expridtab_t *xidp;
3485
3486 /* some kind of terminal */
3487 ndp = __exprtab[__xndi];
3488 switch ((byte) ndp->optyp) {
3489 case NUMBER: case REALNUM: case OPEMPTY:
3490 /* 06/22/00 - SJM - if 2 numeric tokens in a row assume sized num */
3491 /* FIXME - need error recovery here - indicate 2nd is part of 2 tok num */
3492 if (__exprtab[__xndi + 1]->optyp == NUMBER)
3493 {
3494 struct expr_t *ndp3;
3495
3496 ndp3 = __exprtab[__xndi + 1];
3497 if (!ndp->unsiznum || ndp->ibase != BDEC || ndp3->unsiznum
3498 || ndp3->sizdflt) goto not_2tok_num;
3499 __xndi++;
3500 }
3501
3502 not_2tok_num:
3503 /* this copies any constant value from __exprtab[] */
3504 ndp = alloc_xtnd(__xndi);
3505 __xndi++;
3506 return(ndp);
3507 case LCB:
3508 ndp2 = parse_concat();
3509 return(ndp2);
3510 case ID:
3511 idndp = alloc_xtnd(__xndi);
3512 xidp = __expr_idtab[__xndi];
3513 /* DBG remove --- */
3514 if (xidp == NULL) __misc_terr(__FILE__, __LINE__);
3515 /* --- */
3516
3517 /* move one past ID */
3518 __xndi++;
3519 ndp = __exprtab[__xndi];
3520
3521 /* special case determine and return no argument sys fcall */
3522 /* system function no args legal - $ no ( implies function call */
3523 /* for range expr. ndp sy == NULL true */
3524 /* ID that is system func call, can not be glb. ref. */
3525 /* LOOKATME - can access functions start with $ - think not */
3526 if (xidp->idnam[0] == '$' && ndp->optyp != LPAR)
3527 {
3528 if ((syp = __get_sym(xidp->idnam, __syssyms)) == NULL)
3529 {
3530 __pv_ferr(683,
3531 "call of unknown built-in or unregistered PLI system function %s illegal - for dynamic, register generic place holder",
3532 xidp->idnam);
3533 return(NULL);
3534 }
3535 /* attempt to call ID starting with $ (must be system task?) illegal */
3536 if (syp->sytyp != SYM_SF)
3537 {
3538 __pv_ferr(681,
3539 "illegal call of system task %s - only functions calleable",
3540 syp->synam);
3541 return(NULL);
3542 }
3543
3544 idndp->lu.sy = syp;
3545 /* error if system function used in xmr */
3546 if (ndp->optyp == DOT)
3547 {
3548 __pv_ferr(1127,
3549 "call of system function %s followed by '.' - illegal hierarchical reference",
3550 idndp->lu.sy->synam);
3551 return(NULL);
3552 }
3553 ndp2 = __alloc_newxnd();
3554 ndp2->optyp = FCALL;
3555 ndp2->lu.x = idndp;
3556 ndp2->ru.x = NULL;
3557 return(ndp2);
3558 }
3559
3560
3561 /* if system func with args, continue to normal fcall */
3562 if (ndp->optyp == LSB)
3563 {
3564 /* inst array ref. then fix global resolution code to make select */
3565 /* on error returns nil - can not parse possible rest of expr */
3566 if ((ndp2 = parse_select(idndp)) == NULL) return(NULL);
3567
3568 /* xndi one past end of select - xmr is special case */
3569 /* routine will not add path components to current sym table */
3570 if (__exprtab[__xndi]->optyp == DOT)
3571 {
3572 if ((glbndp = parse_glbref(ndp2, xidp)) == NULL) return(NULL);
3573 if (__exprtab[__xndi]->optyp != LPAR) return(glbndp);
3574
3575 /* xmr followed by ( is function call - 1st comp. inst arr case */
3576 /* can not be system func and therefore '(' required */
3577 ndp2 = parse_fcall(glbndp, NULL, TRUE);
3578 return(ndp2);
3579 }
3580 /* part select never legal for one comp array of insts select */
3581 if (__allow_scope_var && ndp2->optyp == LSB)
3582 {
3583 /* if already declared as net t in current env., know not glb */
3584 /* must also be net - since net is never xmr */
3585 if ((syp = __get_sym_env(xidp->idnam)) != NULL && syp->sytyp == SYM_N)
3586 goto do_decl;
3587
3588 /* notice this can not fail - make ID into global ref. */
3589 return(bld_1cmp_global(ndp2, xidp));
3590 }
3591
3592 do_decl:
3593 /* not xmr - declare the ID symbol */
3594 if (!decl_id_inexpr(idndp, xidp)) return(NULL);
3595 return(ndp2);
3596 }
3597 if (ndp->optyp == LPAR)
3598 {
3599
3600 /* fcall can be xmr, handle in global parsing routine */
3601 /* this works because user function (no $ first char) must have args */
3602 ndp2 = parse_fcall(idndp, xidp, FALSE);
3603 return(ndp2);
3604 }
3605 /* simple ID - current location one after ID */
3606 /* non special terminal - next is lower precedence rest of expr */
3607 if (__exprtab[__xndi]->optyp == DOT)
3608 {
3609 if ((glbndp = parse_glbref(idndp, xidp)) == NULL) return(NULL);
3610
3611 if (__exprtab[__xndi]->optyp != LPAR) return(glbndp);
3612
3613 /* xmr followed by ( is function call - non inst array 1st comp case */
3614 ndp2 = parse_fcall(glbndp, NULL, TRUE);
3615 return(ndp2);
3616 }
3617 if (__allow_scope_var)
3618 {
3619 /* notice this can not fail - make ID into global ref. */
3620 return(bld_1cmp_global(idndp, xidp));
3621 }
3622
3623 if (!decl_id_inexpr(idndp, xidp)) return(NULL);
3624 return(idndp);
3625 case DOT:
3626 /* need exact error for ID that starts with . */
3627 __pv_ferr(1128,
3628 "hierarchical reference or real constant initial '.' illegal");
3629 return(NULL);
3630 default:
3631 if (__pv_err_cnt <= __saverr_cnt)
3632 __pv_ferr(1116, "expression terminal expected - %s read",
3633 to_xndnam(__xs, __xndi));
3634 }
3635 return(NULL);
3636 }
3637
3638
3639 /*
3640 * routine to find symbol in symbol table adding if needed
3641 *
3642 * must not call until ID known not to be part of xmr
3643 * name of variable taken from expr id nam global table
3644 */
decl_id_inexpr(struct expr_t * ndp,struct expridtab_t * xidp)3645 static int32 decl_id_inexpr(struct expr_t *ndp, struct expridtab_t *xidp)
3646 {
3647 struct sy_t *syp;
3648 struct net_t *np;
3649
3650 /* routine never called for function call or task enable */
3651 /* DBG remove --- */
3652 if (xidp->idnam[0] == '$') __arg_terr(__FILE__, __LINE__);
3653 /* --- */
3654
3655 ndp->lu.x = NULL;
3656 /* since parse range as select with dummy var leave sy field nil for "[]" */
3657 if (xidp->idnam[0] == '[') return(TRUE);
3658
3659 if ((syp = __get_sym_env(xidp->idnam)) == NULL)
3660 {
3661 /* undeclared specify declared as net var in current sym tab */
3662 if (__cur_declobj == SPECIFY)
3663 syp = __decl_sym(xidp->idnam, __venviron[__top_sti]);
3664 /* undeclared var. declared at module level because task/block */
3665 /* declaration must come first and therefore will be declared */
3666 else
3667 {
3668 if (__iact_state)
3669 {
3670 /* interactive statement - all variables must be declared */
3671 /* for $dumpvars will avoid this code and jump to assume glb */
3672 __pv_err_cnt++;
3673 if (strcmp(xidp->idnam, "") == 0)
3674 {
3675 __ia_err(1436,
3676 "escaped identifier empty - probable white space before escaped continuation new line");
3677 }
3678 else __ia_err(1436, "variable %s not declared", xidp->idnam);
3679 return(FALSE);
3680 }
3681 else syp = __decl_sym(xidp->idnam, __venviron[0]);
3682 }
3683
3684 np = __add_net(syp);
3685 /* assume register - this is forward decl */
3686 /* even if in specify assume wire and fix up when declared */
3687 np->ntyp = N_REG;
3688 syp->sylin_cnt = xidp->idlin_cnt;
3689 syp->syfnam_ind = xidp->idfnam_ind;
3690 }
3691 ndp->lu.sy = syp;
3692 return(TRUE);
3693 }
3694
3695 /*
3696 * find a a system task/func symbol (know name starts with $)
3697 * must be system function or task (maybe PLI)
3698 *
3699 * notice no special processing of scale arg. since must be var.
3700 * in module from which scale taken
3701 */
find_systf_sym(struct expridtab_t * xidp)3702 static struct sy_t *find_systf_sym(struct expridtab_t *xidp)
3703 {
3704 struct sy_t *syp;
3705
3706 /* look up in system task/func symbol table - must be there*/
3707 /* PLI redefine legal and will be in this symbol table */
3708 if ((syp = __get_sym(xidp->idnam, __syssyms)) == NULL)
3709 {
3710 if (__expr_is_lval)
3711 __gferr(1102, xidp->idfnam_ind, xidp->idlin_cnt,
3712 "enable of unknown system task or undefined PLI task %s",
3713 xidp->idnam);
3714 else
3715 __gferr(1102, xidp->idfnam_ind, xidp->idlin_cnt,
3716 "call of unknown system or undefined PLI function %s",
3717 xidp->idnam);
3718 return(NULL);
3719 }
3720 /* if lvalue, must be system table enable */
3721 if (__expr_is_lval)
3722 {
3723 if (syp->sytyp != SYM_STSK)
3724 {
3725 __gferr(1100, xidp->idfnam_ind, xidp->idlin_cnt,
3726 "attempt to enable (not call) system function %s", xidp->idnam);
3727 return(NULL);
3728 }
3729 }
3730 else
3731 {
3732 if (syp->sytyp != SYM_SF)
3733 {
3734 __gferr(1103, xidp->idfnam_ind, xidp->idlin_cnt,
3735 "call of system task %s illegal", xidp->idnam);
3736 return(NULL);
3737 }
3738 }
3739 return(syp);
3740 }
3741
3742 /*
3743 * parse a concatenate
3744 * know current expr. token is leading { and points to one after }
3745 * on non error (non NULL) return
3746 *
3747 * form is: {el, el, ..., el}, where el. is <expr.>, { concat, or
3748 * <expr> concat
3749 *
3750 * must be optimized after building tree
3751 * for now optimize just remove one element concatenates and dups
3752 * rep concat. form
3753 */
parse_concat(void)3754 static struct expr_t *parse_concat(void)
3755 {
3756 struct expr_t *ndp, *ndp2, *argndp, *last_ndp;
3757 struct expr_t *lop;
3758
3759 ndp2 = alloc_xtnd(__xndi);
3760 __xndi++;
3761 ndp2->lu.x = NULL;
3762
3763 for (last_ndp = NULL;;)
3764 {
3765 if ((argndp = parse_qcexpr()) == NULL) return(NULL);
3766 add_to_tree:
3767 ndp = __exprtab[__xndi];
3768
3769 /* processing depends on thing after 1st concat el. */
3770 switch ((byte) ndp->optyp) {
3771 case COMMA:
3772 /* build node since at least one more concat element */
3773 lop = __alloc_newxnd();
3774 lop->optyp = CATCOM;
3775 if (last_ndp == NULL) ndp2->ru.x = lop; else last_ndp->ru.x = lop;
3776 lop->lu.x = argndp;
3777 last_ndp = lop;
3778 /* must skip over comma */
3779 __xndi++;
3780 break;
3781 case RCB:
3782 /* done - notice last CATCOM node has NULL right pointer */
3783 lop = __alloc_newxnd();
3784 lop->optyp = CATCOM;
3785 if (last_ndp == NULL) ndp2->ru.x = lop; else last_ndp->ru.x = lop;
3786 lop->lu.x = argndp;
3787 lop->ru.x = NULL;
3788 __xndi++;
3789 return(ndp2);
3790 case LCB:
3791 {
3792 struct expr_t *repndp, *catndp;
3793
3794 repndp = argndp;
3795 if ((catndp = parse_concat()) == NULL) return(NULL);
3796
3797 argndp = __alloc_newxnd();
3798 argndp->optyp = CATREP;
3799 argndp->lu.x = repndp;
3800 argndp->ru.x = catndp;
3801 }
3802 goto add_to_tree;
3803 default:
3804 if (__pv_err_cnt <= __saverr_cnt)
3805 __pv_ferr(1119,
3806 "nested concatenate or comma separator expected - %s read",
3807 to_xndnam(__xs, __xndi));
3808 /* as special case for concat, must skip to } if possible */
3809 __vskipto_any(RCB);
3810 return(NULL);
3811 }
3812 }
3813 }
3814
3815 /*
3816 * parse a select
3817 * copies into malloced storage and return select expr subtree
3818 * know id ndp already copied to malloced storage
3819 *
3820 * [ read - reads one past ending ]
3821 */
parse_select(struct expr_t * idndp)3822 static struct expr_t *parse_select(struct expr_t *idndp)
3823 {
3824 struct expr_t *ndp, *sel_ndp, *i1ndp, *i2ndp;
3825
3826 /* build (alloc and copy) select sub expression root */
3827 sel_ndp = alloc_xtnd(__xndi);
3828 __xndi++;
3829 /* side effect of parsing sub expression is advancing global x ndi */
3830 /* returned i1ndp is malloced not built in __exprtab */
3831 if ((i1ndp = parse_qcexpr()) == NULL) return(NULL);
3832 sel_ndp->lu.x = idndp;
3833 ndp = __exprtab[__xndi];
3834 if (ndp->optyp == RSB)
3835 {
3836 sel_ndp->ru.x = i1ndp;
3837 __xndi++;
3838 /* next may be dot (handled as term by caller) or rest of expr */
3839 return(sel_ndp);
3840 }
3841 /* part select - if illegal in context caller must detect */
3842 if (ndp->optyp != COLON)
3843 {
3844 if (__pv_err_cnt <= __saverr_cnt)
3845 __pv_ferr(1114,
3846 "bit/part select expression : or ] separator expected - %s read",
3847 to_xndnam(__xs, __xndi));
3848 /* if T, current is one past ending ] */
3849 return(NULL);
3850 }
3851 /* part select after : */
3852 __xndi++;
3853 if ((i2ndp = parse_qcexpr()) == NULL) return(NULL);
3854 ndp = __exprtab[__xndi];
3855 if (ndp->optyp != RSB)
3856 {
3857 if (__pv_err_cnt <= __saverr_cnt)
3858 __pv_ferr(1115,
3859 "part select expression ending ] expected - %s read",
3860 to_xndnam(__xs, __xndi));
3861 return(NULL);
3862 }
3863 sel_ndp->optyp = PARTSEL;
3864 ndp = alloc_xtnd(__xndi);
3865 ndp->optyp = COLON;
3866 sel_ndp->ru.x = ndp;
3867 ndp->lu.x = i1ndp;
3868 ndp->ru.x = i2ndp;
3869 /* move one past RSB if possible */
3870 if (__xndi < __last_xtk) __xndi++;
3871 /* part select never xmr */
3872 return(sel_ndp);
3873 }
3874
3875 /*
3876 * parse and and build global record for xmr
3877 *
3878 * current expr table node is one past id (dot or [) when called
3879 * reads one past end of xmr
3880 * argument is xmr first component expression and id name tab element
3881 * returns expression that may be select (if var tail is select)
3882 *
3883 * allowing constant selects for arrays of instances and gates
3884 * for say a[a+b].b.c.w[kk], w[kk] is bit select of variable
3885 * for xmr instance allowed context - gets fixed up to instance
3886 *
3887 * changes IDs where unparsed name in expr id tab move to
3888 * expr node with special XMRID node type
3889 */
parse_glbref(struct expr_t * cmp1_ndp,struct expridtab_t * cmp1_xidp)3890 static struct expr_t *parse_glbref(struct expr_t *cmp1_ndp,
3891 struct expridtab_t *cmp1_xidp)
3892 {
3893 int32 is_sel;
3894 struct expr_t *ndp, *glbndp, *last_cmp;
3895 struct expr_t *idndp, *ndp2, *cmp_ndp;
3896 struct expridtab_t *xidp;
3897 struct gref_t *grp;
3898
3899 /* expr. has top level global then each xmr comma left points to id */
3900 /* or select for inst or gate array */
3901 glbndp = __alloc_newxnd();
3902 glbndp->optyp = GLBREF;
3903 glbndp->ru.x = __alloc_newxnd();
3904 glbndp->ru.x->optyp = XMRCOM;
3905 glbndp->ru.x->lu.x = cmp1_ndp;
3906
3907 if (cmp1_ndp->optyp == LSB)
3908 {
3909 /* select already parsed and bsel expr. built */
3910 /* cmp ndp ru field set to idnam for first comp. of global */
3911 cmp1_ndp->lu.x->ru.qnchp = __pv_stralloc(cmp1_xidp->idnam);
3912 /* current xndi now one past end of select */
3913 cmp1_ndp->lu.x->optyp = XMRID;
3914 }
3915 else if (cmp1_ndp->optyp == ID)
3916 {
3917 /* unused ru field used for name, lu.sy to xmr dest. filled later */
3918 cmp1_ndp->ru.qnchp = __pv_stralloc(cmp1_xidp->idnam);
3919 cmp1_ndp->optyp = XMRID;
3920 }
3921 else if (cmp1_ndp->optyp != DOT)
3922 {
3923 /* notice here gnam no build and rest of gref expr no read */
3924 __pv_ferr(682, "hierarchical reference contains illegal operator %s",
3925 __to_opname(cmp1_ndp->optyp));
3926 return(NULL);
3927 }
3928
3929 /* DBG remove --- */
3930 if (__exprtab[__xndi]->optyp != DOT) __arg_terr(__FILE__, __LINE__);
3931 /* --- */
3932
3933 /* last comp is always right tree end expr. comp */
3934 last_cmp = glbndp->ru.x;
3935 /* know this will be dot at start */
3936 for (;;)
3937 {
3938 /* move one past dot */
3939 __xndi++;
3940 ndp = __exprtab[__xndi];
3941
3942 /* only use of dot in expr is for xmr - must be followed by ID */
3943 if (ndp->optyp != ID)
3944 {
3945 __pv_ferr(1136,
3946 "hierarchical reference '.' separator not followed by identifier: %s read",
3947 to_xndnam(__xs, __xndi));
3948 return(NULL);
3949 }
3950 idndp = alloc_xtnd(__xndi);
3951 xidp = __expr_idtab[__xndi];
3952 /* DBG remove --- */
3953 if (xidp == NULL) __misc_terr(__FILE__, __LINE__);
3954 /* --- */
3955
3956 /* move past identifier to dot separator or [ select - any other end */
3957 __xndi++;
3958 ndp = __exprtab[__xndi];
3959 /* assume not a end of xmr select */
3960 is_sel = FALSE;
3961 /* access possible select - if not select add ID */
3962 if (ndp->optyp == LSB)
3963 {
3964 /* cmp ndp copied to malloced storage */
3965 /* in select non xmr expressions added to sym table since */
3966 /* they exist in reference context */
3967 if ((cmp_ndp = parse_select(idndp)) == NULL) return(NULL);
3968 /* current xndi now one past end of select */
3969 cmp_ndp->lu.x->ru.qnchp = __pv_stralloc(xidp->idnam);
3970 cmp_ndp->lu.x->optyp = XMRID;
3971 /* move to next which must be dot after ending ] */
3972 ndp = __exprtab[__xndi];
3973 if (!__allow_scope_var) is_sel = TRUE;
3974 /* inst. part select inside xmrs illegal */
3975 if (cmp_ndp->optyp == PARTSEL && ndp->optyp == DOT)
3976 {
3977 __pv_ferr(682,
3978 "hierarchical reference part select of array of instances illegal");
3979 return(NULL);
3980 }
3981 }
3982 /* know seen ID not followed by . - done */
3983 else
3984 {
3985 /* simple ID component (maybe at end) */
3986 cmp_ndp = idndp;
3987 cmp_ndp->ru.qnchp = __pv_stralloc(xidp->idnam);
3988 cmp_ndp->optyp = XMRID;
3989 }
3990
3991 if (ndp->optyp != DOT)
3992 {
3993 /* end of xmr - not followed by dot - must be end of expr */
3994 if (!is_sel)
3995 {
3996 /* end is simple ID but must not be added to symbol table */
3997 ndp2 = __alloc_newxnd();
3998 ndp2->optyp = XMRCOM;
3999 ndp2->lu.x = cmp_ndp;
4000 ndp2->ru.x = NULL;
4001 last_cmp->ru.x = ndp2;
4002 }
4003 else
4004 {
4005 /* need to add comp ID to end as ID not select because select of xmr */
4006 ndp2 = __alloc_newxnd();
4007 ndp2->optyp = XMRCOM;
4008 ndp2->lu.x = cmp_ndp->lu.x;
4009 ndp2->ru.x = NULL;
4010 last_cmp->ru.x = ndp2;
4011
4012 cmp_ndp->lu.x = glbndp;
4013 glbndp = cmp_ndp;
4014 }
4015 break;
4016 }
4017
4018 /* if followed by '.', add to tail of xmr expr and get next cmp */
4019 ndp2 = __alloc_newxnd();
4020 ndp2->optyp = XMRCOM;
4021 /* know cmp ndp copied to malloced storage */
4022 ndp2->lu.x = cmp_ndp;
4023 ndp2->ru.x = NULL;
4024 last_cmp->ru.x = ndp2;
4025 last_cmp = ndp2;
4026 }
4027 /* tail component is select - assume wire - i.e. not part of inst arr */
4028 /* rare inst. allowd context fixed up later by caller if needed */
4029 /* cmp ndx rotated to become top of select expr. */
4030 /* first add ID part of select to end of xmr */
4031 if (is_sel)
4032 {
4033 grp = __bld_glbref(glbndp->lu.x, cmp1_xidp->idfnam_ind,
4034 cmp1_xidp->idlin_cnt);
4035 }
4036 else
4037 {
4038 /* know x ndi pointing to one past end of xmr */
4039 grp = __bld_glbref(glbndp, cmp1_xidp->idfnam_ind, cmp1_xidp->idlin_cnt);
4040 }
4041
4042 /* for interactive now can resolve global (case for ID in expr.) */
4043 if (__iact_state)
4044 { __resolve_glbnam(grp); __fill_grp_targu_fld(grp); }
4045 return(glbndp);
4046 }
4047
4048 /*
4049 * IDs when allow scope var on (scope system task contexts) make globals
4050 *
4051 * during resolution will be converted back to wires if needed
4052 * for these special contexts since need scope ref. even if net with
4053 * same name instance takes precedence (conflict can be labeled block
4054 * local variable versus task name)
4055 */
bld_1cmp_global(struct expr_t * ndp,struct expridtab_t * xidp)4056 static struct expr_t *bld_1cmp_global(struct expr_t *ndp,
4057 struct expridtab_t *xidp)
4058 {
4059 struct expr_t *glbndp, *cmp_ndp;
4060 struct gref_t *grp;
4061
4062 /* build the one component */
4063 cmp_ndp = ndp;
4064 if (ndp->optyp == ID)
4065 {
4066 cmp_ndp->ru.qnchp = __pv_stralloc(xidp->idnam);
4067 cmp_ndp->optyp = XMRID;
4068 }
4069 else
4070 {
4071 /* build the one component as select form */
4072 cmp_ndp = ndp;
4073 cmp_ndp->lu.x->optyp = XMRID;
4074 cmp_ndp->lu.x->ru.qnchp = __pv_stralloc(xidp->idnam);
4075 }
4076
4077 /* build the top level global */
4078 glbndp = __alloc_newxnd();
4079 glbndp->optyp = GLBREF;
4080 glbndp->ru.x = __alloc_newxnd();
4081 glbndp->ru.x->optyp = XMRCOM;
4082 glbndp->ru.x->lu.x = cmp_ndp;
4083
4084 grp = __bld_glbref(glbndp, xidp->idfnam_ind, xidp->idlin_cnt);
4085
4086 /* for interactive now can resolve global (case for ID in expr.) */
4087 if (__iact_state)
4088 {
4089 /* if really local since dumpvars illegal, caller emits error */
4090 __resolve_glbnam(grp);
4091 if (!grp->gr_gone && !grp->gr_err) __fill_grp_targu_fld(grp);
4092 }
4093 return(glbndp);
4094 }
4095
4096 /*
4097 * build a global reference entry in work table and convert glb ref ndp
4098 *
4099 * later work table is copied into right size allocated mod table
4100 *
4101 * at this build point, only link if from expression
4102 * caller must set line and file location
4103 */
__bld_glbref(struct expr_t * glbndp,int32 gfnam_ind,int32 glin_cnt)4104 extern struct gref_t *__bld_glbref(struct expr_t *glbndp, int32 gfnam_ind,
4105 int32 glin_cnt)
4106 {
4107 struct gref_t *grp;
4108 struct expr_t *glbpth_ndp;
4109 char *gnam;
4110
4111 /* convert global expr to name */
4112 /* for inst/gate arrays later will free and regenerate with const indices */
4113 /* notice gnam malloced because xmr expr. can be long here */
4114 /* and malloced to exact size of string (plus room for ending \0) */
4115 gnam = alloc_glbndp_tostr(glbndp);
4116
4117 if ((++__grwrknum) >= __grwrktabsiz) grow_grtab();
4118 grp = &(__grwrktab[__grwrknum - 1]);
4119
4120 /* SJM 03/19/00 - gnam malloced above, now linked onto grp - must not free */
4121 init_gref(grp, gnam);
4122 grp->grfnam_ind = gfnam_ind;
4123 grp->grflin_cnt = glin_cnt;
4124
4125 /* first save global as path expr. then convert to gref */
4126 /* must use glbref because that expr. is linked correctly in source stmts */
4127 glbpth_ndp = glbndp->ru.x;
4128 grp->gxndp = glbndp;
4129 grp->gxndp->ru.grp = grp;
4130
4131 /* link global reference as XMR expr. off of gref */
4132 grp->glbref = __alloc_newxnd();
4133 grp->glbref->optyp = GLBPTH;
4134 grp->glbref->ru.x = glbpth_ndp;
4135
4136 /* lu.x gets filled later with destination symbol (of net usually) */
4137 /* DBG remove --- */
4138 if (grp->gxndp->lu.x != NULL) __misc_terr(__FILE__, __LINE__);
4139 /* --- */
4140
4141 /* accessed through symbol field to gref */
4142 if (__allow_scope_var) grp->gr_inst_ok = TRUE;
4143 if (__iact_state)
4144 {
4145 /* for interact global, current scope determines */
4146 if (__scope_tskp != NULL) grp->grsytp = __scope_tskp->tsksymtab;
4147 else grp->grsytp = __scope_ptr->itip->imsym->el.emdp->msymtab;
4148 grp->gin_mdp = __scope_ptr->itip->imsym->el.emdp;
4149 /* for interactive will be resolved when expression parsed */
4150 }
4151 else
4152 {
4153 /* this is the symbol table gref appears in */
4154 grp->grsytp = __venviron[__top_sti];
4155 grp->gin_mdp = __inst_mod;
4156 }
4157 return(grp);
4158 }
4159
4160 /*
4161 * grow global gref work table
4162 */
grow_grtab(void)4163 static void grow_grtab(void)
4164 {
4165 int32 old_grtsiz, osize, nsize;
4166
4167 old_grtsiz = __grwrktabsiz;
4168 osize = old_grtsiz*sizeof(struct gref_t);
4169 __grwrktabsiz = (3*__grwrktabsiz)/2;
4170 nsize = __grwrktabsiz*sizeof(struct gref_t);
4171 __grwrktab = (struct gref_t *) __my_realloc((char *) __grwrktab, osize,
4172 nsize);
4173 }
4174
4175 /*
4176 * generate a name for a global refence
4177 *
4178 * uses msg expr to string mechanism for instance array selects
4179 * does not assume select is constant expression
4180 *
4181 * LOOKATME - assume xmr component name ID[<expr>] is name and
4182 * therefore expression plus ID must be less the ID max length
4183 */
alloc_glbndp_tostr(struct expr_t * glbndp)4184 static char *alloc_glbndp_tostr(struct expr_t *glbndp)
4185 {
4186 register struct expr_t *gcmp_ndp, *ndp;
4187 int32 slen, glen, gstrsiz;
4188 char *chp, *gnam, s1[IDLEN];
4189
4190 /* DBG remove --- */
4191 if (glbndp->optyp != GLBREF) __arg_terr(__FILE__, __LINE__);
4192 /* --- */
4193 /* this is starting size only - can grow */
4194 gstrsiz = IDLEN;
4195 gnam = __my_malloc(gstrsiz);
4196 /* must move right down tree one to get first component */
4197 for (gcmp_ndp = glbndp->ru.x, glen = 0;;)
4198 {
4199 ndp = gcmp_ndp->lu.x;
4200 if (ndp->optyp == XMRID) chp = ndp->ru.qnchp;
4201 else if (ndp->optyp == LSB || ndp->optyp == PARTSEL)
4202 {
4203 /* build the <id>[<expr>] expression as string */
4204 /* works because XMRID nodes know to dmp expr */
4205 chp = __msgexpr_tostr(s1, ndp);
4206 }
4207 else { __arg_terr(__FILE__, __LINE__); return(NULL); }
4208
4209 /* DBG LINT remove -- */
4210 if (chp == NULL) __misc_terr(__FILE__, __LINE__);
4211 /* -- */
4212
4213 slen = strlen(chp);
4214 /* add room for '.' separator */
4215 if (glen != 0) slen++;
4216 /* need room for one final \0 to end string */
4217 if (glen + slen + 1 >= gstrsiz)
4218 {
4219 gnam = __my_realloc(gnam, gstrsiz, gstrsiz + IDLEN);
4220 gstrsiz += IDLEN;
4221 }
4222 if (glen == 0) strcpy(gnam, chp);
4223 else { gnam[glen] = '.'; strcpy(&(gnam[glen + 1]), chp); }
4224 glen += slen;
4225
4226 if ((gcmp_ndp = gcmp_ndp->ru.x) == NULL) break;
4227 /* DBG remove --- */
4228 if (gcmp_ndp->optyp != XMRCOM) __arg_terr(__FILE__, __LINE__);
4229 /* --- */
4230 }
4231 gnam[glen] = '\0';
4232 /* realloc to exact string size */
4233 if (glen + 1 != gstrsiz)
4234 {
4235 gnam = __my_realloc(gnam, gstrsiz, glen + 1);
4236 }
4237 return(gnam);
4238 }
4239
4240 /*
4241 * convert glb ref expression into string
4242 *
4243 * when first read now since do not know index constant expression values
4244 * is printed name - fixed later to use number indices
4245 */
4246
4247 /*
4248 * allocate a input phase global ref. record
4249 *
4250 * BEWARE - gnam must be malloced not fixed string
4251 */
init_gref(struct gref_t * grp,char * gnam)4252 static void init_gref(struct gref_t *grp, char *gnam)
4253 {
4254 grp->gnam = gnam;
4255 grp->gr_err = FALSE;
4256 /* assume in decl. code */
4257 grp->upwards_rel = FALSE;
4258 grp->is_upreltsk = FALSE;
4259 grp->is_rooted = FALSE;
4260 grp->path_has_isel = FALSE;
4261 grp->pathisel_done = FALSE;
4262 grp->gr_inst_ok = FALSE;
4263 grp->gr_defparam = FALSE;
4264 grp->gr_gone = FALSE;
4265
4266 grp->gxndp = NULL;
4267 grp->glbref = NULL;
4268 grp->grsytp = NULL;
4269 grp->targmdp = NULL;
4270 grp->targtskp = NULL;
4271 grp->grfnam_ind = 0;
4272 grp->grflin_cnt = 0;
4273 grp->grcmps = NULL;
4274 grp->grxcmps = NULL;
4275 grp->last_gri = -1;
4276 grp->targu.targitp = NULL;
4277 grp->targsyp = NULL;
4278 grp->spltgrp = NULL;
4279 }
4280
4281 /*
4282 * parse a function call
4283 * called when ( seen immediately after
4284 * know __xndi points to ( and moves one past ending )
4285 * ,, form legal for system functions but not user - caught elsewhere
4286 */
parse_fcall(struct expr_t * fcall_ndp,struct expridtab_t * xidp,int32 is_glb)4287 static struct expr_t *parse_fcall(struct expr_t *fcall_ndp,
4288 struct expridtab_t *xidp, int32 is_glb)
4289 {
4290 int32 is_sysfunc;
4291 struct expr_t *ndp, *fchdrx, *argndp, *last_ndp, *lop;
4292
4293 is_sysfunc = FALSE;
4294 /* for non global function call, check symbol type and add if needed */
4295 if (!is_glb)
4296 {
4297 /* only fails if interactive and unable to find - stmt parser handles */
4298 /* error skipping */
4299 if (!chk_decl_func(&is_sysfunc, fcall_ndp, xidp)) return(NULL);
4300 }
4301 else
4302 {
4303 /* because can not tell if select of last component is from wire */
4304 /* error if global is select - no other checking possible here */
4305 if (fcall_ndp->optyp != GLBREF)
4306 {
4307 __pv_ferr(1137,
4308 "hierarchical function call name %s illegal select",
4309 __msgexpr_tostr(__xs, fcall_ndp));
4310 return(NULL);
4311 }
4312 }
4313
4314 fchdrx = alloc_xtnd(__xndi);
4315 fchdrx->optyp = FCALL;
4316 fchdrx->lu.x = fcall_ndp;
4317 __xndi++;
4318 ndp = __exprtab[__xndi];
4319 if (ndp->optyp == RPAR && !is_sysfunc)
4320 {
4321 __pv_ferr(1120,
4322 "Verilog user defined function call requires at least one argument - () illegal");
4323 return(NULL);
4324 }
4325 /* now checking moved 1 past 1st token of 1st expr. */
4326 /* expr. structure identical to concatenate , present even for 1 arg. */
4327 /* can trace through br x rights until NULL */
4328 /* task port list for functs has extra 1st ret. argument but not expr. */
4329 for (last_ndp = fchdrx;;)
4330 {
4331 ndp = __exprtab[__xndi];
4332 /* case 1: empty expr. only allowed for built-in or PLI sysfuncs */
4333 if (ndp->optyp == COMMA || ndp->optyp == RPAR)
4334 {
4335 if (!is_sysfunc)
4336 {
4337 __pv_ferr(1121,
4338 "user function %s call empty ',,' argument form illegal",
4339 __to_idnam(fcall_ndp));
4340 argndp = __alloc_newxnd();
4341 /* user function error, make 1 bit x */
4342 __set_numval(argndp, 1L, 1L, 1);
4343 }
4344 else
4345 {
4346 /* must allocate new xnode because need both ,'s of ,, */
4347 argndp = __alloc_newxnd();
4348 argndp->optyp = OPEMPTY;
4349 argndp->folded = TRUE;
4350 }
4351 }
4352 else
4353 {
4354 /* case 2: actual expr */
4355 /* case 2a: PLI system function - xmr arguments legal for any arg */
4356 if (is_sysfunc)
4357 {
4358 struct sy_t *syp;
4359 struct sysfunc_t *sfbp;
4360
4361 syp = fcall_ndp->lu.sy;
4362 sfbp = syp->el.esyftbp;
4363
4364 /* XMR's (scope args) legal for built-in system functions */
4365 /* but can never be function scope since functions always called */
4366 if (sfbp->syfnum >= BASE_VERIUSERTFS)
4367 {
4368 if (sfbp->syfnum > __last_systf) __misc_terr(__FILE__, __LINE__);
4369
4370 /* PLI user defined system function - must allow */
4371 __allow_scope_var = TRUE;
4372 }
4373 /* turning on allow scope global - turns on conversion in here */
4374 if ((argndp = parse_qcexpr()) == NULL)
4375 {
4376 __allow_scope_var = FALSE;
4377 return(NULL);
4378 }
4379 /* must turn off allowing scope for both paths thru ifs */
4380 __allow_scope_var = FALSE;
4381 }
4382 else
4383 {
4384 /* case 2b: use defined (non sysf or PLI sysf) function */
4385 /* SJM 07/26/99 - was return FALSE but same NULL */
4386 if ((argndp = parse_qcexpr()) == NULL) return(NULL);
4387
4388 /* DBG remove ---
4389 if (__debug_flg)
4390 __dbg_msg("ARG FCALL: %s\n", __msgexpr_tostr(__xs, argndp));
4391 --- */
4392 }
4393 }
4394
4395 ndp = __exprtab[__xndi];
4396 if (ndp->optyp != RPAR && ndp->optyp != COMMA)
4397 {
4398 if (__pv_err_cnt <= __saverr_cnt)
4399 __pv_ferr(1122,
4400 "function call argument , or ) separator expected - %s read",
4401 __to_opname(ndp->optyp));
4402 return(NULL);
4403 }
4404 lop = __alloc_newxnd();
4405 lop->optyp = FCCOM;
4406 lop->ru.x = NULL;
4407 lop->lu.x = argndp;
4408 last_ndp->ru.x = lop;
4409 last_ndp = lop;
4410 __xndi++;
4411 if (ndp->optyp == RPAR) break;
4412 }
4413 /* DBG remove ---
4414 if (__debug_flg)
4415 __dbg_msg("FCALL: %s\n", __msgexpr_tostr(__xs, fchdrx));
4416 --- */
4417 return(fchdrx);
4418 }
4419
4420 /*
4421 * check and declare a non xmr function call expression
4422 *
4423 * know ID and following '(' read - must find or maybe add func symbol
4424 * xidp ok here since only declaring no movement in symbol table
4425 */
chk_decl_func(int32 * is_sysfunc,struct expr_t * idndp,struct expridtab_t * xidp)4426 static int32 chk_decl_func(int32 *is_sysfunc, struct expr_t *idndp,
4427 struct expridtab_t *xidp)
4428 {
4429 struct sy_t *syp;
4430 char s1[RECLEN];
4431
4432 *is_sysfunc = FALSE;
4433 /* if starts with '$' must be system function */
4434 if (xidp->idnam[0] == '$')
4435 {
4436 if ((syp = find_systf_sym(xidp)) == NULL) return(FALSE);
4437 idndp->lu.sy = syp;
4438 *is_sysfunc = TRUE;
4439 return(TRUE);
4440 }
4441 /* SJM 02/01/05 - change to use tf undef work symtab - for uprel 1 cmp glb */
4442 /* look up to see if previously declared as function or used as func */
4443 if ((syp = __get_sym(xidp->idnam, __venviron[0])) == NULL)
4444 {
4445 /* for interactive must already be declared or error */
4446 if (__iact_state)
4447 {
4448 /* interactive statement - all variables must be declared */
4449 /* for $dumpvars will avoid this code and jump to assume glb */
4450 __pv_err_cnt++;
4451 __ia_err(1436, "function %s not declared", xidp->idnam);
4452 return(FALSE);
4453 }
4454 /* SJM 02/01/05 - must assume 1 comp XMR - if declared later will be */
4455 /* changed back in resolv local path routine */
4456 cnvt_forw_tfcall_1cmpglb(idndp, xidp->idnam, xidp->idfnam_ind,
4457 xidp->idlin_cnt);
4458 return(TRUE);
4459 }
4460 /* if already in symbol table as wire error - used as wire */
4461 idndp->lu.sy = syp;
4462
4463 /* if declared (or just seen) but not as fcall error */
4464 if (syp->sytyp != SYM_F)
4465 {
4466 if (syp->sydecl)
4467 {
4468 __pv_ferr(1123,
4469 "%s called as function but symbol declared with type %s",
4470 __to_idnam(idndp), __to_sytyp(s1, syp->sytyp));
4471 }
4472 else
4473 {
4474 __pv_ferr(1123,
4475 "%s called as function but symbol previously used with type %s",
4476 __to_idnam(idndp), __to_sytyp(s1, syp->sytyp));
4477 }
4478 /* return T since can continue parsing with wrong type symbol */
4479 }
4480 return(TRUE);
4481 }
4482
4483 /*
4484 * routine to build func call 1 comp global for forward refs
4485 *
4486 * special case because must convert top node to xmr and make left
4487 * offspring newly allocated with same contents
4488 *
4489 * needed because f([args]) may be upward relative xmr to f in above
4490 * module - can't tell so any function call use before declares must
4491 * be assumed to be XMRs - will get changed back if decl later in mod
4492 */
cnvt_forw_tfcall_1cmpglb(struct expr_t * ndp,char * tfnam,int32 fnam_ind,int32 lin_cnt)4493 static void cnvt_forw_tfcall_1cmpglb(struct expr_t *ndp, char *tfnam,
4494 int32 fnam_ind, int32 lin_cnt)
4495 {
4496 struct expr_t *cmp_ndp, sav_xnod;
4497 struct gref_t *grp;
4498
4499 /* DBG remove -- */
4500 if (ndp->optyp != ID) __misc_terr(__FILE__, __LINE__);
4501 /* -- */
4502
4503 sav_xnod = *ndp;
4504 ndp->optyp = GLBREF;
4505 ndp->ru.x = __alloc_newxnd();
4506 ndp->ru.x->optyp = XMRCOM;
4507 cmp_ndp = __alloc_newxnd();
4508 *cmp_ndp = sav_xnod;
4509 ndp->ru.x->lu.x = cmp_ndp;
4510 ndp->ru.x->ru.x = NULL;
4511
4512 cmp_ndp->ru.qnchp = __pv_stralloc(tfnam);
4513 cmp_ndp->optyp = XMRID;
4514
4515 grp = __bld_glbref(ndp, fnam_ind, lin_cnt);
4516 }
4517
4518 /*
4519 * convert event expression table to expression tree
4520 */
__bld_evxtree(void)4521 extern void __bld_evxtree(void)
4522 {
4523 struct expr_t *ndp;
4524
4525 /* add end of expression fence */
4526 ndp = __alloc_exprnd();
4527 ndp->optyp = UNDEF;
4528 __xndi = 0;
4529 if ((__root_ndp = parse_evexpr()) == NULL || __xndi != __last_xtk)
4530 {
4531 if (__pv_err_cnt <= __saverr_cnt)
4532 __pv_ferr(1124, "event expression error at token [%s]",
4533 to_xndnam(__xs, __xndi));
4534 __root_ndp = __alloc_newxnd();
4535 __set_numval(__root_ndp, 1L, 1L, 1);
4536 }
4537 /* if (__debug_flg) __dbg_msg(__msgexpr_tostr(__xs, __root_ndp)); */
4538 }
4539
4540 /*
4541 * parse a specialized event expression
4542 */
parse_evexpr(void)4543 static struct expr_t *parse_evexpr(void)
4544 {
4545 struct expr_t *ndp, *ndp2, *ndp3, *ndp4, *rhsndp, *leftopndp;
4546
4547 /* SJM 08/22/00 - need to separate of possible leading pos/neg edge */
4548 /* because they apply to entire rest of expr to end or ev or */
4549 ndp = __exprtab[__xndi];
4550 if (ndp->optyp == OPPOSEDGE || ndp->optyp == OPNEGEDGE)
4551 {
4552 ndp3 = alloc_xtnd(__xndi);
4553 __xndi++;
4554 }
4555 else ndp3 = NULL;
4556
4557 /* routine leaves __xndi at next place to look */
4558 if ((leftopndp = parse_qcexpr()) == NULL) return(NULL);
4559 if (ndp3 != NULL) { ndp3->lu.x = leftopndp; leftopndp = ndp3; }
4560
4561 ndp = __exprtab[__xndi];
4562 for (;;)
4563 {
4564 if (ndp->optyp == OPEVOR || ndp->optyp == OPEVCOMMAOR)
4565 {
4566 ndp2 = alloc_xtnd(__xndi);
4567 __xndi++;
4568
4569 /* SJM 08/22/00 - need to separate of possible leading pos/neg edge */
4570 /* because they apply to entire rest of expr to end or ev or */
4571 ndp4 = __exprtab[__xndi];
4572 if (ndp4->optyp == OPPOSEDGE || ndp4->optyp == OPNEGEDGE)
4573 {
4574 ndp3 = alloc_xtnd(__xndi);
4575 __xndi++;
4576 }
4577 else ndp3 = NULL;
4578
4579 if ((rhsndp = parse_qcexpr()) == NULL) break;
4580 if (ndp3 != NULL) { ndp3->lu.x = rhsndp; rhsndp = ndp3; }
4581
4582 /* this makes sure optyp right */
4583 ndp2->lu.x = leftopndp;
4584 ndp2->ru.x = rhsndp;
4585 leftopndp = ndp2;
4586 ndp = __exprtab[__xndi];
4587 }
4588 else break;
4589 }
4590 return(leftopndp);
4591 }
4592
4593 /*
4594 * LOW LEVEL EXPRESSION NODE ROUTINES
4595 */
4596
4597 /*
4598 * convert a symbol into a expression
4599 *
4600 * easy because all the normal work of parse term for ID is
4601 * declaring symbol
4602 */
__gen_wireid_expr(struct sy_t * syp)4603 extern struct expr_t *__gen_wireid_expr(struct sy_t *syp)
4604 {
4605 struct expr_t *ndp;
4606
4607 ndp = __alloc_newxnd();
4608 ndp->lu.sy = syp;
4609 ndp->optyp = ID;
4610 return(ndp);
4611 }
4612
4613 /*
4614 * allocate an expression node in fixed current expr. array
4615 *
4616 * this sets node type to be operator
4617 * if used as number must have a/b val allocated
4618 * when allocated for expr. allocated a/b values used
4619 */
__alloc_exprnd(void)4620 extern struct expr_t *__alloc_exprnd(void)
4621 {
4622 struct expr_t *ndp;
4623
4624 /* SJM 11/22/01 - can't use fixed operator precedence xpr tab */
4625 /* need malloced for very large bus concatenates */
4626 if (++__last_xtk >= __exprtabsiz - 1) grow_exprtab();
4627 if ((ndp = __exprtab[__last_xtk]) == NULL)
4628 {
4629 ndp = my_xndalloc();
4630 __exprtab[__last_xtk] = ndp;
4631 }
4632 __init_xnd(ndp);
4633 return(ndp);
4634 }
4635
4636 /*
4637 *
4638 * grow exprtab used during operator precedence expr tab * parsing
4639 *
4640 * can realloc because contains ptr's to malloced expr nodes where
4641 * node but not table is linked together to form run time expr
4642 *
4643 * but notice expr id table must increased to same size to avoid
4644 * overflow check
4645 *
4646 * SJM 10/22/01
4647 */
grow_exprtab(void)4648 static void grow_exprtab(void)
4649 {
4650 register int32 i;
4651 int32 old_xtabsiz, osize, nsize;
4652
4653 old_xtabsiz = __exprtabsiz;
4654 osize = old_xtabsiz*sizeof(struct expr_t *);
4655 __exprtabsiz = (3*__exprtabsiz)/2;
4656 nsize = __exprtabsiz*sizeof(struct expr_t *);
4657 __exprtab = (struct expr_t **) __my_realloc((char *) __exprtab,
4658 osize, nsize);
4659 for (i = old_xtabsiz - 1; i < __exprtabsiz; i++) __exprtab[i] = NULL;
4660
4661 /* also must grow expr id table */
4662 osize = old_xtabsiz*sizeof(struct expridtab_t *);
4663 nsize = __exprtabsiz*sizeof(struct expridtab_t *);
4664 __expr_idtab = (struct expridtab_t **)
4665 __my_realloc((char *) __expr_idtab, osize, nsize);
4666 for (i = old_xtabsiz - 1; i < __exprtabsiz; i++) __expr_idtab[i] = NULL;
4667 }
4668
4669 /*
4670 * allocate a expr ID table entry
4671 */
__alloc_expridnd(char * idnam)4672 extern struct expridtab_t *__alloc_expridnd(char *idnam)
4673 {
4674 int32 slen;
4675 struct expridtab_t *xidp;
4676
4677 if ((xidp = __expr_idtab[__last_xtk]) == NULL)
4678 {
4679 xidp = (struct expridtab_t *) __my_malloc(sizeof(struct expridtab_t));
4680 __expr_idtab[__last_xtk] = xidp;
4681 xidp->idnam = NULL;
4682 xidp->idfldwid = 0;
4683 }
4684 slen = strlen(idnam);
4685 if (slen + 1 > xidp->idfldwid)
4686 {
4687 /* guess 2x so prevent increase by one byte allocs */
4688 xidp->idnam = __my_malloc(2*slen + 1);
4689 xidp->idfldwid = 2*slen + 1;
4690 }
4691 strcpy(xidp->idnam, idnam);
4692 xidp->idlin_cnt = __lin_cnt;
4693 xidp->idfnam_ind = __cur_fnam_ind;
4694 return(xidp);
4695 }
4696
4697 /*
4698 * allocate an expr node
4699 */
my_xndalloc(void)4700 static struct expr_t *my_xndalloc(void)
4701 {
4702 struct expr_t *ndp;
4703
4704 ndp = (struct expr_t *) __my_malloc(sizeof(struct expr_t));
4705 ndp->optyp = UNDEF;
4706 if (__inst_mod != NULL) (__inst_mod->mexprnum)++;
4707 return(ndp);
4708 }
4709
4710 /*
4711 * allocate a copy of __exprtab node in malloced storage
4712 * this uses the allocated values in the __exprtab node
4713 *
4714 * numeric values never changed because __exprtab node just points to
4715 * atokptr and btokptr and those values moved to malloced node
4716 */
alloc_xtnd(int32 ndi)4717 static struct expr_t *alloc_xtnd(int32 ndi)
4718 {
4719 struct expr_t *ndp, *ndp2;
4720
4721 /* xtnd out of range */
4722 if (ndi < 0 || ndi > __last_xtk) __misc_terr(__FILE__, __LINE__);
4723 ndp = my_xndalloc();
4724 ndp2 = __exprtab[ndi];
4725 *ndp = *ndp2;
4726 return(ndp);
4727 }
4728
4729 /*
4730 * initialize a new node - assume expression node for now
4731 */
__init_xnd(struct expr_t * ndp)4732 extern void __init_xnd(struct expr_t *ndp)
4733 {
4734 ndp->optyp = UNDEF;
4735 ndp->has_sign = FALSE;
4736 ndp->rel_ndssign = FALSE;
4737 ndp->is_string = FALSE;
4738 /* unless simple decimal, must be sized */
4739 ndp->unsiznum = FALSE;
4740 ndp->ibase = BHEX;
4741 ndp->sizdflt = FALSE;
4742 ndp->is_real = FALSE;
4743 ndp->cnvt_to_real = FALSE;
4744 ndp->unsgn_widen = FALSE;
4745 ndp->consubxpr = FALSE;
4746 ndp->consub_is = FALSE;
4747 ndp->folded = FALSE;
4748 ndp->getpatlhs = FALSE;
4749 ndp->ind_noth0 = FALSE; /* assume h:0 form */
4750 ndp->x_multfi = FALSE;
4751 ndp->tf_isrw = FALSE;
4752 ndp->x_islhs = FALSE;
4753 ndp->locqualnam = FALSE;
4754 ndp->lhsx_ndel = FALSE;
4755 ndp->x_stren = FALSE;
4756 ndp->unc_pull = NO_UNCPULL;
4757 ndp->szu.xclen = 0;
4758 ndp->lu.x = ndp->ru.x = NULL;
4759 }
4760
4761 /*
4762 * allocate and initialize new expression node (may be table)
4763 * this initializes a node so if copied to number will have value alloced
4764 */
__alloc_newxnd(void)4765 extern struct expr_t *__alloc_newxnd(void)
4766 {
4767 struct expr_t *ndp;
4768
4769 ndp = my_xndalloc();
4770 __init_xnd(ndp);
4771 return(ndp);
4772 }
4773
4774 /*
4775 * run time (during sim or xform) allocate new xnode
4776 * does not get copied to mod's expr table
4777 */
__sim_alloc_newxnd(void)4778 extern struct expr_t *__sim_alloc_newxnd(void)
4779 {
4780 struct expr_t *ndp;
4781
4782 ndp = (struct expr_t *) __my_malloc(sizeof(struct expr_t));
4783 ndp->optyp = UNDEF;
4784 __init_xnd(ndp);
4785 return(ndp);
4786 }
4787
4788 /*
4789 * set an collection routine exprtab entry to x
4790 * this must be called for empty expr. tab - all fields reclaimed
4791 */
__set_xtab_errval(void)4792 extern void __set_xtab_errval(void)
4793 {
4794 __last_xtk = 0;
4795 __init_xnd(__exprtab[0]);
4796 __set_numval(__exprtab[0], 1L, 1L, 1);
4797 }
4798
4799 /*
4800 * set an collection routine exprtab entry to 0 - for specify
4801 * this must be called for empty expr. tab - all fields reclaimed
4802 */
__set_0tab_errval(void)4803 extern void __set_0tab_errval(void)
4804 {
4805 __last_xtk = 0;
4806 __set_numval(__exprtab[0], 0L, 0L, 1);
4807 }
4808
4809 /*
4810 * free an expression tree
4811 * notice cannot free symbols or wires pointed to by these nodes
4812 * ndp now points to garbage - caller must unlink
4813 */
__free_xtree(struct expr_t * ndp)4814 extern void __free_xtree(struct expr_t *ndp)
4815 {
4816 if (ndp == NULL) return;
4817 /* first free underneath */
4818 __free2_xtree(ndp);
4819 /* then node itself */
4820 __my_free((char *) ndp, sizeof(struct expr_t));
4821 }
4822
4823 /*
4824 * free all nodes under expression node and free number if needed
4825 * notice cannot free symbols or wires pointed to by these nodes
4826 * expects __inst_mod to be set if form is IS
4827 * caller to reuse ndp must change fields
4828 *
4829 * notice freeing here assumes that all nodes have both a and b parts
4830 */
__free2_xtree(struct expr_t * ndp)4831 extern void __free2_xtree(struct expr_t *ndp)
4832 {
4833 switch ((byte) ndp->optyp) {
4834 case NUMBER: case REALNUM: case OPEMPTY:
4835 ndp->ru.xvi = -1;
4836 return;
4837 case ISNUMBER: case ISREALNUM:
4838 /* LOOKATME - unable to free IS constant value parts - is this leak? */
4839 ndp->ru.xvi = -1;
4840 return;
4841 case ID:
4842 ndp->lu.sy = NULL;
4843 return;
4844 case GLBREF:
4845 ndp->lu.sy = NULL;
4846 /* globals free elsewhere - through glogal list */
4847 ndp->ru.grp = NULL;
4848 return;
4849 case XMRID:
4850 __my_free(ndp->ru.qnchp, strlen(ndp->ru.qnchp) + 1);
4851 /* DBG remove --- */
4852 ndp->ru.x = NULL;
4853 /* --- */
4854 return;
4855 /* fall thru for GLBPTH that has no contents - just subexprs under */
4856 }
4857 if (ndp->lu.x != NULL) __free_xtree(ndp->lu.x);
4858 if (ndp->ru.x != NULL) __free_xtree(ndp->ru.x);
4859 }
4860
4861 /*
4862 * build an unc. expression - may have width set to 1 for now - know later
4863 * before calling must free exprtab and anything pointed to __root_ndp
4864 */
__bld_unc_expr(void)4865 extern void __bld_unc_expr(void)
4866 {
4867 __root_ndp = __alloc_newxnd();
4868 set2_opempty(__root_ndp);
4869 }
4870
4871 /*
4872 * this build a 1 token empty expr that may or may not be parsed
4873 * this is for 1 bit expression
4874 *
4875 * this does not free partially built x trees - caller must free if needed
4876 */
__set_opempty(int32 ndi)4877 extern void __set_opempty(int32 ndi)
4878 {
4879 __init_xnd(__exprtab[ndi]);
4880 set2_opempty(__exprtab[ndi]);
4881 }
4882
4883 /*
4884 * version of set opempty that is passed allocated expr. value
4885 */
set2_opempty(struct expr_t * ndp)4886 static void set2_opempty(struct expr_t *ndp)
4887 {
4888 ndp->optyp = OPEMPTY;
4889 ndp->folded = TRUE;
4890 ndp->szu.xclen = 1;
4891 /* if unconnected drive active, must set in node */
4892 if (__unconn_drive != TOK_NONE)
4893 {
4894 ndp->unc_pull = (__unconn_drive == PULL0) ? UNCPULL0 : UNCPULL1;
4895 ndp->x_stren = TRUE;
4896 /* must force propogating strengths up and down */
4897 /* but maybe no wire marked as strength */
4898 __design_no_strens = FALSE;
4899 }
4900 }
4901
4902 /*
4903 * set an already allocated leaf node (no subnodes) to a numeric value
4904 * only for <= WBITS values and node must be new - know previous alloc num
4905 *
4906 * notice this must not change __root_ndp
4907 */
__set_numval(struct expr_t * ndp,word32 av,word32 bv,int32 blen)4908 extern void __set_numval(struct expr_t *ndp, word32 av, word32 bv, int32 blen)
4909 {
4910 ndp->optyp = NUMBER;
4911 if (blen <= WBITS)
4912 {
4913 ndp->ru.xvi = __alloc_shareable_cval(av, bv, blen);
4914 }
4915 else __case_terr(__FILE__, __LINE__);
4916 ndp->szu.xclen = blen;
4917 if (bv == 0) ndp->ibase = BDEC;
4918 }
4919
4920 /*
4921 * print an expression node for error messages
4922 * must be wide enough for id
4923 * this is a routine that uses wr to exprline routines so cannot be
4924 * called to add to exprline - must use disp of expr. routine
4925 *
4926 * BEWARE - can only be called during expression reading because needs
4927 * __exprtab and __expridtab
4928 */
to_xndnam(char * s,int32 xndi)4929 static char *to_xndnam(char *s, int32 xndi)
4930 {
4931 int32 wlen;
4932 word32 *ap, *bp;
4933 struct expr_t *ndp;
4934 struct expridtab_t *xidp;
4935 char s1[2*IDLEN], s2[RECLEN];
4936
4937 ndp = __exprtab[xndi];
4938 switch ((byte) ndp->optyp) {
4939 case ID:
4940 xidp = __expr_idtab[xndi];
4941 if (xidp == NULL || strcmp(xidp->idnam, "") == 0)
4942 { strcpy(s, "**range**"); return(s); }
4943 sprintf(s1, "IDENTIFIER: %s", xidp->idnam);
4944 break;
4945 /* LOOKATME - can GLBREF occur here */
4946 case NUMBER:
4947 case ISNUMBER:
4948 ap = &(__contab[ndp->ru.xvi]);
4949 wlen = wlen_(ndp->szu.xclen);
4950 bp = &ap[wlen];
4951 sprintf(s1, "NUMBER: %s", __regab_tostr(s2, ap, bp, ndp->szu.xclen,
4952 BHEX, FALSE));
4953 break;
4954 case REALNUM: case ISREALNUM:
4955 /* LOOKATME - better to just format as double */
4956 /* just pass a part for both here */
4957 ap = &(__contab[ndp->ru.xvi]);
4958 sprintf(s1, "REAL: %s", __regab_tostr(s2, ap, ap, ndp->szu.xclen, BDBLE,
4959 FALSE));
4960 break;
4961 case OPEMPTY:
4962 strcpy(s, "<EMPTY>");
4963 return(s);
4964 case UNDEF:
4965 strcpy(s, "<EXPR END>");
4966 return(s);
4967 default:
4968 strcpy(s, __to_opname(ndp->optyp)); return(s);
4969 }
4970 if ((int32) strlen(s1) >= RECLEN - 1) s1[RECLEN - 1] = '\0';
4971 strcpy(s, s1);
4972 return(s);
4973 }
4974