1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : SPEF Version 1.00 */
6 /* Fichier : spef.yac */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Olivier Bichaut */
13 /****************************************************************************/
21 #include "spef_actions.h"
22 #include "spef_annot.h"
23 #include "spef_util.h"
24 #include "spef_drive.h"
26 /*****************************************************************************
28 *****************************************************************************/
30 /*****************************************************************************
31 * function declarations *
32 *****************************************************************************/
33 /*ptsignode = (signode_ctc*)mbkalloc (sizeof (struct signode_ctc));*/
39 it *namemaptable = NULL;
40 ht *portmap_ht = NULL;
41 chain_list *ctclist = NULL;
43 // static void clean_SPEF_INFO();
44 static int SPEF_ERROR;
75 %token _E_BUS_DELIMITER
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
109 %token <UL> _POS_INTEGER
110 %token <UR> _POS_NUMBER
111 %token <text> _IDENTIFIER
112 %token <text> _QSTRING
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
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
128 if(SPEF_PRELOAD == 'N'){
134 spef_treatafterctclist(&ctclist);
136 spef_setneg2posnode(Lofig);
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
144 if(V_BOOL_TAB[__MBK_FLATTEN_FOR_PARA].VALUE){
145 char separavant = SEPAR;
148 SEPAR = SPEF_INFO->DIVIDER;
149 oldkeepstate=FLATTEN_KEEP_ALL_NAMES;
150 FLATTEN_KEEP_ALL_NAMES=1;
152 rflattenlofig(Lofig, YES, YES);
154 FLATTEN_KEEP_ALL_NAMES=oldkeepstate;
157 if( MBKFOPEN_FILTER==NO )
158 rcn_enable_cache( Lofig, spef_cache_parse, spef_cache_free, pool );
160 if( RCN_CACHE_SIZE > 0 ) {
161 avt_errmsg(SPE_ERRMSG, "001", AVT_WARNING);
164 if( rcn_getlofigcache( Lofig ) ){
166 SPEF_LOFIG_CACHE = 1;
169 spef_destroyexistingRC(Lofig);
170 spef_create_losig_htable(Lofig);
171 spef_create_loins_htable(Lofig);
174 spef_version : _E_SPEF _QSTRING
176 SPEF_INFO->SPEF = namealloc($2);
180 design_name : _E_DESIGN _QSTRING
182 char *name = spef_deqstring($2);
183 if(Lofig==NULL || strcmp(name, Lofig->NAME)!=0){
184 if ((Lofig = getloadedlofig(name))==NULL)
186 avt_errmsg(SPE_ERRMSG, "002", AVT_ERROR, name, spef_ParsedFile);
191 if (!spef_quiet) fprintf(stdout, "LOADING FILE %s.spef\n", name);
195 date : _E_DATE _QSTRING { mbkfree($2); } ;
197 vendor : _E_VENDOR _QSTRING { SPEF_INFO->VENDOR = namealloc($2); mbkfree($2); } ;
199 program_name : _E_PROGRAM _QSTRING { SPEF_INFO->PROGRAM = namealloc($2); mbkfree($2); } ;
201 program_version : _E_VERSION _QSTRING { SPEF_INFO->VERSION = namealloc($2); mbkfree($2); } ;
203 design_flow : _E_DESIGN_FLOW _QSTRING qstring_list
205 SPEF_INFO->DESIGN_FLOW = addchain(SPEF_INFO->DESIGN_FLOW, mbkstrdup($2));
209 qstring_list : empty { }
210 | qstring_list _QSTRING
212 SPEF_INFO->DESIGN_FLOW = addchain(SPEF_INFO->DESIGN_FLOW, mbkstrdup($2));
216 _HCHAR: '.' { $$='.'; }
222 hierarchy_div_def : _E_DIVIDER _HCHAR { SPEF_INFO->DIVIDER = $2; } ;
224 pin_delim_def : _E_DELIMITER _HCHAR { SPEF_INFO->DELIMITER = $2; } ;
226 _PREFIX_BUS_DELIM: '[' {$$='[';}
232 _SUFFIX_BUS_DELIM: ']' {$$=']';}
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);
243 | _E_BUS_DELIMITER _PREFIX_BUS_DELIM _SUFFIX_BUS_DELIM
244 { SPEF_INFO->PREFIX_BUS_DELIMITER = $2;
245 SPEF_INFO->SUFFIX_BUS_DELIMITER = $3;
248 unit_def : time_scale cap_scale res_scale induc_scale { } ;
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; } ;
254 time_unit : _NS { SPEF_INFO->SPEF_T_UNIT = 'N'; }
255 | _PS { SPEF_INFO->SPEF_T_UNIT = 'P'; } ;
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;
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;
268 cap_unit : _PF { SPEF_INFO->SPEF_CAP_UNIT = 'P'; }
269 | _FF { SPEF_INFO->SPEF_CAP_UNIT = 'F'; } ;
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;
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;
282 res_unit : _OHM { SPEF_INFO->SPEF_RES_UNIT = 'O'; }
283 | _KOHM { SPEF_INFO->SPEF_RES_UNIT = 'K';} ;
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; } ;
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'; } ;
293 | _E_NAME_MAP {namemaptable = addit(100); } name_map_entry name_map_entry_list { } ;
295 name_map_entry : _INDEX a_name
297 int index = atoi($1 + 1);
298 char *name = spef_rename($2);
299 setititem(namemaptable, index, (long)name);
304 name_map_entry_list : empty { }
305 | name_map_entry_list name_map_entry { } ;
307 power_def : empty { }
309 | power_net_def ground_net_def
313 power_net_def : _E_POWER_NETS net_name_list ;
314 ground_net_def : _E_GROUND_NETS net_name_list ;
316 net_name_list: net_name
317 | net_name_list net_name
320 net_name : net_ref {mbkfree($1);}
327 portmap_ht = addht(100);
328 for(ptcon=Lofig->LOCON; ptcon; ptcon=ptcon->NEXT)
329 addhtitem(portmap_ht, ptcon->NAME, (long)ptcon->NAME);
331 vss = namealloc("VSS");
332 spef_SetGroundSignal(vss);
338 vss = namealloc("VSS");
339 spef_SetGroundSignal(vss);
343 port_def : _E_PORTS {portmap_ht = addht(100);} port_entry port_entry_list
347 port_entry : port_name direction conn_attr_list { } ;
349 port_entry_list : empty { }
350 | port_entry_list port_entry { } ;
357 spef_SetGroundSignal($1);
361 addhtitem(portmap_ht, spef_spi_devect($1), (long)spef_spi_devect($1));
369 spef_SetGroundSignal($1);
373 addhtitem(portmap_ht, spef_spi_devect($1), (long)spef_spi_devect($1));
377 direction : _SPEF_I { }
382 conn_attr_list : empty { }
383 | conn_attr_list conn_attr { } ;
385 conn_attr : coordinates { }
390 coordinates : _E_C number number { } ;
396 cap_load : _E_L par_value { } ;
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; } ;
403 slews : _E_S par_value par_value .thresholds. { } ;
405 .thresholds. : threshold threshold
409 threshold: _POS_NUMBER {}
410 | _POS_NUMBER ':' _POS_NUMBER ':' _POS_NUMBER {}
414 driving_cell : _E_D a_name
418 | _E_D _INDEX {mbkfree($2);}
421 define_def : empty { } ;
423 internal_def : nets nets_list { } ;
425 nets_list : empty { }
426 | nets_list nets { } ;
434 d_net : _E_D_NET net_ref total_cap
439 name = (char*)getititem(namemaptable, atoi($2 + 1));
440 ls =spef_NewNet(name, $3 * SPEF_INFO->SPEF_CAP_SCALE);
442 name = spef_spi_devect($2);
443 ls=spef_NewNet(name, $3 * SPEF_INFO->SPEF_CAP_SCALE);
445 spef_setcurnet($2, ls);
447 .routing_conf. .conn_sec. .cap_sec. .res_sec. .induc_sec. _E_END
450 if ((ptsig = spef_getcurnet())!=NULL)
452 spef_setcurnet("", NULL);
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
459 net_ref : _INDEX { $$ = $1; }
460 | a_name { $$ = $1; } ;
463 total_cap : par_value { $$ = $1; } ;
465 .routing_conf. : empty { }
466 | _E_V _POS_INTEGER { } ;
468 .conn_sec. : _E_CONN conn_def conn_def_list .internal_node_coord_list. { }
472 conn_def_list : empty { }
473 | conn_def_list conn_def { } ;
475 .internal_node_coord_list.:
476 .internal_node_coord_list. internal_node_coord
480 internal_node_coord : _E_N node_name coordinates {mbkfree($2);}
483 .extention_node.: _E_X _POS_INTEGER
485 $$.longint=$2.longint;
493 conn_def : _E_P a_name direction conn_attr_list .extention_node.
496 name = namealloc($2);
497 if (!ignore) spef_AddConnector(name, $5.longint);
500 | _E_P _INDEX direction conn_attr_list .extention_node.
503 name = namealloc($2);
504 if (!ignore) spef_AddConnector(name, $5.longint);
507 | _E_I a_name direction conn_attr_list .extention_node.
509 char *instpinname, *pinname, *name;
511 instpinname = mbkstrdup($2);
512 pinname = strrchr(instpinname, SPEF_INFO->DELIMITER);
520 pinname="<delimiter not found>";
521 avt_errmsg(SPE_ERRMSG, "015", AVT_FATAL, spef_ParsedFile, Line, SPEF_INFO->DELIMITER, instpinname);
524 if(instpinname[0] == '*')
525 name = (char*)getititem(namemaptable, atoi(instpinname + 1));
529 spef_AddInstanceConnector($2,name,pinname,$5.longint);
530 mbkfree(instpinname);
536 .cap_sec. : _E_CAP cap_elm cap_elm_list { }
540 cap_elm_list : empty { }
541 | cap_elm_list cap_elm { } ;
543 cap_elm : _POS_INTEGER reduced_node_name par_value
545 if (!ignore) ctclist = spef_AddCapacitance(ctclist, $2,vss,$3 * SPEF_INFO->SPEF_CAP_SCALE);
548 | _POS_INTEGER reduced_node_name reduced_node_name par_value
550 if (!ignore) ctclist = spef_AddCapacitance(ctclist, $2,$3,$4 * SPEF_INFO->SPEF_CAP_SCALE);
561 $$ = mbkstrdup($1.text);
574 reduced_node_name : _IDENTIFIER
584 .res_sec. : _E_RES res_elm res_elm_list { }
588 res_elm_list : empty { }
589 | res_elm_list res_elm { } ;
591 res_elm : _POS_INTEGER node_name node_name par_value
593 if (!ignore) spef_AddResistor($2,$3,$4 * SPEF_INFO->SPEF_RES_SCALE);
598 .induc_sec. : _E_INDUC induc_elm induc_elm_list { }
601 induc_elm_list : empty { }
602 | induc_elm_list induc_elm { } ;
604 induc_elm : _POS_INTEGER node_name node_name par_value { mbkfree($2); mbkfree($3);} ;
609 r_net : _E_RNET net_ref total_cap
610 .routing_conf. .driver_reduc_list. _E_END {mbkfree($2);}
613 r_pnet : _E_RPNET net_ref total_cap
614 .routing_conf. .driver_reduc_list. _E_END {mbkfree($2);}
617 .driver_reduc_list. :
618 .driver_reduc_list. driver_reduc
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);};
625 rc_desc_list : rc_desc
626 | rc_desc_list rc_desc
629 rc_desc: _E_RC a_name par_value .pole_residue_desc. {mbkfree($2);};
631 .pole_residue_desc.: pole_desc residue_desc
635 pole_desc: _E_Q _POS_INTEGER pole_list ;
636 residue_desc: _E_K _POS_INTEGER residue_list ;
641 residue_list: residue
642 | residue_list residue
645 pole: complex_par_value ;
646 residue: complex_par_value ;
648 complex_par_value: cnumber
650 | cnumber ':' cnumber ':' cnumber
651 | number ':' number ':' number
654 cnumber: '(' number number ')' ;
659 extern char *speftext ;
663 avt_errmsg(SPE_ERRMSG, "004", AVT_FATAL, spef_ParsedFile, Line, speftext);
664 // printf("\nSPEF Parser:%s:%d: Syntax Error.\n", spef_ParsedFile, Line) ;
669 void spef_parser_error(char *message)
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) ;
676 static void clean_SPEF_INFO()
679 for (cl=SPEF_INFO->DESIGN_FLOW; cl!=NULL; cl=cl->NEXT)
681 freechain(SPEF_INFO->DESIGN_FLOW);