copyright, rm obsolete files

This commit is contained in:
James Cherry 2019-03-23 15:56:23 -07:00
parent 601143cec3
commit 20ab0a1f23
11 changed files with 28 additions and 2062 deletions

View File

@ -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/>.

View File

@ -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

View File

@ -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

View File

@ -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]); }
%%

View File

@ -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:
'.'
{ $$ = '.'; }
| '/'
{ $$ = '/'; }
| '|'
{ $$ = '|'; }
| ':'
{ $$ = ':'; }
| '['
{ $$ = '['; }
| ']'
{ $$ = ']'; }
| '<'
{ $$ = '<'; }
| '>'
{ $$ = '>'; }
| '('
{ $$ = '('; }
| ')'
{ $$ = ')'; }
;
%%

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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