03d7ea9762b6ac4df26c18635958247a8ab65847
[tas-yagle.git] / distrib / sources / mbkspef / spef.y
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : SPEF Version 1.00 */
6 /* Fichier : spef.yac */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Olivier Bichaut */
12 /* */
13 /****************************************************************************/
14
15 %{
16 #include SPE_H
17 #include AVT_H
18 #include MUT_H
19 #include MLO_H
20 #include MLU_H
21 #include "spef_actions.h"
22 #include "spef_annot.h"
23 #include "spef_util.h"
24 #include "spef_drive.h"
25
26 /*****************************************************************************
27 * private *
28 *****************************************************************************/
29
30 /*****************************************************************************
31 * function declarations *
32 *****************************************************************************/
33 /*ptsignode = (signode_ctc*)mbkalloc (sizeof (struct signode_ctc));*/
34
35 static int ignore=0;
36 int yyerror();
37 int yylex();
38 char *vss = NULL;
39 it *namemaptable = NULL;
40 ht *portmap_ht = NULL;
41 chain_list *ctclist = NULL;
42 spef_info *SPEF_INFO;
43 // static void clean_SPEF_INFO();
44 static int SPEF_ERROR;
45 %}
46
47 %union
48 {
49 char *text ;
50 struct
51 {
52 double real ;
53 char text[1024];
54 } UR;
55 struct
56 {
57 long longint;
58 char text[1024];
59 } UL;
60
61 struct chain *ch_l ;
62 char char_t;
63 } ;
64
65 /* general */
66 %token _E_SPEF
67 %token _E_DESIGN
68 %token _E_DATE
69 %token _E_VENDOR
70 %token _E_PROGRAM
71 %token _E_VERSION
72 %token _E_DESIGN_FLOW
73 %token _E_DIVIDER
74 %token _E_DELIMITER
75 %token _E_BUS_DELIMITER
76 %token _E_T_UNIT
77 %token _NS
78 %token _PS
79 %token _E_C_UNIT
80 %token _PF
81 %token _FF
82 %token _E_R_UNIT
83 %token _OHM
84 %token _KOHM
85 %token _E_L_UNIT
86 %token _HENRY
87 %token _MH
88 %token _UH
89 %token _E_NAME_MAP
90 %token _E_PORTS
91 %token _SPEF_I
92 %token _SPEF_B
93 %token _SPEF_O
94 %token _SPEF_X
95 %token _E_C _E_GROUND_NETS _E_POWER_NETS _E_PHYSICAL_PORTS
96 %token _E_L _E_DEFINE _E_PDEFINE _E_RNET _E_RPNET _E_DPNET
97 %token _E_S _E_INDUC _E_DRIVER _E_CELL _E_C2_R1_C1 _E_LOADS
98 %token _E_D _E_RC _E_Q _E_K _E_N
99 %token _E_V
100 %token _E_D_NET
101 %token _E_CONN
102 %token _E_P
103 %token _E_I _E_X
104 %token _E_CAP
105 %token _E_RES
106 %token _E_END
107 %token <UR> _NUMBER
108 %token <text> _INDEX
109 %token <UL> _POS_INTEGER
110 %token <UR> _POS_NUMBER
111 %token <text> _IDENTIFIER
112 %token <text> _QSTRING
113 %start spef_file
114
115 %type <text> net_ref
116 %type <UR.real> par_value
117 %type <UR.real> total_cap
118 %type <UL> .extention_node.
119 %type <text> node_name a_name reduced_node_name
120 %type <char_t> _PREFIX_BUS_DELIM _SUFFIX_BUS_DELIM _HCHAR
121
122 %%
123
124
125 spef_file :{SPEF_INFO = (spef_info*)mbkalloc(sizeof (struct spef_info)); spef_initinfo(SPEF_INFO);}
126 header_def name_map power_def external_def define_def internal_def
127 {
128 if(SPEF_PRELOAD == 'N'){
129 spef_remove_htctc();
130 if(portmap_ht)
131 delht(portmap_ht);
132 if(namemaptable)
133 delit(namemaptable);
134 spef_treatafterctclist(&ctclist);
135 }
136 spef_setneg2posnode(Lofig);
137 };
138
139 header_def : spef_version { SPEF_ERROR=0; } design_name date vendor program_name
140 program_version design_flow hierarchy_div_def
141 pin_delim_def bus_delim_def unit_def
142 {
143 char *str ;
144 if(V_BOOL_TAB[__MBK_FLATTEN_FOR_PARA].VALUE){
145 char separavant = SEPAR;
146 char oldkeepstate;
147
148 SEPAR = SPEF_INFO->DIVIDER;
149 oldkeepstate=FLATTEN_KEEP_ALL_NAMES;
150 FLATTEN_KEEP_ALL_NAMES=1;
151
152 rflattenlofig(Lofig, YES, YES);
153
154 FLATTEN_KEEP_ALL_NAMES=oldkeepstate;
155 SEPAR = separavant;
156 }
157 if( MBKFOPEN_FILTER==NO )
158 rcn_enable_cache( Lofig, spef_cache_parse, spef_cache_free, pool );
159 else {
160 if( RCN_CACHE_SIZE > 0 ) {
161 avt_errmsg(SPE_ERRMSG, "001", AVT_WARNING);
162 }
163 }
164 if( rcn_getlofigcache( Lofig ) ){
165 SPEF_PRELOAD = 'Y';
166 SPEF_LOFIG_CACHE = 1;
167 }
168
169 spef_destroyexistingRC(Lofig);
170 spef_create_losig_htable(Lofig);
171 spef_create_loins_htable(Lofig);
172 };
173
174 spef_version : _E_SPEF _QSTRING
175 {
176 SPEF_INFO->SPEF = namealloc($2);
177 mbkfree($2);
178 };
179
180 design_name : _E_DESIGN _QSTRING
181 {
182 char *name = spef_deqstring($2);
183 if(Lofig==NULL || strcmp(name, Lofig->NAME)!=0){
184 if ((Lofig = getloadedlofig(name))==NULL)
185 {
186 avt_errmsg(SPE_ERRMSG, "002", AVT_ERROR, name, spef_ParsedFile);
187 SPEF_ERROR=1;
188 YYACCEPT;
189 }
190 }
191 if (!spef_quiet) fprintf(stdout, "LOADING FILE %s.spef\n", name);
192 mbkfree($2);
193 } ;
194
195 date : _E_DATE _QSTRING { mbkfree($2); } ;
196
197 vendor : _E_VENDOR _QSTRING { SPEF_INFO->VENDOR = namealloc($2); mbkfree($2); } ;
198
199 program_name : _E_PROGRAM _QSTRING { SPEF_INFO->PROGRAM = namealloc($2); mbkfree($2); } ;
200
201 program_version : _E_VERSION _QSTRING { SPEF_INFO->VERSION = namealloc($2); mbkfree($2); } ;
202
203 design_flow : _E_DESIGN_FLOW _QSTRING qstring_list
204 {
205 SPEF_INFO->DESIGN_FLOW = addchain(SPEF_INFO->DESIGN_FLOW, mbkstrdup($2));
206 mbkfree($2);
207 } ;
208
209 qstring_list : empty { }
210 | qstring_list _QSTRING
211 {
212 SPEF_INFO->DESIGN_FLOW = addchain(SPEF_INFO->DESIGN_FLOW, mbkstrdup($2));
213 mbkfree($2);
214 } ;
215
216 _HCHAR: '.' { $$='.'; }
217 | '/' { $$='/'; }
218 | ':' { $$=':'; }
219 | '|' { $$='|'; }
220 ;
221
222 hierarchy_div_def : _E_DIVIDER _HCHAR { SPEF_INFO->DIVIDER = $2; } ;
223
224 pin_delim_def : _E_DELIMITER _HCHAR { SPEF_INFO->DELIMITER = $2; } ;
225
226 _PREFIX_BUS_DELIM: '[' {$$='[';}
227 | '{' {$$='{';}
228 | '(' {$$='(';}
229 | '<' {$$='<';}
230 ;
231
232 _SUFFIX_BUS_DELIM: ']' {$$=']';}
233 | '}' {$$='}';}
234 | ')' {$$=')';}
235 | '>' {$$='>';}
236 ;
237
238
239 bus_delim_def : _E_BUS_DELIMITER _PREFIX_BUS_DELIM
240 { SPEF_INFO->PREFIX_BUS_DELIMITER = $2;
241 SPEF_INFO->SUFFIX_BUS_DELIMITER = spef_sufdelim($2);
242 }
243 | _E_BUS_DELIMITER _PREFIX_BUS_DELIM _SUFFIX_BUS_DELIM
244 { SPEF_INFO->PREFIX_BUS_DELIMITER = $2;
245 SPEF_INFO->SUFFIX_BUS_DELIMITER = $3;
246 } ;
247
248 unit_def : time_scale cap_scale res_scale induc_scale { } ;
249
250 time_scale : _E_T_UNIT _POS_NUMBER time_unit { SPEF_INFO->SPEF_T_SCALE = $2.real; }
251 | _E_T_UNIT _POS_INTEGER time_unit { SPEF_INFO->SPEF_T_SCALE = $2.longint; } ;
252
253
254 time_unit : _NS { SPEF_INFO->SPEF_T_UNIT = 'N'; }
255 | _PS { SPEF_INFO->SPEF_T_UNIT = 'P'; } ;
256
257 cap_scale : _E_C_UNIT _POS_NUMBER cap_unit
258 { SPEF_INFO->SPEF_CAP_SCALE = $2.real;
259 if(SPEF_INFO->SPEF_CAP_UNIT == 'F')
260 SPEF_INFO->SPEF_CAP_SCALE /= 1000.0;
261 }
262 | _E_C_UNIT _POS_INTEGER cap_unit
263 { SPEF_INFO->SPEF_CAP_SCALE = $2.longint;
264 if(SPEF_INFO->SPEF_CAP_UNIT == 'F')
265 SPEF_INFO->SPEF_CAP_SCALE /= 1000.0;
266 } ;
267
268 cap_unit : _PF { SPEF_INFO->SPEF_CAP_UNIT = 'P'; }
269 | _FF { SPEF_INFO->SPEF_CAP_UNIT = 'F'; } ;
270
271 res_scale : _E_R_UNIT _POS_NUMBER res_unit
272 { SPEF_INFO->SPEF_RES_SCALE = $2.real;
273 if(SPEF_INFO->SPEF_RES_UNIT == 'K')
274 SPEF_INFO->SPEF_RES_SCALE *= 1000.0;
275 }
276 | _E_R_UNIT _POS_INTEGER res_unit
277 { SPEF_INFO->SPEF_RES_SCALE = $2.longint;
278 if(SPEF_INFO->SPEF_RES_UNIT == 'K')
279 SPEF_INFO->SPEF_RES_SCALE *= 1000.0;
280 } ;
281
282 res_unit : _OHM { SPEF_INFO->SPEF_RES_UNIT = 'O'; }
283 | _KOHM { SPEF_INFO->SPEF_RES_UNIT = 'K';} ;
284
285 induc_scale : _E_L_UNIT _POS_NUMBER induc_unit { SPEF_INFO->SPEF_L_SCALE = $2.real; }
286 | _E_L_UNIT _POS_INTEGER induc_unit { SPEF_INFO->SPEF_L_SCALE = $2.longint; } ;
287
288 induc_unit : _HENRY { SPEF_INFO->SPEF_L_UNIT = 'H'; }
289 | _MH { SPEF_INFO->SPEF_L_UNIT = 'M'; }
290 | _UH { SPEF_INFO->SPEF_L_UNIT = 'U'; } ;
291
292 name_map : empty { }
293 | _E_NAME_MAP {namemaptable = addit(100); } name_map_entry name_map_entry_list { } ;
294
295 name_map_entry : _INDEX a_name
296 {
297 int index = atoi($1 + 1);
298 char *name = spef_rename($2);
299 setititem(namemaptable, index, (long)name);
300 mbkfree($1);
301 mbkfree($2);
302 } ;
303
304 name_map_entry_list : empty { }
305 | name_map_entry_list name_map_entry { } ;
306
307 power_def : empty { }
308 | power_net_def
309 | power_net_def ground_net_def
310 | ground_net_def
311 ;
312
313 power_net_def : _E_POWER_NETS net_name_list ;
314 ground_net_def : _E_GROUND_NETS net_name_list ;
315
316 net_name_list: net_name
317 | net_name_list net_name
318 ;
319
320 net_name : net_ref {mbkfree($1);}
321 ;
322
323
324 external_def : empty
325 {
326 locon_list *ptcon;
327 portmap_ht = addht(100);
328 for(ptcon=Lofig->LOCON; ptcon; ptcon=ptcon->NEXT)
329 addhtitem(portmap_ht, ptcon->NAME, (long)ptcon->NAME);
330 if(!vss){
331 vss = namealloc("VSS");
332 spef_SetGroundSignal(vss);
333 }
334 }
335 | port_def
336 {
337 if(!vss){
338 vss = namealloc("VSS");
339 spef_SetGroundSignal(vss);
340 }
341 } ;
342
343 port_def : _E_PORTS {portmap_ht = addht(100);} port_entry port_entry_list
344 {
345 } ;
346
347 port_entry : port_name direction conn_attr_list { } ;
348
349 port_entry_list : empty { }
350 | port_entry_list port_entry { } ;
351
352 port_name : _INDEX
353 {
354 if(isvss($1)){
355 if(!vss){
356 vss = namealloc($1);
357 spef_SetGroundSignal($1);
358 }
359 }
360 else
361 addhtitem(portmap_ht, spef_spi_devect($1), (long)spef_spi_devect($1));
362 mbkfree($1);
363 }
364 | _IDENTIFIER
365 {
366 if(isvss($1)){
367 if(!vss){
368 vss = namealloc($1);
369 spef_SetGroundSignal($1);
370 }
371 }
372 else
373 addhtitem(portmap_ht, spef_spi_devect($1), (long)spef_spi_devect($1));
374 mbkfree($1);
375 } ;
376
377 direction : _SPEF_I { }
378 | _SPEF_B { }
379 | _SPEF_O { }
380 | _SPEF_X { } ;
381
382 conn_attr_list : empty { }
383 | conn_attr_list conn_attr { } ;
384
385 conn_attr : coordinates { }
386 | cap_load { }
387 | slews { }
388 | driving_cell { } ;
389
390 coordinates : _E_C number number { } ;
391
392 number : _NUMBER { }
393 | _POS_NUMBER { }
394 | _POS_INTEGER { } ;
395
396 cap_load : _E_L par_value { } ;
397
398 par_value : _POS_NUMBER { $$ = $1.real; }
399 | _POS_NUMBER ':' _POS_NUMBER ':' _POS_NUMBER { $$ = $3.real; }
400 | _POS_INTEGER { $$ = $1.longint; }
401 | _POS_INTEGER ':' _POS_INTEGER ':' _POS_INTEGER { $$ = $3.longint; } ;
402
403 slews : _E_S par_value par_value .thresholds. { } ;
404
405 .thresholds. : threshold threshold
406 |
407 ;
408
409 threshold: _POS_NUMBER {}
410 | _POS_NUMBER ':' _POS_NUMBER ':' _POS_NUMBER {}
411 ;
412
413
414 driving_cell : _E_D a_name
415 {
416 mbkfree($2);
417 }
418 | _E_D _INDEX {mbkfree($2);}
419 ;
420
421 define_def : empty { } ;
422
423 internal_def : nets nets_list { } ;
424
425 nets_list : empty { }
426 | nets_list nets { } ;
427
428 nets : d_net { }
429 | r_net
430 | d_pnet
431 | r_pnet
432 ;
433
434 d_net : _E_D_NET net_ref total_cap
435 {
436 char *name;
437 losig_list *ls;
438 if($2[0] == '*'){
439 name = (char*)getititem(namemaptable, atoi($2 + 1));
440 ls =spef_NewNet(name, $3 * SPEF_INFO->SPEF_CAP_SCALE);
441 }else{
442 name = spef_spi_devect($2);
443 ls=spef_NewNet(name, $3 * SPEF_INFO->SPEF_CAP_SCALE);
444 }
445 spef_setcurnet($2, ls);
446 }
447 .routing_conf. .conn_sec. .cap_sec. .res_sec. .induc_sec. _E_END
448 {
449 losig_list *ptsig;
450 if ((ptsig = spef_getcurnet())!=NULL)
451 rcn_calccapa(ptsig);
452 spef_setcurnet("", NULL);
453 mbkfree($2);
454 } ;
455 d_pnet : _E_DPNET {ignore=1;} net_ref total_cap
456 .routing_conf. .conn_sec. .cap_sec. .res_sec. .induc_sec. {ignore=0; mbkfree($3); } _E_END
457 ;
458
459 net_ref : _INDEX { $$ = $1; }
460 | a_name { $$ = $1; } ;
461
462
463 total_cap : par_value { $$ = $1; } ;
464
465 .routing_conf. : empty { }
466 | _E_V _POS_INTEGER { } ;
467
468 .conn_sec. : _E_CONN conn_def conn_def_list .internal_node_coord_list. { }
469 |
470 ;
471
472 conn_def_list : empty { }
473 | conn_def_list conn_def { } ;
474
475 .internal_node_coord_list.:
476 .internal_node_coord_list. internal_node_coord
477 |
478 ;
479
480 internal_node_coord : _E_N node_name coordinates {mbkfree($2);}
481 ;
482
483 .extention_node.: _E_X _POS_INTEGER
484 {
485 $$.longint=$2.longint;
486 }
487 |
488 {
489 $$.longint=-1;
490 }
491 ;
492
493 conn_def : _E_P a_name direction conn_attr_list .extention_node.
494 {
495 char *name;
496 name = namealloc($2);
497 if (!ignore) spef_AddConnector(name, $5.longint);
498 mbkfree($2);
499 }
500 | _E_P _INDEX direction conn_attr_list .extention_node.
501 {
502 char *name;
503 name = namealloc($2);
504 if (!ignore) spef_AddConnector(name, $5.longint);
505 mbkfree($2);
506 }
507 | _E_I a_name direction conn_attr_list .extention_node.
508 {
509 char *instpinname, *pinname, *name;
510 if (!ignore) {
511 instpinname = mbkstrdup($2);
512 pinname = strrchr(instpinname, SPEF_INFO->DELIMITER);
513 if (pinname!=NULL)
514 {
515 *pinname = '\0';
516 pinname++;
517 }
518 else
519 {
520 pinname="<delimiter not found>";
521 avt_errmsg(SPE_ERRMSG, "015", AVT_FATAL, spef_ParsedFile, Line, SPEF_INFO->DELIMITER, instpinname);
522 }
523
524 if(instpinname[0] == '*')
525 name = (char*)getititem(namemaptable, atoi(instpinname + 1));
526 else
527 name = instpinname;
528
529 spef_AddInstanceConnector($2,name,pinname,$5.longint);
530 mbkfree(instpinname);
531 }
532 mbkfree($2);
533 }
534 ;
535
536 .cap_sec. : _E_CAP cap_elm cap_elm_list { }
537 |
538 ;
539
540 cap_elm_list : empty { }
541 | cap_elm_list cap_elm { } ;
542
543 cap_elm : _POS_INTEGER reduced_node_name par_value
544 {
545 if (!ignore) ctclist = spef_AddCapacitance(ctclist, $2,vss,$3 * SPEF_INFO->SPEF_CAP_SCALE);
546 mbkfree($2);
547 }
548 | _POS_INTEGER reduced_node_name reduced_node_name par_value
549 {
550 if (!ignore) ctclist = spef_AddCapacitance(ctclist, $2,$3,$4 * SPEF_INFO->SPEF_CAP_SCALE);
551 mbkfree($2);
552 mbkfree($3);
553 } ;
554
555 a_name : _IDENTIFIER
556 {
557 $$ = $1;
558 }
559 | _POS_INTEGER
560 {
561 $$ = mbkstrdup($1.text);
562 }
563 ;
564 node_name : a_name
565 {
566 $$ = $1;
567 }
568 | _INDEX
569 {
570 $$ = $1;
571 }
572 ;
573
574 reduced_node_name : _IDENTIFIER
575 {
576 $$ = $1;
577 }
578 | _INDEX
579 {
580 $$ = $1;
581 }
582 ;
583
584 .res_sec. : _E_RES res_elm res_elm_list { }
585 |
586 ;
587
588 res_elm_list : empty { }
589 | res_elm_list res_elm { } ;
590
591 res_elm : _POS_INTEGER node_name node_name par_value
592 {
593 if (!ignore) spef_AddResistor($2,$3,$4 * SPEF_INFO->SPEF_RES_SCALE);
594 mbkfree($2);
595 mbkfree($3);
596 } ;
597
598 .induc_sec. : _E_INDUC induc_elm induc_elm_list { }
599 | empty { } ;
600
601 induc_elm_list : empty { }
602 | induc_elm_list induc_elm { } ;
603
604 induc_elm : _POS_INTEGER node_name node_name par_value { mbkfree($2); mbkfree($3);} ;
605
606
607 empty : { } ;
608
609 r_net : _E_RNET net_ref total_cap
610 .routing_conf. .driver_reduc_list. _E_END {mbkfree($2);}
611 ;
612
613 r_pnet : _E_RPNET net_ref total_cap
614 .routing_conf. .driver_reduc_list. _E_END {mbkfree($2);}
615 ;
616
617 .driver_reduc_list. :
618 .driver_reduc_list. driver_reduc
619 |
620 ;
621
622 driver_reduc: _E_DRIVER a_name _E_CELL node_name _E_C2_R1_C1 par_value par_value par_value _E_LOADS rc_desc_list
623 {mbkfree($2); mbkfree($4);};
624
625 rc_desc_list : rc_desc
626 | rc_desc_list rc_desc
627 ;
628
629 rc_desc: _E_RC a_name par_value .pole_residue_desc. {mbkfree($2);};
630
631 .pole_residue_desc.: pole_desc residue_desc
632 |
633 ;
634
635 pole_desc: _E_Q _POS_INTEGER pole_list ;
636 residue_desc: _E_K _POS_INTEGER residue_list ;
637
638 pole_list: pole
639 | pole_list pole;
640
641 residue_list: residue
642 | residue_list residue
643 ;
644
645 pole: complex_par_value ;
646 residue: complex_par_value ;
647
648 complex_par_value: cnumber
649 | number
650 | cnumber ':' cnumber ':' cnumber
651 | number ':' number ':' number
652 ;
653
654 cnumber: '(' number number ')' ;
655
656
657 %%
658
659 extern char *speftext ;
660
661 int yyerror()
662 {
663 avt_errmsg(SPE_ERRMSG, "004", AVT_FATAL, spef_ParsedFile, Line, speftext);
664 // printf("\nSPEF Parser:%s:%d: Syntax Error.\n", spef_ParsedFile, Line) ;
665 EXIT(1);
666 return 0;
667 }
668
669 void spef_parser_error(char *message)
670 {
671 avt_errmsg(SPE_ERRMSG, "003", AVT_FATAL, spef_ParsedFile, Line, message);
672 //fprintf(stderr,"\nSPEF Parser:%s:%d: %s\n", spef_ParsedFile, Line, message) ;
673 EXIT(1);
674 }
675 /*
676 static void clean_SPEF_INFO()
677 {
678 chain_list *cl;
679 for (cl=SPEF_INFO->DESIGN_FLOW; cl!=NULL; cl=cl->NEXT)
680 mbkfree(cl->DATA);
681 freechain(SPEF_INFO->DESIGN_FLOW);
682 mbkfree(SPEF_INFO);
683 }
684 */
685 int spef_error()
686 {
687 return SPEF_ERROR;
688 }