copyright, rm obsolete files
This commit is contained in:
parent
601143cec3
commit
20ab0a1f23
18
README.md
18
README.md
|
|
@ -195,9 +195,19 @@ I am happy to say I haven't owned a windoz machine in 20 years.
|
|||
|
||||
## License
|
||||
|
||||
OpenSTA, Static Timing Analyzer
|
||||
Copyright (c) 2019, Parallax Software, Inc.
|
||||
All rights reserved.
|
||||
|
||||
No part of this document may be copied, transmitted or
|
||||
disclosed in any form or fashion without the express
|
||||
written consent of 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/>.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
// 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 <string.h>
|
||||
#include <ctype.h>
|
||||
#include "Machine.hh"
|
||||
#include "Zlib.hh"
|
||||
#include "Error.hh"
|
||||
#include "Report.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "SpfReader.hh"
|
||||
#include "SpefReader.hh"
|
||||
#include "ReadParasitics.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
typedef enum {
|
||||
parasitics_file_dspf,
|
||||
parasitics_file_rspf,
|
||||
parasitics_file_spef,
|
||||
parasitics_file_unknown
|
||||
} ParasiticsFileType;
|
||||
|
||||
static void
|
||||
parsiticsFileType(gzFile stream,
|
||||
Report *report,
|
||||
ParasiticsFileType &file_type,
|
||||
int &line_num);
|
||||
static bool
|
||||
isSpfComment(const char *line,
|
||||
bool &in_multi_line_comment,
|
||||
bool &in_single_line_comment);
|
||||
|
||||
bool
|
||||
readParasiticsFile(const char *filename,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool save, bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics)
|
||||
{
|
||||
bool success = false;
|
||||
// Use zlib to uncompress gzip'd files automagically.
|
||||
gzFile stream = gzopen(filename, "rb");
|
||||
if (stream) {
|
||||
ParasiticsFileType file_type;
|
||||
int line_num;
|
||||
parsiticsFileType(stream, report, file_type, line_num);
|
||||
switch (file_type) {
|
||||
case parasitics_file_spef:
|
||||
success = readSpefFile(filename, stream, line_num,
|
||||
instance, ap, increment, pin_cap_included,
|
||||
keep_coupling_caps, coupling_cap_factor,
|
||||
reduce_to, delete_after_reduce,
|
||||
op_cond, corner, cnst_min_max,
|
||||
save, quiet, report, network, parasitics);
|
||||
|
||||
break;
|
||||
case parasitics_file_rspf:
|
||||
success = readSpfFile(filename, stream, line_num, true, instance, ap,
|
||||
increment, pin_cap_included,
|
||||
keep_coupling_caps, coupling_cap_factor,
|
||||
reduce_to, delete_after_reduce,
|
||||
op_cond, corner, cnst_min_max,
|
||||
save, quiet, report, network, parasitics);
|
||||
break;
|
||||
case parasitics_file_dspf:
|
||||
success = readSpfFile(filename, stream, line_num, false, instance, ap,
|
||||
increment, pin_cap_included,
|
||||
keep_coupling_caps, coupling_cap_factor,
|
||||
reduce_to, delete_after_reduce,
|
||||
op_cond, corner, cnst_min_max,
|
||||
save, quiet, report,
|
||||
network, parasitics);
|
||||
break;
|
||||
case parasitics_file_unknown:
|
||||
report->error("unknown parasitics file type.\n");
|
||||
break;
|
||||
}
|
||||
gzclose(stream);
|
||||
}
|
||||
else
|
||||
throw FileNotReadable(filename);
|
||||
return success;
|
||||
}
|
||||
|
||||
// Read the first line of a parasitics file to find its type.
|
||||
static void
|
||||
parsiticsFileType(gzFile stream,
|
||||
Report *report,
|
||||
ParasiticsFileType &file_type,
|
||||
int &line_num)
|
||||
{
|
||||
file_type = parasitics_file_unknown;
|
||||
line_num = 1;
|
||||
const int line_len = 100;
|
||||
char line[line_len];
|
||||
char *err;
|
||||
bool in_multi_line_comment = false;
|
||||
bool in_single_line_comment = false;
|
||||
// Skip comment lines before looking for file type.
|
||||
do {
|
||||
err = gzgets(stream, line, line_len);
|
||||
if (err == Z_NULL) {
|
||||
report->error("SPEF/RSPF/DSPF header not found.\n");
|
||||
file_type = parasitics_file_unknown;
|
||||
}
|
||||
if (line[strlen(line) - 1] == '\n')
|
||||
line_num++;
|
||||
} while (isSpfComment(line, in_multi_line_comment, in_single_line_comment)
|
||||
|| in_multi_line_comment
|
||||
|| in_single_line_comment);
|
||||
|
||||
if (stringEq(line, "*SPEF", 5))
|
||||
file_type = parasitics_file_spef;
|
||||
else if (stringEq(line, "*|RSPF", 6))
|
||||
file_type = parasitics_file_rspf;
|
||||
else if (stringEq(line, "*|DSPF", 6))
|
||||
file_type = parasitics_file_dspf;
|
||||
}
|
||||
|
||||
static bool
|
||||
isSpfComment(const char *line,
|
||||
bool &in_multi_line_comment,
|
||||
bool &in_single_line_comment)
|
||||
{
|
||||
const char *s = line;
|
||||
while (isspace(*s) && *s)
|
||||
s++;
|
||||
if (in_multi_line_comment) {
|
||||
in_multi_line_comment = (strstr(s, "*/") == NULL);
|
||||
return true;
|
||||
}
|
||||
else if (in_single_line_comment) {
|
||||
in_single_line_comment = (line[strlen(line) - 1] != '\n');
|
||||
return true;
|
||||
}
|
||||
else if (*s && stringEq(s, "/*", 2)) {
|
||||
in_multi_line_comment = strstr(s, "*/") == NULL;
|
||||
return true;
|
||||
}
|
||||
else if (*s && stringEq(s, "//", 2)) {
|
||||
in_single_line_comment = (line[strlen(line) - 1] != '\n');
|
||||
return true;
|
||||
}
|
||||
else if (*s && stringEq(s, "*", 1)
|
||||
&& !stringEq(s, "*|", 2)
|
||||
&& !stringEq(s, "*SPEF", 5)) {
|
||||
in_single_line_comment = false;
|
||||
// DSPF or RSPF comment.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// 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/>.
|
||||
|
||||
namespace sta {
|
||||
|
||||
#include "ParasiticsClass.hh"
|
||||
|
||||
class Report;
|
||||
|
||||
// Read a Spf or Spef parasitics file that may be compressed with gzip.
|
||||
// Spf or Spef single value parasitics are read into analysis point ap.
|
||||
// In a Spef file with triplet values the first value is used.
|
||||
// If reduce_to is specified detailed parasitics are reduced.
|
||||
// If delete_after_reduce is specified the detailed parasitics are
|
||||
// deleted after they are reduced.
|
||||
// Constraint min/max cnst_min_max and operating condition op_cond
|
||||
// are used for parasitic network reduction.
|
||||
// Return true if successful.
|
||||
bool
|
||||
readParasiticsFile(const char *filename,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool save,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics);
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
%{
|
||||
|
||||
// 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 <string.h>
|
||||
#include <string>
|
||||
#include "Machine.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "SpfReaderPvt.hh"
|
||||
#include "SpfParse.hh"
|
||||
|
||||
#define YY_NO_INPUT
|
||||
|
||||
#define keyword(_key_) \
|
||||
BEGIN(STMT); \
|
||||
return _key_;
|
||||
|
||||
static std::string spf_token;
|
||||
|
||||
void
|
||||
spfFlushBuffer()
|
||||
{
|
||||
YY_FLUSH_BUFFER;
|
||||
}
|
||||
|
||||
// Reset the start condition to INITIAL.
|
||||
void
|
||||
spfResetScanner()
|
||||
{
|
||||
BEGIN(0);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
/* %option debug */
|
||||
%option noyywrap
|
||||
%option nounput
|
||||
%option never-interactive
|
||||
|
||||
%x STMT
|
||||
%x QUOTE
|
||||
|
||||
INUMBER [0-9]+
|
||||
NUMBER ([0-9]*)"."[0-9]+
|
||||
ENUMBER ({NUMBER}|{INUMBER})[eE]("-"|"+")?[0-9]+
|
||||
UNIT [KMUNPF]
|
||||
HCHAR "."|"/"|"|"|":"|"["|"]"|"<"|">"|"("|")"
|
||||
ID ([A-Za-z_]|\\.)([A-Za-z0-9_\[\]]|\\.)*
|
||||
BLANK [ \n\t\r\b]
|
||||
EOL \r?\n
|
||||
|
||||
%%
|
||||
|
||||
"*|RSPF" { keyword(RSPF) }
|
||||
"*|DSPF" { keyword(DSPF) }
|
||||
"*|DESIGN" { keyword(DESIGN) }
|
||||
"*|DATE" { keyword(DATE) }
|
||||
"*|VENDOR" { keyword(VENDOR) }
|
||||
"*|PROGRAM" { keyword(PROGRAM) }
|
||||
"*|VERSION" { keyword(PVERSION) }
|
||||
"*|DIVIDER" { keyword(DIVIDER) }
|
||||
"*|DELIMITER" { keyword(DELIMITER) }
|
||||
"*|BUSBIT" { keyword(BUSBIT) }
|
||||
"*|GROUND_NET" { keyword(GROUND_NET) }
|
||||
"*|NET" { keyword(NET) }
|
||||
"*|DRIVER" { keyword(DRIVER) }
|
||||
"*|LOAD" { keyword(LOAD) }
|
||||
"*|P" { keyword(PINDEF) }
|
||||
"*|I" { keyword(INSTPIN) }
|
||||
"*|S" { keyword(SUBNODE) }
|
||||
".SUBCKT" { keyword(SUBCKT) }
|
||||
".ENDS" { keyword(ENDS) }
|
||||
".END" { keyword(END) }
|
||||
X { keyword(SUBCKT_CALL) }
|
||||
C { keyword(CAPACITOR) }
|
||||
R { keyword(RESISTOR) }
|
||||
E { keyword(VCVS) }
|
||||
|
||||
"*"[^|+\r\n][^\r\n]*{EOL} {
|
||||
/* comment */
|
||||
sta::spf_reader->incrLine();
|
||||
}
|
||||
|
||||
"*"{EOL} {
|
||||
/* blank single line comment */
|
||||
sta::spf_reader->incrLine();
|
||||
}
|
||||
|
||||
[ \t]*{EOL} {
|
||||
/* blank line */
|
||||
sta::spf_reader->incrLine();
|
||||
}
|
||||
|
||||
<STMT>{
|
||||
|
||||
{INUMBER} {
|
||||
SpfParse_lval.integer = atoi(yytext);
|
||||
return INUMBER;
|
||||
}
|
||||
|
||||
{ENUMBER} {
|
||||
SpfParse_lval.number = static_cast<float>(atof(yytext));
|
||||
return ENUMBER;
|
||||
}
|
||||
|
||||
{NUMBER} {
|
||||
SpfParse_lval.number = static_cast<float>(atof(yytext));
|
||||
return NUMBER;
|
||||
}
|
||||
|
||||
({INUMBER}|{NUMBER}|{ENUMBER}){UNIT} {
|
||||
int len = strlen(yytext);
|
||||
char unit = yytext[len - 1];
|
||||
float scale = sta::spf_reader->unitScale(unit);
|
||||
yytext[len - 1] = '\0';
|
||||
SpfParse_lval.number = static_cast<float>(atof(yytext) * scale);
|
||||
return NUMBER;
|
||||
}
|
||||
|
||||
({INUMBER}|{NUMBER}|{ENUMBER}){UNIT}?F {
|
||||
int len = strlen(yytext);
|
||||
char unit = yytext[len - 2];
|
||||
float scale = sta::spf_reader->unitScale(unit);
|
||||
yytext[len - 2] = '\0';
|
||||
SpfParse_lval.number = static_cast<float>(atof(yytext) * scale);
|
||||
return CVALUE;
|
||||
}
|
||||
|
||||
{HCHAR} { return ((int) yytext[0]); }
|
||||
|
||||
{ID} {
|
||||
SpfParse_lval.string = sta::spf_reader->translated(yytext);
|
||||
return ID;
|
||||
}
|
||||
|
||||
{ID}({HCHAR}({ID}|{INUMBER}))+ {
|
||||
SpfParse_lval.string = sta::spf_reader->translated(yytext);
|
||||
return PATH;
|
||||
}
|
||||
|
||||
{EOL}"+" {
|
||||
/* continuation */
|
||||
sta::spf_reader->incrLine();
|
||||
}
|
||||
|
||||
{EOL}"*+" {
|
||||
/* comment continuation */
|
||||
sta::spf_reader->incrLine();
|
||||
}
|
||||
|
||||
{EOL} {
|
||||
sta::spf_reader->incrLine();
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
"\"" {
|
||||
BEGIN(QUOTE);
|
||||
spf_token.erase();
|
||||
}
|
||||
|
||||
{BLANK} /* ignore blanks */
|
||||
|
||||
/* Send out of bound characters to parser. */
|
||||
. { return ((int) yytext[0]); }
|
||||
|
||||
}
|
||||
|
||||
<QUOTE>{
|
||||
|
||||
"\\". { spf_token += yytext[1]; }
|
||||
|
||||
"\"" {
|
||||
BEGIN(STMT);
|
||||
const char *token = spf_token.c_str();
|
||||
SpfParse_lval.string= sta::stringCopy(token);
|
||||
return QSTRING;
|
||||
}
|
||||
|
||||
. { spf_token += yytext[0]; }
|
||||
|
||||
}
|
||||
|
||||
/* Send out of bound characters to parser. */
|
||||
. { return ((int) yytext[0]); }
|
||||
|
||||
%%
|
||||
|
|
@ -1,498 +0,0 @@
|
|||
%{
|
||||
|
||||
// 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:
|
||||
'.'
|
||||
{ $$ = '.'; }
|
||||
| '/'
|
||||
{ $$ = '/'; }
|
||||
| '|'
|
||||
{ $$ = '|'; }
|
||||
| ':'
|
||||
{ $$ = ':'; }
|
||||
| '['
|
||||
{ $$ = '['; }
|
||||
| ']'
|
||||
{ $$ = ']'; }
|
||||
| '<'
|
||||
{ $$ = '<'; }
|
||||
| '>'
|
||||
{ $$ = '>'; }
|
||||
| '('
|
||||
{ $$ = '('; }
|
||||
| ')'
|
||||
{ $$ = ')'; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
@ -1,633 +0,0 @@
|
|||
// 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 "Zlib.hh"
|
||||
#include "Debug.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "Map.hh"
|
||||
#include "Network.hh"
|
||||
#include "Transition.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "SpfReaderPvt.hh"
|
||||
#include "SpfReader.hh"
|
||||
|
||||
int
|
||||
SpfParse_parse();
|
||||
void
|
||||
spfResetScanner();
|
||||
|
||||
namespace sta {
|
||||
|
||||
SpfReader *spf_reader;
|
||||
const Pin *SpfReader::gnd_net_ = reinterpret_cast<Pin*>(1);
|
||||
const Pin *SpfReader::rspf_subnode_ = reinterpret_cast<Pin*>(2);
|
||||
|
||||
bool
|
||||
readSpfFile(const char *filename,
|
||||
gzFile stream,
|
||||
int line,
|
||||
bool rspf,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool save,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics)
|
||||
{
|
||||
SpfReader reader(filename, stream, line, rspf, instance, ap,
|
||||
increment, pin_cap_included, keep_coupling_caps,
|
||||
coupling_cap_factor, reduce_to, delete_after_reduce,
|
||||
op_cond, corner, cnst_min_max, quiet,
|
||||
report, network, parasitics);
|
||||
spf_reader = &reader;
|
||||
::spfResetScanner();
|
||||
// yyparse returns 0 on success.
|
||||
bool success = (::SpfParse_parse() == 0);
|
||||
if (success && save)
|
||||
parasitics->save();
|
||||
return success;
|
||||
}
|
||||
|
||||
SpfReader::SpfReader(const char *filename,
|
||||
gzFile stream,
|
||||
int line,
|
||||
bool rspf,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics):
|
||||
SpfSpefReader(filename, stream, line, instance, ap, increment,
|
||||
pin_cap_included, keep_coupling_caps, coupling_cap_factor,
|
||||
reduce_to, delete_after_reduce, op_cond, corner, cnst_min_max,
|
||||
quiet, report, network, parasitics),
|
||||
is_rspf_(rspf),
|
||||
gnd_net_name_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
SpfReader::~SpfReader()
|
||||
{
|
||||
clearPinMap();
|
||||
// gnd_net remains in the pin map, so delete it here.
|
||||
if (gnd_net_name_)
|
||||
stringDelete(gnd_net_name_);
|
||||
pin_node_map_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::setGroundNet(const char *ground_net)
|
||||
{
|
||||
gnd_net_name_ = ground_net;
|
||||
pin_node_map_[ground_net] = gnd_net_;
|
||||
}
|
||||
|
||||
// Some SPF writers use DRIVER/LOAD stmts to define an alias for the
|
||||
// pin name so make a table to map from the name to the node/pin.
|
||||
void
|
||||
SpfReader::rspfDrvrBegin(const char *drvr_pin_name)
|
||||
{
|
||||
rspf_drvr_pin_ = findPinRelative(drvr_pin_name);
|
||||
if (rspf_drvr_pin_)
|
||||
pin_node_map_[drvr_pin_name] = rspf_drvr_pin_;
|
||||
else {
|
||||
pinNotFound(drvr_pin_name);
|
||||
stringDelete(drvr_pin_name);
|
||||
}
|
||||
rspfDrvrBegin();
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfDrvrBegin(const char *drvr_pin_name,
|
||||
const char *inst_name,
|
||||
const char *port_name)
|
||||
{
|
||||
rspf_drvr_pin_ = 0;
|
||||
parasitic_ = 0;
|
||||
Instance *inst = findInstanceRelative(inst_name);
|
||||
if (inst) {
|
||||
rspf_drvr_pin_ = network_->findPinRelative(inst, port_name);
|
||||
if (rspf_drvr_pin_)
|
||||
pin_node_map_[drvr_pin_name] = rspf_drvr_pin_;
|
||||
else {
|
||||
instPinNotFound(inst_name, port_name);
|
||||
stringDelete(drvr_pin_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
instNotFound(inst_name);
|
||||
stringDelete(drvr_pin_name);
|
||||
}
|
||||
rspfDrvrBegin();
|
||||
stringDelete(inst_name);
|
||||
stringDelete(port_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfDrvrBegin()
|
||||
{
|
||||
rspf_c1_ = 0.0;
|
||||
rspf_c2_ = 0.0;
|
||||
rspf_rpi_ = 0.0;
|
||||
|
||||
rspf_load_pin_ = 0;
|
||||
rspf_c3_ = 0.0;
|
||||
rspf_r3_ = 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfLoadBegin(const char *load_pin_name)
|
||||
{
|
||||
rspf_load_pin_ = findPinRelative(load_pin_name);
|
||||
if (rspf_load_pin_)
|
||||
pin_node_map_[load_pin_name] = rspf_load_pin_;
|
||||
else {
|
||||
pinNotFound(load_pin_name);
|
||||
stringDelete(load_pin_name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfLoadBegin(const char *load_pin_name,
|
||||
const char *inst_name,
|
||||
const char *port_name)
|
||||
{
|
||||
Instance *inst = findInstanceRelative(inst_name);
|
||||
if (inst) {
|
||||
rspf_load_pin_ = network_->findPinRelative(inst, port_name);
|
||||
if (rspf_load_pin_)
|
||||
pin_node_map_[load_pin_name] = rspf_load_pin_;
|
||||
else {
|
||||
instPinNotFound(inst_name, port_name);
|
||||
stringDelete(load_pin_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
instNotFound(inst_name);
|
||||
rspf_load_pin_ = 0;
|
||||
stringDelete(load_pin_name);
|
||||
}
|
||||
stringDelete(inst_name);
|
||||
stringDelete(port_name);
|
||||
}
|
||||
|
||||
// Note that some SPF writers do not include subnode definitions.
|
||||
void
|
||||
SpfReader::subnodeDef(const char *subnode_name)
|
||||
{
|
||||
if (is_rspf_)
|
||||
pin_node_map_[subnode_name] = rspf_subnode_;
|
||||
else
|
||||
stringDelete(subnode_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::resistor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float res)
|
||||
{
|
||||
if (is_rspf_) {
|
||||
if (rspf_drvr_pin_) {
|
||||
if (rspf_load_pin_ == NULL)
|
||||
rspfDrvrRes(node1, node2, res);
|
||||
else
|
||||
rspfLoadRes(node1, node2, res);
|
||||
}
|
||||
stringDelete(name);
|
||||
}
|
||||
else
|
||||
dspfResistor(name, node1, node2, res);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfDrvrRes(const char *node1,
|
||||
const char *node2,
|
||||
float res)
|
||||
{
|
||||
const Pin *pin1 = pin_node_map_.findKey(node1);
|
||||
const Pin *pin2 = pin_node_map_.findKey(node2);
|
||||
// Ignore gnd'd resistors (r1).
|
||||
if (!((pin1 && pin1 == gnd_net_)
|
||||
|| (pin2 && pin2 == gnd_net_))) {
|
||||
if (pin1 && pin1 == rspf_drvr_pin_) {
|
||||
rspfSubnode(pin2, node2);
|
||||
rspf_rpi_ = res;
|
||||
stringDelete(node1);
|
||||
}
|
||||
else if (pin2 && pin2 == rspf_drvr_pin_) {
|
||||
rspfSubnode(pin1, node1);
|
||||
rspf_rpi_ = res;
|
||||
stringDelete(node2);
|
||||
}
|
||||
else
|
||||
warn("rspf resistor not connected to driver pin.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfSubnode(const Pin *subnode_pin,
|
||||
const char *subnode_name)
|
||||
{
|
||||
// Subnode does not have to be declared before use.
|
||||
if (subnode_pin != rspf_subnode_)
|
||||
// Define the driver subnode name.
|
||||
pin_node_map_[subnode_name] = rspf_subnode_;
|
||||
else
|
||||
stringDelete(subnode_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfLoadRes(const char *node1,
|
||||
const char *node2,
|
||||
float res)
|
||||
{
|
||||
rspf_r3_ = res;
|
||||
stringDelete(node1);
|
||||
stringDelete(node2);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::capacitor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float cap)
|
||||
{
|
||||
if (is_rspf_) {
|
||||
if (rspf_drvr_pin_) {
|
||||
if (rspf_load_pin_ == NULL)
|
||||
rspfDrvrCap(node1, node2, cap);
|
||||
else
|
||||
rspfLoadCap(node1, node2, cap);
|
||||
}
|
||||
stringDelete(name);
|
||||
}
|
||||
else
|
||||
dspfCapacitor(name, node1, node2, cap);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfDrvrCap(const char *node1,
|
||||
const char *node2,
|
||||
float cap)
|
||||
{
|
||||
const Pin *pin1 = pin_node_map_.findKey(node1);
|
||||
const Pin *pin2 = pin_node_map_.findKey(node2);
|
||||
if (pin1 && pin1 == gnd_net_) {
|
||||
rspfDrvrCap1(node2, pin2, cap);
|
||||
stringDelete(node1);
|
||||
}
|
||||
else if (pin2 && pin2 == gnd_net_) {
|
||||
rspfDrvrCap1(node1, pin1, cap);
|
||||
stringDelete(node2);
|
||||
}
|
||||
else
|
||||
warn("capacitor is not grounded.\n");
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfDrvrCap1(const char *pin_name,
|
||||
const Pin *pin,
|
||||
float cap)
|
||||
{
|
||||
if (pin && pin == rspf_drvr_pin_) {
|
||||
rspf_c2_ = cap;
|
||||
stringDelete(pin_name);
|
||||
}
|
||||
else {
|
||||
rspfSubnode(pin, pin_name);
|
||||
rspf_c1_ = cap;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfLoadCap(const char *node1,
|
||||
const char *node2,
|
||||
float cap)
|
||||
{
|
||||
rspf_c3_ = cap;
|
||||
stringDelete(node1);
|
||||
stringDelete(node2);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfDrvrFinish()
|
||||
{
|
||||
if (rspf_drvr_pin_
|
||||
// Incremental parasitics do not overwrite existing parasitics.
|
||||
&& !(increment_ &&
|
||||
parasitics_->hasPiElmore(rspf_drvr_pin_,
|
||||
TransRiseFall::rise(), ap_))) {
|
||||
parasitics_->deletePiElmore(rspf_drvr_pin_, TransRiseFall::rise(), ap_);
|
||||
parasitics_->deletePiElmore(rspf_drvr_pin_, TransRiseFall::fall(), ap_);
|
||||
// Only one parasitic, save it under rise transition.
|
||||
parasitic_ = parasitics_->makePiElmore(rspf_drvr_pin_,
|
||||
TransRiseFall::rise(), ap_,
|
||||
rspf_c2_, rspf_rpi_, rspf_c1_);
|
||||
}
|
||||
rspf_c2_ = rspf_rpi_ = rspf_c1_ = 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfLoadFinish()
|
||||
{
|
||||
if (parasitic_ && rspf_load_pin_)
|
||||
parasitics_->setElmore(parasitic_, rspf_load_pin_, rspf_r3_*rspf_c3_);
|
||||
rspf_load_pin_ = 0;
|
||||
rspf_r3_ = rspf_c3_ = 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::rspfNetFinish()
|
||||
{
|
||||
rspf_drvr_pin_ = 0;
|
||||
parasitic_ = 0;
|
||||
clearPinMap();
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::clearPinMap()
|
||||
{
|
||||
// Delete the pin names in the pin map.
|
||||
// Note that erasing the map elements while iterating fails on slowaris,
|
||||
// so delete all the strings, clear the map and put gnd back in.
|
||||
SpfPinMap::Iterator node_iter(pin_node_map_);
|
||||
while (node_iter.hasNext()) {
|
||||
const char *pin_name;
|
||||
const Pin *pin;
|
||||
node_iter.next(pin_name, pin);
|
||||
if (pin != gnd_net_)
|
||||
stringDelete(pin_name);
|
||||
}
|
||||
pin_node_map_.clear();
|
||||
pin_node_map_[gnd_net_name_] = gnd_net_;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
SpfReader::netBegin(const char *net_name)
|
||||
{
|
||||
if (!is_rspf_) {
|
||||
net_ = findNetRelative(net_name);
|
||||
if (net_) {
|
||||
if (increment_
|
||||
&& parasitics_->hasParasiticNetwork(net_, ap_))
|
||||
// Do not overwrite existing parasitic.
|
||||
dspf_ = 0;
|
||||
else {
|
||||
parasitics_->deleteParasitics(net_, ap_);
|
||||
dspf_ = parasitics_->makeParasiticNetwork(net_,pin_cap_included_,ap_);
|
||||
}
|
||||
}
|
||||
else {
|
||||
netNotFound(net_name);
|
||||
dspf_ = 0;
|
||||
}
|
||||
}
|
||||
stringDelete(net_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::dspfPinDef(const char *pin_name,
|
||||
const char *pin_type)
|
||||
{
|
||||
Pin *pin = findPortPinRelative(pin_name);
|
||||
if (pin)
|
||||
pin_node_map_[pin_name] = pin;
|
||||
else {
|
||||
pinNotFound(pin_name);
|
||||
stringDelete(pin_name);
|
||||
}
|
||||
stringDelete(pin_type);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::dspfInstPinDef(const char *pin_name,
|
||||
const char *inst_name,
|
||||
const char *port_name,
|
||||
const char *pin_type)
|
||||
{
|
||||
Instance *inst = findInstanceRelative(inst_name);
|
||||
if (inst) {
|
||||
Pin *pin = network_->findPinRelative(inst, port_name);
|
||||
if (pin)
|
||||
pin_node_map_[pin_name] = pin;
|
||||
else {
|
||||
instPinNotFound(inst_name, port_name);
|
||||
stringDelete(pin_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
instNotFound(inst_name);
|
||||
stringDelete(pin_name);
|
||||
}
|
||||
stringDelete(inst_name);
|
||||
stringDelete(port_name);
|
||||
stringDelete(pin_type);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::dspfResistor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float res)
|
||||
{
|
||||
if (dspf_) {
|
||||
ParasiticNode *pnode1 = ensureDspfNode(node1);
|
||||
ParasiticNode *pnode2 = ensureDspfNode(node2);
|
||||
if (!keep_device_names_) {
|
||||
stringDelete(name);
|
||||
name = 0;
|
||||
}
|
||||
if (pnode1 && pnode2)
|
||||
parasitics_->makeResistor(name, pnode1, pnode2, res, ap_);
|
||||
}
|
||||
stringDelete(node1);
|
||||
stringDelete(node2);
|
||||
}
|
||||
|
||||
ParasiticNode *
|
||||
SpfReader::ensureDspfNode(const char *node_name)
|
||||
{
|
||||
const Pin *pin = pin_node_map_.findKey(node_name);
|
||||
if (pin)
|
||||
return parasitics_->ensureParasiticNode(dspf_, pin);
|
||||
else {
|
||||
const char *delim = strrchr(node_name, delimiter_);
|
||||
if (delim) {
|
||||
const char *id_str = delim + 1;
|
||||
if (isDigits(id_str)) {
|
||||
int id = atoi(id_str);
|
||||
return parasitics_->ensureParasiticNode(dspf_, net_, id);
|
||||
}
|
||||
// Fall thru.
|
||||
}
|
||||
warn("node %s is not a sub-node or external pin connection\n", node_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::dspfCapacitor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float cap)
|
||||
{
|
||||
if (dspf_) {
|
||||
if (stringEq(node1, gnd_net_name_)) {
|
||||
ParasiticNode *pnode = ensureDspfNode(node2);
|
||||
if (pnode)
|
||||
parasitics_->incrCap(pnode, cap, ap_);
|
||||
stringDelete(name);
|
||||
}
|
||||
else if (stringEq(node2, gnd_net_name_)) {
|
||||
ParasiticNode *pnode = ensureDspfNode(node1);
|
||||
if (pnode)
|
||||
parasitics_->incrCap(pnode, cap, ap_);
|
||||
stringDelete(name);
|
||||
}
|
||||
else {
|
||||
// Coupling capacitor.
|
||||
ParasiticNode *pnode1 = ensureDspfNode(node1);
|
||||
ParasiticNode *pnode2 = ensureDspfNode(node2);
|
||||
if (keep_coupling_caps_
|
||||
&& pnode1 && pnode2) {
|
||||
if (!keep_device_names_) {
|
||||
stringDelete(name);
|
||||
name = 0;
|
||||
}
|
||||
parasitics_->makeCouplingCap(name, pnode1, pnode2, cap, ap_);
|
||||
}
|
||||
else {
|
||||
float scaled_cap = cap * ap_->couplingCapFactor();
|
||||
if (pnode1)
|
||||
parasitics_->incrCap(pnode1, scaled_cap, ap_);
|
||||
if (pnode2)
|
||||
parasitics_->incrCap(pnode2, scaled_cap, ap_);
|
||||
stringDelete(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
stringDelete(node1);
|
||||
stringDelete(node2);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::dspfNetFinish()
|
||||
{
|
||||
if (dspf_) {
|
||||
if (!quiet_)
|
||||
parasitics_->check(dspf_);
|
||||
if (reduce_to_ != reduce_parasitics_to_none) {
|
||||
TransRiseFallIterator tr_iter;
|
||||
while (tr_iter.hasNext()) {
|
||||
TransRiseFall *tr = tr_iter.next();
|
||||
parasitics_->reduceTo(dspf_, net_, reduce_to_, tr, op_cond_,
|
||||
corner_, cnst_min_max_, ap_);
|
||||
}
|
||||
if (delete_after_reduce_)
|
||||
parasitics_->deleteParasiticNetwork(net_, ap_);
|
||||
}
|
||||
}
|
||||
clearPinMap();
|
||||
net_ = 0;
|
||||
dspf_ = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
float
|
||||
SpfReader::unitScale(char unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case 'K':
|
||||
return 1E+3F;
|
||||
case 'M':
|
||||
return 1E+6F;
|
||||
case 'U':
|
||||
return 1E-6F;
|
||||
case 'N':
|
||||
return 1E-9F;
|
||||
case 'P':
|
||||
return 1E-12F;
|
||||
case 'F':
|
||||
return 1E-15F;
|
||||
default:
|
||||
warn("unknown unit suffix %c.\n", unit);
|
||||
}
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::pinNotFound(const char *pin_name)
|
||||
{
|
||||
warn("pin %s not found.\n", pin_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::netNotFound(const char *net_name)
|
||||
{
|
||||
warn("net %s not found.\n", net_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::instNotFound(const char *inst_name)
|
||||
{
|
||||
warn("instance %s not found.\n", inst_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfReader::instPinNotFound(const char *inst_name,
|
||||
const char *port_name)
|
||||
{
|
||||
warn("instance %s pin %s not found.\n", inst_name, port_name);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Global namespace
|
||||
|
||||
void spfFlushBuffer();
|
||||
|
||||
int
|
||||
SpfParse_error(const char *msg)
|
||||
{
|
||||
sta::spf_reader->warn("%s.\n", msg);
|
||||
spfFlushBuffer();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
// 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/>.
|
||||
|
||||
#ifndef STA_SPF_READER_H
|
||||
#define STA_SPF_READER_H
|
||||
|
||||
#include "Zlib.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
class Report;
|
||||
class Network;
|
||||
class Parasitics;
|
||||
class Instance;
|
||||
|
||||
// Constraint min/max cnst_min_max and operating condition op_cond
|
||||
// are used for parasitic network reduction.
|
||||
// Return true if successful.
|
||||
bool
|
||||
readSpfFile(const char *filename,
|
||||
gzFile stream,
|
||||
int line,
|
||||
bool rspf,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool save,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics);
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
// 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/>.
|
||||
|
||||
#ifndef STA_SPF_READER_PVT_H
|
||||
#define STA_SPF_READER_PVT_H
|
||||
|
||||
#include "Zlib.hh"
|
||||
#include "Map.hh"
|
||||
#include "SpfSpefReader.hh"
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
sta::spf_reader->getChars(buf, result, max_size)
|
||||
|
||||
int
|
||||
SpfParse_error(const char *msg);
|
||||
|
||||
namespace sta {
|
||||
|
||||
class Parasitics;
|
||||
class Parasitic;
|
||||
class ParasiticNode;
|
||||
class ParasiticNetwork;
|
||||
|
||||
typedef Map<const char *, const Pin*, CharPtrLess> SpfPinMap;
|
||||
|
||||
class SpfReader : public SpfSpefReader
|
||||
{
|
||||
public:
|
||||
SpfReader(const char *filename,
|
||||
gzFile stream,
|
||||
int line,
|
||||
bool rspf,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics);
|
||||
virtual ~SpfReader();
|
||||
void read();
|
||||
void setGroundNet(const char *ground_net);
|
||||
void netBegin(const char *net_name);
|
||||
void rspfDrvrBegin(const char *drvr_pin_name);
|
||||
void rspfDrvrBegin(const char *drvr_pin_name,
|
||||
const char *inst_name,
|
||||
const char *port_name);
|
||||
void subnodeDef(const char *subnode_name);
|
||||
void resistor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float res);
|
||||
void capacitor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float cap);
|
||||
void rspfLoadBegin(const char *load_pin_name);
|
||||
void rspfLoadBegin(const char *load_pin_name,
|
||||
const char *inst_name,
|
||||
const char *port_name);
|
||||
void rspfDrvrFinish();
|
||||
void rspfLoadFinish();
|
||||
void rspfNetFinish();
|
||||
|
||||
void dspfPinDef(const char *pin_name,
|
||||
const char *pin_type);
|
||||
void dspfInstPinDef(const char *pin_name,
|
||||
const char *inst_name,
|
||||
const char *port_name,
|
||||
const char *pin_type);
|
||||
void dspfNetFinish();
|
||||
|
||||
float unitScale(char unit);
|
||||
|
||||
private:
|
||||
void rspfDrvrBegin();
|
||||
void instNotFound(const char *inst_name);
|
||||
void pinNotFound(const char *pin_name);
|
||||
void netNotFound(const char *net_name);
|
||||
void instPinNotFound(const char *inst_name,
|
||||
const char *port_name);
|
||||
void clearPinMap();
|
||||
void rspfDrvrRes(const char *node1,
|
||||
const char *node2,
|
||||
float res);
|
||||
void rspfSubnode(const Pin *subnode_pin,
|
||||
const char *subnode_name);
|
||||
void rspfLoadRes(const char *node1,
|
||||
const char *node2,
|
||||
float res);
|
||||
void dspfResistor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float res);
|
||||
void rspfDrvrCap(const char *node1,
|
||||
const char *node2,
|
||||
float cap);
|
||||
void rspfDrvrCap1(const char *pin_name,
|
||||
const Pin *pin,
|
||||
float cap);
|
||||
void rspfLoadCap(const char *node1,
|
||||
const char *node2,
|
||||
float cap);
|
||||
void dspfCapacitor(const char *name,
|
||||
const char *node1,
|
||||
const char *node2,
|
||||
float cap);
|
||||
ParasiticNode *ensureDspfNode(const char *node_name);
|
||||
|
||||
bool reduce_dspf_;
|
||||
bool delete_reduced_dspf_;
|
||||
bool is_rspf_;
|
||||
Parasitic *parasitic_;
|
||||
Pin *rspf_drvr_pin_;
|
||||
Pin *rspf_load_pin_;
|
||||
SpfPinMap pin_node_map_;
|
||||
float rspf_c1_;
|
||||
float rspf_c2_;
|
||||
float rspf_rpi_;
|
||||
float rspf_c3_;
|
||||
float rspf_r3_;
|
||||
Parasitic *dspf_;
|
||||
const char *gnd_net_name_;
|
||||
|
||||
// spf_gnd_net is inserted into spf_node_map to save string compares.
|
||||
static const Pin *gnd_net_;
|
||||
static const Pin *rspf_subnode_;
|
||||
};
|
||||
|
||||
extern SpfReader *spf_reader;
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
// 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 <stdarg.h>
|
||||
#include "Machine.hh"
|
||||
#include "Zlib.hh"
|
||||
#include "Report.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Network.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "SpefNamespace.hh"
|
||||
#include "SpfSpefReader.hh"
|
||||
#include "Parasitics.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
SpfSpefReader::SpfSpefReader(const char *filename,
|
||||
gzFile stream,
|
||||
int line,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics) :
|
||||
filename_(filename),
|
||||
instance_(instance),
|
||||
ap_(ap),
|
||||
increment_(increment),
|
||||
pin_cap_included_(pin_cap_included),
|
||||
keep_coupling_caps_(keep_coupling_caps),
|
||||
reduce_to_(reduce_to),
|
||||
delete_after_reduce_(delete_after_reduce),
|
||||
op_cond_(op_cond),
|
||||
corner_(corner),
|
||||
cnst_min_max_(cnst_min_max),
|
||||
keep_device_names_(false),
|
||||
quiet_(quiet),
|
||||
stream_(stream),
|
||||
line_(line),
|
||||
// defaults
|
||||
divider_('\0'),
|
||||
delimiter_('\0'),
|
||||
bus_brkt_left_('\0'),
|
||||
bus_brkt_right_('\0'),
|
||||
net_(NULL),
|
||||
report_(report),
|
||||
network_(network),
|
||||
parasitics_(parasitics)
|
||||
{
|
||||
ap->setCouplingCapFactor(coupling_cap_factor);
|
||||
}
|
||||
|
||||
SpfSpefReader::~SpfSpefReader()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::setDivider(char divider)
|
||||
{
|
||||
divider_ = divider;
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::setDelimiter(char delimiter)
|
||||
{
|
||||
delimiter_ = delimiter;
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::setBusBrackets(char left, char right)
|
||||
{
|
||||
bus_brkt_left_ = left;
|
||||
bus_brkt_right_ = right;
|
||||
}
|
||||
|
||||
Instance *
|
||||
SpfSpefReader::findInstanceRelative(const char *name)
|
||||
{
|
||||
return network_->findInstanceRelative(instance_, name);
|
||||
}
|
||||
|
||||
Net *
|
||||
SpfSpefReader::findNetRelative(const char *name)
|
||||
{
|
||||
return network_->findNetRelative(instance_, name);
|
||||
}
|
||||
|
||||
Pin *
|
||||
SpfSpefReader::findPinRelative(const char *name)
|
||||
{
|
||||
return network_->findPinRelative(instance_, name);
|
||||
}
|
||||
|
||||
Pin *
|
||||
SpfSpefReader::findPortPinRelative(const char *name)
|
||||
{
|
||||
return network_->findPin(instance_, name);
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::getChars(char *buf,
|
||||
int &result,
|
||||
size_t max_size)
|
||||
{
|
||||
char *status = gzgets(stream_, buf, max_size);
|
||||
if (status == Z_NULL)
|
||||
result = 0; // YY_NULL
|
||||
else
|
||||
result = static_cast<int>(strlen(buf));
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::getChars(char *buf,
|
||||
size_t &result,
|
||||
size_t max_size)
|
||||
{
|
||||
char *status = gzgets(stream_, buf, max_size);
|
||||
if (status == Z_NULL)
|
||||
result = 0; // YY_NULL
|
||||
else
|
||||
result = strlen(buf);
|
||||
}
|
||||
|
||||
char *
|
||||
SpfSpefReader::translated(const char *token)
|
||||
{
|
||||
return spefToSta(token, divider_, network_->pathDivider(),
|
||||
network_->pathEscape());
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::incrLine()
|
||||
{
|
||||
line_++;
|
||||
}
|
||||
|
||||
void
|
||||
SpfSpefReader::warn(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
report_->vfileWarn(filename_, line_, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
// 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/>.
|
||||
|
||||
#ifndef STA_SPF_SPEF_READER_H
|
||||
#define STA_SPF_SPEF_READER_H
|
||||
|
||||
#include "Zlib.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "ParasiticsClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
class Report;
|
||||
class OperatingConditions;
|
||||
class MinMax;
|
||||
class Corner;
|
||||
|
||||
// Common to Spf and Spef readers.
|
||||
class SpfSpefReader
|
||||
{
|
||||
public:
|
||||
// Constraint min/max cnst_min_max and operating condition op_cond
|
||||
// are used for parasitic network reduction.
|
||||
SpfSpefReader(const char *filename,
|
||||
gzFile stream,
|
||||
int line,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool increment,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
float coupling_cap_factor,
|
||||
ReduceParasiticsTo reduce_to,
|
||||
bool delete_after_reduce,
|
||||
const OperatingConditions *op_cond,
|
||||
const Corner *corner,
|
||||
const MinMax *cnst_min_max,
|
||||
bool quiet,
|
||||
Report *report,
|
||||
Network *network,
|
||||
Parasitics *parasitics);
|
||||
virtual ~SpfSpefReader();
|
||||
char divider() const { return divider_; }
|
||||
void setDivider(char divider);
|
||||
char delimiter() const { return delimiter_; }
|
||||
void setDelimiter(char delimiter);
|
||||
void setBusBrackets(char left, char right);
|
||||
void incrLine();
|
||||
int line() const { return line_; }
|
||||
const char *filename() const { return filename_; }
|
||||
// flex YY_INPUT yy_n_chars arg changed definition from int to size_t,
|
||||
// so provide both forms.
|
||||
void getChars(char *buf,
|
||||
int &result,
|
||||
size_t max_size);
|
||||
void getChars(char *buf,
|
||||
size_t &result,
|
||||
size_t max_size);
|
||||
// Translate from spf/spef namespace to sta namespace.
|
||||
char *translated(const char *token);
|
||||
void warn(const char *fmt, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
|
||||
protected:
|
||||
Pin *findPinRelative(const char *name);
|
||||
Pin *findPortPinRelative(const char *name);
|
||||
Net *findNetRelative(const char *name);
|
||||
Instance *findInstanceRelative(const char *name);
|
||||
|
||||
const char *filename_;
|
||||
Instance *instance_;
|
||||
const ParasiticAnalysisPt *ap_;
|
||||
bool increment_;
|
||||
bool pin_cap_included_;
|
||||
bool keep_coupling_caps_;
|
||||
ReduceParasiticsTo reduce_to_;
|
||||
bool delete_after_reduce_;
|
||||
const OperatingConditions *op_cond_;
|
||||
const Corner *corner_;
|
||||
const MinMax *cnst_min_max_;
|
||||
// Normally no need to keep device names.
|
||||
bool keep_device_names_;
|
||||
bool quiet_;
|
||||
gzFile stream_;
|
||||
int line_;
|
||||
char divider_;
|
||||
char delimiter_;
|
||||
char bus_brkt_left_;
|
||||
char bus_brkt_right_;
|
||||
Net *net_;
|
||||
Report *report_;
|
||||
Network *network_;
|
||||
Parasitics *parasitics_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
@ -14,13 +14,21 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Parallax Static Timing Analyzer
|
||||
// Copyright (c) 2018, Parallax Software, Inc.
|
||||
// All rights reserved.
|
||||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2019, Parallax Software, Inc.
|
||||
//
|
||||
// No part of this document may be copied, transmitted or
|
||||
// disclosed in any form or fashion without the express
|
||||
// written consent of 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/>.
|
||||
|
||||
#ifndef STA_GENCLKS_H
|
||||
#define STA_GENCLKS_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue