OpenSTA/parasitics/SpfParse.yy

499 lines
7.1 KiB
Plaintext

%{
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "Machine.hh"
#include "StringUtil.hh"
#include "SpfReaderPvt.hh"
int SpfLex_lex();
#define SpfParse_lex SpfLex_lex
// Use yacc generated parser errors.
#define YYERROR_VERBOSE
%}
%union {
char ch;
const char *string;
int integer;
float number;
}
%token RSPF DSPF DESIGN DATE VENDOR PROGRAM PVERSION DIVIDER DELIMITER BUSBIT
%token GROUND_NET NET PINDEF INSTPIN SUBNODE DRIVER LOAD
%token SUBCKT ENDS SUBCKT_CALL CAPACITOR RESISTOR VCVS
%token END
%token NUMBER ENUMBER INUMBER CVALUE QSTRING ID PATH
%type <integer> INUMBER
%type <number> NUMBER ENUMBER CVALUE
%type <string> QSTRING ID PATH
%type <number> net_cap pin_cap cvalue rvalue vvalue
%type <number> rc_pair rc_pairs coord coords
%type <string> inst_name net_name subnode_name instpin_name pin_name
%type <string> pin_type element_name element_node id_or_inumber
%type <ch> hchar
%start file
%{
%}
%%
file:
dspf_file
| rspf_file
;
////////////////////////////////////////////////////////////////
//
// DSPF
//
////////////////////////////////////////////////////////////////
dspf_file:
header dspf_subckt end
;
dspf_subckt:
subckt_def
gnet_defs
dspf_blocks
end_subckt
;
dspf_blocks:
dspf_block
| dspf_blocks dspf_block
;
dspf_block:
dspf_net_block
| inst_block
;
dspf_net_block:
net_def
net_node_defs
rc_defs
{ sta::spf_reader->dspfNetFinish(); }
;
net_node_defs:
net_node_def
| net_node_defs net_node_def
;
net_node_def:
pin_def
| instpin_def
| subnode_def
;
pin_def:
PINDEF pin_elements
;
pin_elements:
pin_element
| pin_elements pin_element
;
pin_element:
'(' pin_name pin_type pin_cap coords ')'
{ sta::spf_reader->dspfPinDef($2, $3); }
;
instpin_def:
INSTPIN instpin_elements
;
instpin_elements:
instpin_element
| instpin_elements instpin_element
;
instpin_element:
'(' instpin_name inst_name pin_name pin_type pin_cap coords ')'
{ sta::spf_reader->dspfInstPinDef($2, $3, $4, $5); }
;
////////////////////////////////////////////////////////////////
//
// RSPF
//
////////////////////////////////////////////////////////////////
rspf_file:
header rspf_subckt end
;
rspf_subckt:
subckt_def
gnet_defs
rspf_net_blocks
inst_blocks
end_subckt
;
rspf_net_blocks:
rspf_net_block
| rspf_net_blocks rspf_net_block
;
rspf_net_block:
net_def
dl_blocks
{ sta::spf_reader->rspfNetFinish(); }
;
dl_blocks:
/* empty */
| dl_block
;
dl_block:
driver_block
load_blocks
;
load_blocks:
/* empty */
| load_blocks load_block
;
driver_block:
driver_def rc_defs
{ sta::spf_reader->rspfDrvrFinish(); }
| driver_def subnode_def rc_defs
{ sta::spf_reader->rspfDrvrFinish(); }
;
driver_def:
DRIVER pin_name
{ sta::spf_reader->rspfDrvrBegin($2); }
| DRIVER instpin_name inst_name pin_name
{ sta::spf_reader->rspfDrvrBegin($2, $3, $4); }
;
load_block:
load_def rcv_defs
{ sta::spf_reader->rspfLoadFinish(); }
| load_def subnode_def rcv_defs
{ sta::spf_reader->rspfLoadFinish(); }
;
load_def:
LOAD pin_name
{ sta::spf_reader->rspfLoadBegin($2); }
| LOAD instpin_name inst_name pin_name
{ sta::spf_reader->rspfLoadBegin($2, $3, $4); }
;
////////////////////////////////////////////////////////////////
//
// RSPF/DSPF common
//
////////////////////////////////////////////////////////////////
header:
design_name
date
vendor
program_name
program_version
hierarchy_divider
name_delimiter
busbit_chars
;
design_name:
/* empty */
| DESIGN QSTRING
{ sta::stringDelete($2); }
| DESIGN ID
{ sta::stringDelete($2); }
;
date:
/* empty */
| DATE QSTRING
{ sta::stringDelete($2); }
;
vendor:
/* empty */
| VENDOR QSTRING
{ sta::stringDelete($2); }
;
program_name:
/* empty */
| PROGRAM QSTRING
{ sta::stringDelete($2); }
;
program_version:
/* empty */
| PVERSION QSTRING
{ sta::stringDelete($2); }
;
hierarchy_divider:
/* empty */
| DIVIDER hchar
{ sta::spf_reader->setDivider($2); }
;
name_delimiter:
/* empty */
| DELIMITER hchar
{ sta::spf_reader->setDelimiter($2); }
;
busbit_chars:
/* empty */
| BUSBIT hchar hchar
{ sta::spf_reader->setBusBrackets($2, $3); }
;
end:
/* empty */
| END
;
subckt_def:
SUBCKT ID subckt_ports
{ sta::stringDelete($2); }
;
subckt_ports:
/* empty */
| subckt_ports ID
{ sta::stringDelete($2); }
;
gnet_defs:
gnet_def
| gnet_defs gnet_def
;
gnet_def:
GROUND_NET id_or_inumber
{ sta::spf_reader->setGroundNet($2); }
;
subnode_def:
SUBNODE subnode_elements
;
subnode_elements:
subnode_element
| subnode_elements subnode_element
;
subnode_element:
'(' subnode_name coords ')'
{ sta::spf_reader->subnodeDef($2); }
;
element_node:
id_or_inumber
| PATH
;
element_name:
id_or_inumber
;
rc_defs:
/* empty */
| rc_defs resistor_def
| rc_defs capacitor_def
;
resistor_def:
RESISTOR element_name element_node element_node rvalue
{ sta::spf_reader->resistor($2, $3, $4, $5); }
;
capacitor_def:
CAPACITOR element_name element_node element_node cvalue
{ sta::spf_reader->capacitor($2, $3, $4, $5); }
;
vcvs_def:
VCVS element_name
element_node element_node
element_node element_node vvalue
{ sta::stringDelete($2);
sta::stringDelete($3);
sta::stringDelete($4);
sta::stringDelete($5);
sta::stringDelete($6);
}
;
rcv_defs:
/* empty */
| rcv_defs resistor_def
| rcv_defs capacitor_def
| rcv_defs vcvs_def
;
inst_blocks:
/* empty */
| inst_blocks inst_block
;
inst_block:
SUBCKT_CALL inst_block_nodes ID
{ sta::stringDelete($3); }
;
inst_block_nodes:
/* empty */
| inst_block_nodes net_name
{ sta::stringDelete($2); }
;
end_subckt:
ENDS
;
net_def:
NET net_name net_cap
{ sta::spf_reader->netBegin($2); }
;
instpin_name:
PATH
;
subnode_name:
PATH
;
net_name:
ID
| PATH
;
inst_name:
ID
| PATH
;
net_cap:
cvalue
;
pin_name:
ID
;
pin_type:
ID
;
id_or_inumber:
ID
| INUMBER
{ $$ = sta::integerString($1); }
;
pin_cap:
cvalue
| cvalue '(' rc_pairs ')'
;
rc_pairs:
rc_pair
| rc_pairs rc_pair
;
rc_pair:
rvalue cvalue
;
coords:
/* empty */
{ $$ = 0; }
| coord coord
;
coord:
INUMBER
{ $$ = static_cast<float>($1); }
| '-' INUMBER
{ $$ = -static_cast<float>($2); }
| NUMBER
| '-' NUMBER
{ $$ = $2; }
;
cvalue:
INUMBER
{ $$ = static_cast<float>($1); }
| NUMBER
| ENUMBER
| CVALUE
;
rvalue:
INUMBER
{ $$ = static_cast<float>($1); }
| NUMBER
| ENUMBER
;
vvalue:
INUMBER
{ $$ = static_cast<float>($1); }
| NUMBER
| ENUMBER
;
hchar:
'.'
{ $$ = '.'; }
| '/'
{ $$ = '/'; }
| '|'
{ $$ = '|'; }
| ':'
{ $$ = ':'; }
| '['
{ $$ = '['; }
| ']'
{ $$ = ']'; }
| '<'
{ $$ = '<'; }
| '>'
{ $$ = '>'; }
| '('
{ $$ = '('; }
| ')'
{ $$ = ')'; }
;
%%