LibExpr/spef/saif c++ parsers
commit a686a6f77e555513adc40228471c1ad1af4646b3
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 18:45:44 2025 -0800
spef compiles
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 986a3a00c246a927c494066c56bb627e55da8692
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 18:45:32 2025 -0800
spef compiles
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit e8664d21c0b404a82967201c19a087c6680b7177
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 16:36:19 2025 -0800
saif compiles
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 496569018791bff19e57c534f29ac085520fc520
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 15:25:44 2025 -0800
mv bison error funcs to .yy
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit c1e7638840f94eb0baddee47507e607b000ab858
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 14:19:26 2025 -0800
parser cledanup
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 22bc72af46114ddb4fc5876655887ef1189f2195
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 14:19:06 2025 -0800
parser cleanup
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit caeedc4c9e2bf8e7a2f4aceb4ee4a5758efd1b36
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 12:52:55 2025 -0800
LibertyParser stack stream
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit e029a01c2fc5ba0ed336978c5853d49095d07d66
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 12:10:35 2025 -0800
bison 3.2 required
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 2ca9423a2d518f51fdee6c41d41348dbfd548bae
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 12:05:19 2025 -0800
LibertyExpr -> LibExpr
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit d64df413675c2978c0f24d5594cc201032233447
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 11:18:05 2025 -0800
LibertyExpr -> LibExpr
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 57cfbae240984bd7928862b1d6c3b1047ee5d71f
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 10:25:49 2025 -0800
comment
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 5249ac32d809ba30ce09437d61beaf4360bc2cd8
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 10:24:35 2025 -0800
parseError
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 8c5442007f99c06bfb16a496e00862353c82282c
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 10:11:46 2025 -0800
libecxpr parseError unused
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 67dacf60db2c0d7e3f7ceeae672b4bdaf1e039b7
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 10:09:39 2025 -0800
reader pvt includes
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 1d7097399b4242833bf5a478c903b5d98afe674b
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 09:33:37 2025 -0800
libexpr life
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit cc85e357463399291cb1e7d7b628e5dd356ac8a9
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Jan 31 09:21:12 2025 -0800
libexpr no location
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit e3ef17a746eb4e8822cce732250ae77261d53cf9
Author: James Cherry <cherry@parallaxsw.com>
Date: Thu Jan 30 22:15:50 2025 -0800
compiles
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 3a34874297a5c82930ee0bd131425bccf48526ce
Author: James Cherry <cherry@parallaxsw.com>
Date: Thu Jan 30 20:03:06 2025 -0800
libexpr parse
Signed-off-by: James Cherry <cherry@parallaxsw.com>
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
80d3ba306c
commit
398a22e97d
|
|
@ -101,8 +101,7 @@ set(STA_SOURCE
|
||||||
liberty/LeakagePower.cc
|
liberty/LeakagePower.cc
|
||||||
liberty/Liberty.cc
|
liberty/Liberty.cc
|
||||||
liberty/LibertyBuilder.cc
|
liberty/LibertyBuilder.cc
|
||||||
liberty/LibertyExpr.cc
|
liberty/LibExprReader.cc
|
||||||
liberty/LibertyExprPvt.hh
|
|
||||||
liberty/LibertyParser.cc
|
liberty/LibertyParser.cc
|
||||||
liberty/LibertyReader.cc
|
liberty/LibertyReader.cc
|
||||||
liberty/LibertyWriter.cc
|
liberty/LibertyWriter.cc
|
||||||
|
|
@ -271,61 +270,48 @@ set(STA_TCL_FILES
|
||||||
# Earlier versions of flex use 'register' declarations that are illegal in c++17.
|
# Earlier versions of flex use 'register' declarations that are illegal in c++17.
|
||||||
#find_package(FLEX 2.6.4)
|
#find_package(FLEX 2.6.4)
|
||||||
find_package(FLEX)
|
find_package(FLEX)
|
||||||
find_package(BISON)
|
find_package(BISON REQUIRED 3.2)
|
||||||
|
|
||||||
# Liberty scan/parse.
|
|
||||||
flex_target(LibertyLex ${STA_HOME}/liberty/LibertyLex.ll
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/LibertyLex.cc)
|
|
||||||
bison_target(LibertyParse ${STA_HOME}/liberty/LibertyParse.yy
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/LibertyParse.cc
|
|
||||||
# centos7 bison 3.0.4 < 3.3.0 uses parser_class_name instead of api.parsr.class
|
|
||||||
COMPILE_FLAGS "-Wno-deprecated")
|
|
||||||
add_flex_bison_dependency(LibertyLex LibertyParse)
|
|
||||||
|
|
||||||
# LibertyExpr scan/parse.
|
|
||||||
flex_target(LibertyExprLex ${STA_HOME}/liberty/LibertyExprLex.ll
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/LibertyExprLex.cc
|
|
||||||
COMPILE_FLAGS --prefix=LibertyExprLex_)
|
|
||||||
bison_target(LibertyExprParse ${STA_HOME}/liberty/LibertyExprParse.yy
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/LibertyExprParse.cc
|
|
||||||
COMPILE_FLAGS --name-prefix=LibertyExprParse_
|
|
||||||
)
|
|
||||||
add_flex_bison_dependency(LibertyExprLex LibertyExprParse)
|
|
||||||
|
|
||||||
# Spef scan/parse.
|
|
||||||
flex_target(SpefLex ${STA_HOME}/parasitics/SpefLex.ll ${CMAKE_CURRENT_BINARY_DIR}/SpefLex.cc
|
|
||||||
COMPILE_FLAGS --prefix=SpefLex_
|
|
||||||
)
|
|
||||||
bison_target(SpefParse ${STA_HOME}/parasitics/SpefParse.yy ${CMAKE_CURRENT_BINARY_DIR}/SpefParse.cc
|
|
||||||
COMPILE_FLAGS --name-prefix=SpefParse_
|
|
||||||
)
|
|
||||||
add_flex_bison_dependency(SpefLex SpefParse)
|
|
||||||
|
|
||||||
# Verilog scan/parse.
|
# Verilog scan/parse.
|
||||||
flex_target(VerilogLex ${STA_HOME}/verilog/VerilogLex.ll
|
flex_target(VerilogLex ${STA_HOME}/verilog/VerilogLex.ll
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VerilogLex.cc)
|
${CMAKE_CURRENT_BINARY_DIR}/VerilogLex.cc)
|
||||||
bison_target(VerilogParse ${STA_HOME}/verilog/VerilogParse.yy
|
bison_target(VerilogParse ${STA_HOME}/verilog/VerilogParse.yy
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VerilogParse.cc
|
${CMAKE_CURRENT_BINARY_DIR}/VerilogParse.cc)
|
||||||
# centos7 bison 3.0.4 < 3.3.0 uses parser_class_name instead of api.parsr.class
|
|
||||||
COMPILE_FLAGS "-Wno-deprecated")
|
|
||||||
add_flex_bison_dependency(VerilogLex VerilogParse)
|
add_flex_bison_dependency(VerilogLex VerilogParse)
|
||||||
|
|
||||||
|
# Liberty scan/parse.
|
||||||
|
flex_target(LibertyLex ${STA_HOME}/liberty/LibertyLex.ll
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/LibertyLex.cc)
|
||||||
|
bison_target(LibertyParse ${STA_HOME}/liberty/LibertyParse.yy
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/LibertyParse.cc)
|
||||||
|
add_flex_bison_dependency(LibertyLex LibertyParse)
|
||||||
|
|
||||||
|
# Liberty Expr scan/parse.
|
||||||
|
flex_target(LibExprLex ${STA_HOME}/liberty/LibExprLex.ll
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/LibExprLex.cc)
|
||||||
|
bison_target(LibExprParse ${STA_HOME}/liberty/LibExprParse.yy
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/LibExprParse.cc)
|
||||||
|
add_flex_bison_dependency(LibExprLex LibExprParse)
|
||||||
|
|
||||||
# Sdf scan/parse.
|
# Sdf scan/parse.
|
||||||
flex_target(SdfLex ${STA_HOME}/sdf/SdfLex.ll
|
flex_target(SdfLex ${STA_HOME}/sdf/SdfLex.ll
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/SdfLex.cc)
|
${CMAKE_CURRENT_BINARY_DIR}/SdfLex.cc)
|
||||||
bison_target(SdfParse ${STA_HOME}/sdf/SdfParse.yy
|
bison_target(SdfParse ${STA_HOME}/sdf/SdfParse.yy
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/SdfParse.cc
|
${CMAKE_CURRENT_BINARY_DIR}/SdfParse.cc)
|
||||||
# centos7 bison 3.0.4 < 3.3.0 uses parser_class_name instead of api.parsr.class
|
|
||||||
COMPILE_FLAGS "-Wno-deprecated")
|
|
||||||
add_flex_bison_dependency(SdfLex SdfParse)
|
add_flex_bison_dependency(SdfLex SdfParse)
|
||||||
|
|
||||||
|
# Spef scan/parse.
|
||||||
|
flex_target(SpefLex ${STA_HOME}/parasitics/SpefLex.ll
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/SpefLex.cc)
|
||||||
|
bison_target(SpefParse ${STA_HOME}/parasitics/SpefParse.yy
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/SpefParse.cc)
|
||||||
|
add_flex_bison_dependency(SpefLex SpefParse)
|
||||||
|
|
||||||
# Saif scan/parse.
|
# Saif scan/parse.
|
||||||
flex_target(SaifLex ${STA_HOME}/power/SaifLex.ll ${CMAKE_CURRENT_BINARY_DIR}/SaifLex.cc
|
flex_target(SaifLex ${STA_HOME}/power/SaifLex.ll
|
||||||
COMPILE_FLAGS --prefix=SaifLex_
|
${CMAKE_CURRENT_BINARY_DIR}/SaifLex.cc)
|
||||||
)
|
bison_target(SaifParse ${STA_HOME}/power/SaifParse.yy
|
||||||
bison_target(SaifParse ${STA_HOME}/power/SaifParse.yy ${CMAKE_CURRENT_BINARY_DIR}/SaifParse.cc
|
${CMAKE_CURRENT_BINARY_DIR}/SaifParse.cc)
|
||||||
COMPILE_FLAGS --name-prefix=SaifParse_
|
|
||||||
)
|
|
||||||
add_flex_bison_dependency(SaifLex SaifParse)
|
add_flex_bison_dependency(SaifLex SaifParse)
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
@ -497,8 +483,8 @@ target_sources(OpenSTA
|
||||||
|
|
||||||
${STA_TCL_INIT}
|
${STA_TCL_INIT}
|
||||||
|
|
||||||
${FLEX_LibertyExprLex_OUTPUTS}
|
${FLEX_LibExprLex_OUTPUTS}
|
||||||
${BISON_LibertyExprParse_OUTPUTS}
|
${BISON_LibExprParse_OUTPUTS}
|
||||||
${FLEX_LibertyLex_OUTPUTS}
|
${FLEX_LibertyLex_OUTPUTS}
|
||||||
${BISON_LibertyParse_OUTPUTS}
|
${BISON_LibertyParse_OUTPUTS}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
%{
|
%{
|
||||||
|
|
||||||
// OpenSTA, Static Timing Analyzer
|
// OpenSTA, Static Timing Analyzer
|
||||||
// Copyright (c) 2025, Parallax Software, Inc.
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
//
|
//
|
||||||
|
|
@ -29,31 +28,31 @@
|
||||||
#include "util/FlexDisableRegister.hh"
|
#include "util/FlexDisableRegister.hh"
|
||||||
#include "Debug.hh"
|
#include "Debug.hh"
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "liberty/LibertyExprPvt.hh"
|
#include "liberty/LibExprReaderPvt.hh"
|
||||||
|
#include "liberty/LibExprReader.hh"
|
||||||
|
#include "liberty/LibExprScanner.hh"
|
||||||
|
|
||||||
using sta::libexpr_parser;
|
|
||||||
using sta::stringCopy;
|
using sta::stringCopy;
|
||||||
using sta::FuncExpr;
|
using sta::FuncExpr;
|
||||||
|
|
||||||
#include "LibertyExprParse.hh"
|
#include "LibExprParse.hh"
|
||||||
|
|
||||||
#define YY_NO_INPUT
|
#undef YY_DECL
|
||||||
|
#define YY_DECL \
|
||||||
|
int \
|
||||||
|
sta::LibExprScanner::lex(sta::LibExprParse::semantic_type *const yylval)
|
||||||
|
|
||||||
#define YY_INPUT(buf,result,max_size) \
|
typedef sta::LibExprParse::token token;
|
||||||
result = libexpr_parser->copyInput(buf, max_size)
|
|
||||||
|
|
||||||
void
|
|
||||||
libertyExprFlushBuffer()
|
|
||||||
{
|
|
||||||
YY_FLUSH_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
/* %option debug */
|
%option c++
|
||||||
|
%option yyclass="sta::LibExprScanner"
|
||||||
|
%option prefix="LibExpr"
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option nounput
|
|
||||||
%option never-interactive
|
%option never-interactive
|
||||||
|
%option stack
|
||||||
|
/* %option debug */
|
||||||
|
|
||||||
%x ESCAPED_STRING
|
%x ESCAPED_STRING
|
||||||
|
|
||||||
|
|
@ -67,28 +66,28 @@ EOL \r?\n
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
{OP}|{PAREN} { return ((int) LibertyExprLex_text[0]); }
|
{OP}|{PAREN} { return ((int) yytext[0]); }
|
||||||
|
|
||||||
{ESCAPE}{EOL} { /* I doubt that escaped returns get thru the parser */ }
|
{ESCAPE}{EOL} { /* I doubt that escaped returns get thru the parser */ }
|
||||||
|
|
||||||
{ESCAPE}{QUOTE} { BEGIN(ESCAPED_STRING); libexpr_parser->tokenErase(); }
|
{ESCAPE}{QUOTE} { BEGIN(ESCAPED_STRING); token_.clear(); }
|
||||||
|
|
||||||
<ESCAPED_STRING>. { libexpr_parser->tokenAppend(LibertyExprLex_text[0]); }
|
<ESCAPED_STRING>. { token_ += yytext[0]; }
|
||||||
|
|
||||||
<ESCAPED_STRING>{ESCAPE}{QUOTE} {
|
<ESCAPED_STRING>{ESCAPE}{QUOTE} {
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
LibertyExprParse_lval.string = libexpr_parser->tokenCopy();
|
yylval->string = stringCopy(token_.c_str());
|
||||||
return PORT;
|
return token::PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
{PORT} {
|
{PORT} {
|
||||||
LibertyExprParse_lval.string = stringCopy(LibertyExprLex_text);
|
yylval->string = stringCopy(yytext);
|
||||||
return PORT;
|
return token::PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
{BLANK} {}
|
{BLANK} {}
|
||||||
|
|
||||||
/* Send out of bound characters to parser. */
|
/* Send out of bound characters to parser. */
|
||||||
. { return (int) LibertyExprLex_text[0]; }
|
. { return (int) yytext[0]; }
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
%{
|
|
||||||
|
|
||||||
// OpenSTA, Static Timing Analyzer
|
// OpenSTA, Static Timing Analyzer
|
||||||
// Copyright (c) 2025, Parallax Software, Inc.
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
//
|
//
|
||||||
|
|
@ -26,15 +24,35 @@
|
||||||
|
|
||||||
// Liberty function expression parser.
|
// Liberty function expression parser.
|
||||||
|
|
||||||
|
%{
|
||||||
#include "FuncExpr.hh"
|
#include "FuncExpr.hh"
|
||||||
#include "liberty/LibertyExpr.hh"
|
#include "liberty/LibExprReader.hh"
|
||||||
#include "liberty/LibertyExprPvt.hh"
|
#include "liberty/LibExprReaderPvt.hh"
|
||||||
|
#include "liberty/LibExprScanner.hh"
|
||||||
|
|
||||||
int LibertyExprLex_lex();
|
#undef yylex
|
||||||
#define LibertyExprParse_lex LibertyExprLex_lex
|
#define yylex scanner->lex
|
||||||
|
|
||||||
|
// warning: variable 'yynerrs_' set but not used
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
|
|
||||||
|
void
|
||||||
|
sta::LibExprParse::error(const string &msg)
|
||||||
|
{
|
||||||
|
reader->parseError(msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%require "3.2"
|
||||||
|
%skeleton "lalr1.cc"
|
||||||
|
%debug
|
||||||
|
%define api.namespace {sta}
|
||||||
|
%define parse.assert
|
||||||
|
%parse-param{LibExprScanner *scanner}
|
||||||
|
%parse-param{LibExprReader *reader}
|
||||||
|
%define api.parser.class {LibExprParse}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
int int_val;
|
int int_val;
|
||||||
const char *string;
|
const char *string;
|
||||||
|
|
@ -50,18 +68,15 @@ int LibertyExprLex_lex();
|
||||||
%type <string> PORT
|
%type <string> PORT
|
||||||
%type <expr> expr terminal terminal_expr implicit_and
|
%type <expr> expr terminal terminal_expr implicit_and
|
||||||
|
|
||||||
%{
|
|
||||||
%}
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
result_expr:
|
result_expr:
|
||||||
expr { sta::libexpr_parser->setResult($1); }
|
expr { reader->setResult($1); }
|
||||||
| expr ';'{ sta::libexpr_parser->setResult($1); }
|
| expr ';'{ reader->setResult($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
terminal:
|
terminal:
|
||||||
PORT { $$ = sta::libexpr_parser->makeFuncExprPort($1); }
|
PORT { $$ = reader->makeFuncExprPort($1); }
|
||||||
| '0' { $$ = sta::FuncExpr::makeZero(); }
|
| '0' { $$ = sta::FuncExpr::makeZero(); }
|
||||||
| '1' { $$ = sta::FuncExpr::makeOne(); }
|
| '1' { $$ = sta::FuncExpr::makeOne(); }
|
||||||
| '(' expr ')' { $$ = $2; }
|
| '(' expr ')' { $$ = $2; }
|
||||||
|
|
@ -69,25 +84,25 @@ terminal:
|
||||||
|
|
||||||
terminal_expr:
|
terminal_expr:
|
||||||
terminal
|
terminal
|
||||||
| '!' terminal { $$ = sta::libexpr_parser->makeFuncExprNot($2); }
|
| '!' terminal { $$ = reader->makeFuncExprNot($2); }
|
||||||
| terminal '\'' { $$ = sta::libexpr_parser->makeFuncExprNot($1); }
|
| terminal '\'' { $$ = reader->makeFuncExprNot($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
implicit_and:
|
implicit_and:
|
||||||
terminal_expr terminal_expr
|
terminal_expr terminal_expr
|
||||||
{ $$ = sta::libexpr_parser->makeFuncExprAnd($1, $2); }
|
{ $$ = reader->makeFuncExprAnd($1, $2); }
|
||||||
| implicit_and terminal_expr
|
| implicit_and terminal_expr
|
||||||
{ $$ = sta::libexpr_parser->makeFuncExprAnd($1, $2); }
|
{ $$ = reader->makeFuncExprAnd($1, $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expr:
|
expr:
|
||||||
terminal_expr
|
terminal_expr
|
||||||
| implicit_and
|
| implicit_and
|
||||||
| expr '+' expr { $$ = sta::libexpr_parser->makeFuncExprOr($1, $3); }
|
| expr '+' expr { $$ = reader->makeFuncExprOr($1, $3); }
|
||||||
| expr '|' expr { $$ = sta::libexpr_parser->makeFuncExprOr($1, $3); }
|
| expr '|' expr { $$ = reader->makeFuncExprOr($1, $3); }
|
||||||
| expr '*' expr { $$ = sta::libexpr_parser->makeFuncExprAnd($1, $3); }
|
| expr '*' expr { $$ = reader->makeFuncExprAnd($1, $3); }
|
||||||
| expr '&' expr { $$ = sta::libexpr_parser->makeFuncExprAnd($1, $3); }
|
| expr '&' expr { $$ = reader->makeFuncExprAnd($1, $3); }
|
||||||
| expr '^' expr { $$ = sta::libexpr_parser->makeFuncExprXor($1, $3); }
|
| expr '^' expr { $$ = reader->makeFuncExprXor($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
@ -24,19 +24,17 @@
|
||||||
|
|
||||||
#include "FuncExpr.hh"
|
#include "FuncExpr.hh"
|
||||||
|
|
||||||
#include <algorithm> // min
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "Report.hh"
|
#include "Report.hh"
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "Liberty.hh"
|
#include "Liberty.hh"
|
||||||
#include "LibertyExprPvt.hh"
|
#include "LibExprReaderPvt.hh"
|
||||||
|
#include "LibExprScanner.hh"
|
||||||
extern int
|
|
||||||
LibertyExprParse_parse();
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
LibExprParser *libexpr_parser;
|
|
||||||
|
|
||||||
FuncExpr *
|
FuncExpr *
|
||||||
parseFuncExpr(const char *func,
|
parseFuncExpr(const char *func,
|
||||||
LibertyCell *cell,
|
LibertyCell *cell,
|
||||||
|
|
@ -44,18 +42,20 @@ parseFuncExpr(const char *func,
|
||||||
Report *report)
|
Report *report)
|
||||||
{
|
{
|
||||||
if (func != nullptr && func[0] != '\0') {
|
if (func != nullptr && func[0] != '\0') {
|
||||||
LibExprParser parser(func, cell, error_msg, report);
|
string func1(func);
|
||||||
libexpr_parser = &parser;
|
std::istringstream stream(func);
|
||||||
LibertyExprParse_parse();
|
LibExprReader reader(func, cell, error_msg, report);
|
||||||
FuncExpr *expr = parser.result();
|
LibExprScanner scanner(stream);
|
||||||
libexpr_parser = nullptr;
|
LibExprParse parser(&scanner, &reader);
|
||||||
|
parser.parse();
|
||||||
|
FuncExpr *expr = reader.result();
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibExprParser::LibExprParser(const char *func,
|
LibExprReader::LibExprReader(const char *func,
|
||||||
LibertyCell *cell,
|
LibertyCell *cell,
|
||||||
const char *error_msg,
|
const char *error_msg,
|
||||||
Report *report) :
|
Report *report) :
|
||||||
|
|
@ -63,24 +63,17 @@ LibExprParser::LibExprParser(const char *func,
|
||||||
cell_(cell),
|
cell_(cell),
|
||||||
error_msg_(error_msg),
|
error_msg_(error_msg),
|
||||||
report_(report),
|
report_(report),
|
||||||
result_(nullptr),
|
result_(nullptr)
|
||||||
token_length_(100),
|
|
||||||
token_(new char[token_length_]),
|
|
||||||
token_next_(token_)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LibExprParser::~LibExprParser()
|
// defined in LibertyReader.cc
|
||||||
{
|
|
||||||
stringDelete(token_);
|
|
||||||
}
|
|
||||||
|
|
||||||
LibertyPort *
|
LibertyPort *
|
||||||
libertyReaderFindPort(LibertyCell *cell,
|
libertyReaderFindPort(LibertyCell *cell,
|
||||||
const char *port_name);
|
const char *port_name);
|
||||||
|
|
||||||
FuncExpr *
|
FuncExpr *
|
||||||
LibExprParser::makeFuncExprPort(const char *port_name)
|
LibExprReader::makeFuncExprPort(const char *port_name)
|
||||||
{
|
{
|
||||||
FuncExpr *expr = nullptr;
|
FuncExpr *expr = nullptr;
|
||||||
LibertyPort *port = libertyReaderFindPort(cell_, port_name);
|
LibertyPort *port = libertyReaderFindPort(cell_, port_name);
|
||||||
|
|
@ -94,7 +87,7 @@ LibExprParser::makeFuncExprPort(const char *port_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncExpr *
|
FuncExpr *
|
||||||
LibExprParser::makeFuncExprNot(FuncExpr *arg)
|
LibExprReader::makeFuncExprNot(FuncExpr *arg)
|
||||||
{
|
{
|
||||||
if (arg)
|
if (arg)
|
||||||
return FuncExpr::makeNot(arg);
|
return FuncExpr::makeNot(arg);
|
||||||
|
|
@ -103,7 +96,7 @@ LibExprParser::makeFuncExprNot(FuncExpr *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncExpr *
|
FuncExpr *
|
||||||
LibExprParser::makeFuncExprXor(FuncExpr *arg1,
|
LibExprReader::makeFuncExprXor(FuncExpr *arg1,
|
||||||
FuncExpr *arg2)
|
FuncExpr *arg2)
|
||||||
{
|
{
|
||||||
if (arg1 && arg2)
|
if (arg1 && arg2)
|
||||||
|
|
@ -113,7 +106,7 @@ LibExprParser::makeFuncExprXor(FuncExpr *arg1,
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncExpr *
|
FuncExpr *
|
||||||
LibExprParser::makeFuncExprAnd(FuncExpr *arg1,
|
LibExprReader::makeFuncExprAnd(FuncExpr *arg1,
|
||||||
FuncExpr *arg2)
|
FuncExpr *arg2)
|
||||||
{
|
{
|
||||||
if (arg1 && arg2)
|
if (arg1 && arg2)
|
||||||
|
|
@ -123,7 +116,7 @@ LibExprParser::makeFuncExprAnd(FuncExpr *arg1,
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncExpr *
|
FuncExpr *
|
||||||
LibExprParser::makeFuncExprOr(FuncExpr *arg1,
|
LibExprReader::makeFuncExprOr(FuncExpr *arg1,
|
||||||
FuncExpr *arg2)
|
FuncExpr *arg2)
|
||||||
{
|
{
|
||||||
if (arg1 && arg2)
|
if (arg1 && arg2)
|
||||||
|
|
@ -133,65 +126,22 @@ LibExprParser::makeFuncExprOr(FuncExpr *arg1,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LibExprParser::setResult(FuncExpr *result)
|
LibExprReader::setResult(FuncExpr *result)
|
||||||
{
|
{
|
||||||
result_ = result;
|
result_ = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
|
||||||
LibExprParser::copyInput(char *buf,
|
|
||||||
size_t max_size)
|
|
||||||
{
|
|
||||||
strncpy(buf, func_, max_size);
|
|
||||||
int count = strlen(buf);
|
|
||||||
func_ += count;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
LibExprParser::tokenCopy()
|
|
||||||
{
|
|
||||||
return stringCopy(token_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LibExprParser::tokenErase()
|
LibExprReader::parseError(const char *msg)
|
||||||
{
|
|
||||||
token_next_ = token_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LibExprParser::tokenAppend(char ch)
|
|
||||||
{
|
|
||||||
if (token_next_ + 1 - token_ >= static_cast<signed int>(token_length_)) {
|
|
||||||
size_t index = token_next_ - token_;
|
|
||||||
token_length_ *= 2;
|
|
||||||
char *prev_token = token_;
|
|
||||||
token_ = new char[token_length_];
|
|
||||||
strcpy(token_, prev_token);
|
|
||||||
stringDelete(prev_token);
|
|
||||||
token_next_ = &token_[index];
|
|
||||||
}
|
|
||||||
*token_next_++ = ch;
|
|
||||||
// Make sure the token is always terminated.
|
|
||||||
*token_next_ = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LibExprParser::parseError(const char *msg)
|
|
||||||
{
|
{
|
||||||
report_->error(1131, "%s %s.", error_msg_, msg);
|
report_->error(1131, "%s %s.", error_msg_, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Global namespace
|
|
||||||
|
|
||||||
int
|
LibExprScanner::LibExprScanner(std::istringstream &stream) :
|
||||||
LibertyExprParse_error(const char *msg)
|
yyFlexLexer(&stream)
|
||||||
{
|
{
|
||||||
libertyExprFlushBuffer();
|
|
||||||
sta::libexpr_parser->parseError(msg);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -29,15 +29,15 @@ namespace sta {
|
||||||
class Report;
|
class Report;
|
||||||
class LibertyCell;
|
class LibertyCell;
|
||||||
class FuncExpr;
|
class FuncExpr;
|
||||||
|
class LibExprScanner;
|
||||||
|
|
||||||
class LibExprParser
|
class LibExprReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LibExprParser(const char *func,
|
LibExprReader(const char *func,
|
||||||
LibertyCell *cell,
|
LibertyCell *cell,
|
||||||
const char *error_msg,
|
const char *error_msg,
|
||||||
Report *report);
|
Report *report);
|
||||||
~LibExprParser();
|
|
||||||
FuncExpr *makeFuncExprPort(const char *port_name);
|
FuncExpr *makeFuncExprPort(const char *port_name);
|
||||||
FuncExpr *makeFuncExprOr(FuncExpr *arg1,
|
FuncExpr *makeFuncExprOr(FuncExpr *arg1,
|
||||||
FuncExpr *arg2);
|
FuncExpr *arg2);
|
||||||
|
|
@ -51,11 +51,7 @@ public:
|
||||||
void parseError(const char *msg);
|
void parseError(const char *msg);
|
||||||
size_t copyInput(char *buf,
|
size_t copyInput(char *buf,
|
||||||
size_t max_size);
|
size_t max_size);
|
||||||
void tokenStart();
|
Report *report() const { return report_; }
|
||||||
const char *token();
|
|
||||||
char *tokenCopy();
|
|
||||||
void tokenErase();
|
|
||||||
void tokenAppend(char ch);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *func_;
|
const char *func_;
|
||||||
|
|
@ -63,18 +59,6 @@ private:
|
||||||
const char *error_msg_;
|
const char *error_msg_;
|
||||||
Report *report_;
|
Report *report_;
|
||||||
FuncExpr *result_;
|
FuncExpr *result_;
|
||||||
size_t token_length_;
|
|
||||||
char *token_;
|
|
||||||
char *token_next_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern LibExprParser *libexpr_parser;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Global namespace
|
|
||||||
|
|
||||||
void
|
|
||||||
libertyExprFlushBuffer();
|
|
||||||
int
|
|
||||||
LibertyExprParse_error(const char *msg);
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2025, 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/>.
|
||||||
|
//
|
||||||
|
// The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software.
|
||||||
|
//
|
||||||
|
// Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "LibExprParse.hh"
|
||||||
|
|
||||||
|
#ifndef __FLEX_LEXER_H
|
||||||
|
#undef yyFlexLexer
|
||||||
|
#define yyFlexLexer LibExprFlexLexer
|
||||||
|
#include <FlexLexer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
class Report;
|
||||||
|
class LibExprParse;
|
||||||
|
|
||||||
|
class LibExprScanner : public LibExprFlexLexer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LibExprScanner(std::istringstream &stream);
|
||||||
|
virtual ~LibExprScanner() {}
|
||||||
|
|
||||||
|
virtual int lex(LibExprParse::semantic_type *const yylval);
|
||||||
|
// YY_DECL defined in LibertyLex.ll
|
||||||
|
// Method body created by flex in LibertyLex.cc
|
||||||
|
|
||||||
|
// Get rid of override virtual function warning.
|
||||||
|
using FlexLexer::yylex;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Report *report_;
|
||||||
|
string token_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
%{
|
%{
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "StringUtil.hh"
|
#include "Report.hh"
|
||||||
#include "liberty/LibertyParser.hh"
|
#include "liberty/LibertyParser.hh"
|
||||||
#include "liberty/LibertyScanner.hh"
|
#include "liberty/LibertyScanner.hh"
|
||||||
|
|
||||||
|
|
@ -36,6 +36,15 @@
|
||||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
|
|
||||||
#define loc_line(loc) loc.begin.line
|
#define loc_line(loc) loc.begin.line
|
||||||
|
|
||||||
|
void
|
||||||
|
sta::LibertyParse::error(const location_type &loc,
|
||||||
|
const string &msg)
|
||||||
|
{
|
||||||
|
reader->report()->fileError(164, reader->filename().c_str(),
|
||||||
|
loc.begin.line, "%s", msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%require "3.2"
|
%require "3.2"
|
||||||
|
|
@ -47,11 +56,7 @@
|
||||||
%define parse.assert
|
%define parse.assert
|
||||||
%parse-param { LibertyScanner *scanner }
|
%parse-param { LibertyScanner *scanner }
|
||||||
%parse-param { LibertyParser *reader }
|
%parse-param { LibertyParser *reader }
|
||||||
|
%define api.parser.class {LibertyParse}
|
||||||
// bison 3.0.4 for centos7
|
|
||||||
%define parser_class_name {LibertyParse}
|
|
||||||
// bison 3.3.2
|
|
||||||
//%define api.parser.class {LibertyParse}
|
|
||||||
|
|
||||||
%expect 2
|
%expect 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,18 +41,15 @@ parseLibertyFile(const char *filename,
|
||||||
LibertyGroupVisitor *library_visitor,
|
LibertyGroupVisitor *library_visitor,
|
||||||
Report *report)
|
Report *report)
|
||||||
{
|
{
|
||||||
std::istream *stream = new gzstream::igzstream(filename);
|
gzstream::igzstream stream(filename);
|
||||||
if (stream->good()) {
|
if (stream.is_open()) {
|
||||||
LibertyParser reader(filename, library_visitor, report);
|
LibertyParser reader(filename, library_visitor, report);
|
||||||
LibertyScanner scanner(stream, filename, &reader, report);
|
LibertyScanner scanner(&stream, filename, &reader, report);
|
||||||
LibertyParse parser(&scanner, &reader);
|
LibertyParse parser(&scanner, &reader);
|
||||||
parser.parse();
|
parser.parse();
|
||||||
delete stream;
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
delete stream;
|
|
||||||
throw FileNotReadable(filename);
|
throw FileNotReadable(filename);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyParser::LibertyParser(const char *filename,
|
LibertyParser::LibertyParser(const char *filename,
|
||||||
|
|
@ -567,12 +564,4 @@ LibertyScanner::error(const char *msg)
|
||||||
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
LibertyParse::error(const location_type &loc,
|
|
||||||
const string &msg)
|
|
||||||
{
|
|
||||||
reader->report()->fileError(164, reader->filename().c_str(),
|
|
||||||
loc.begin.line, "%s", msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#include "LinearModel.hh"
|
#include "LinearModel.hh"
|
||||||
#include "Wireload.hh"
|
#include "Wireload.hh"
|
||||||
#include "EquivCells.hh"
|
#include "EquivCells.hh"
|
||||||
#include "LibertyExpr.hh"
|
#include "LibExprReader.hh"
|
||||||
#include "Liberty.hh"
|
#include "Liberty.hh"
|
||||||
#include "LibertyBuilder.hh"
|
#include "LibertyBuilder.hh"
|
||||||
#include "LibertyReaderPvt.hh"
|
#include "LibertyReaderPvt.hh"
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,17 @@
|
||||||
#include "Map.hh"
|
#include "Map.hh"
|
||||||
#include "StringSeq.hh"
|
#include "StringSeq.hh"
|
||||||
#include "MinMax.hh"
|
#include "MinMax.hh"
|
||||||
|
#include "NetworkClass.hh"
|
||||||
#include "Transition.hh"
|
#include "Transition.hh"
|
||||||
#include "TimingArc.hh"
|
#include "TimingArc.hh"
|
||||||
#include "InternalPower.hh"
|
#include "InternalPower.hh"
|
||||||
#include "LeakagePower.hh"
|
#include "LeakagePower.hh"
|
||||||
#include "Liberty.hh"
|
#include "Liberty.hh"
|
||||||
#include "Sequential.hh"
|
#include "Sequential.hh"
|
||||||
|
#include "TableModel.hh"
|
||||||
#include "LibertyParser.hh"
|
#include "LibertyParser.hh"
|
||||||
#include "LibertyReader.hh"
|
#include "LibertyReader.hh"
|
||||||
#include "NetworkClass.hh"
|
#include "LibertyBuilder.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -494,6 +496,8 @@ public:
|
||||||
void endCcsn(LibertyGroup *group);
|
void endCcsn(LibertyGroup *group);
|
||||||
void beginEcsmWaveform(LibertyGroup *group);
|
void beginEcsmWaveform(LibertyGroup *group);
|
||||||
void endEcsmWaveform(LibertyGroup *group);
|
void endEcsmWaveform(LibertyGroup *group);
|
||||||
|
LibertyPort *findPort(LibertyCell *cell,
|
||||||
|
const char *port_name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TimingModel *makeScalarCheckModel(float value,
|
TimingModel *makeScalarCheckModel(float value,
|
||||||
|
|
@ -519,8 +523,6 @@ protected:
|
||||||
StdStringSeq parseTokenList(const char *token_str,
|
StdStringSeq parseTokenList(const char *token_str,
|
||||||
const char separator);
|
const char separator);
|
||||||
LibertyPort *findPort(const char *port_name);
|
LibertyPort *findPort(const char *port_name);
|
||||||
LibertyPort *findPort(LibertyCell *cell,
|
|
||||||
const char *port_name);
|
|
||||||
float defaultCap(LibertyPort *port);
|
float defaultCap(LibertyPort *port);
|
||||||
virtual void visitVariable(LibertyVariable *var);
|
virtual void visitVariable(LibertyVariable *var);
|
||||||
void visitPorts(std::function<void (LibertyPort *port)> func);
|
void visitPorts(std::function<void (LibertyPort *port)> func);
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "LibertyLocation.hh"
|
||||||
|
#include "LibertyParse.hh"
|
||||||
|
|
||||||
#ifndef __FLEX_LEXER_H
|
#ifndef __FLEX_LEXER_H
|
||||||
#undef yyFlexLexer
|
#undef yyFlexLexer
|
||||||
#define yyFlexLexer LibertyFlexLexer
|
#define yyFlexLexer LibertyFlexLexer
|
||||||
#include <FlexLexer.h>
|
#include <FlexLexer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "LibertyLocation.hh"
|
|
||||||
#include "LibertyParse.hh"
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
class Report;
|
class Report;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
%{
|
%{
|
||||||
|
|
||||||
// OpenSTA, Static Timing Analyzer
|
// OpenSTA, Static Timing Analyzer
|
||||||
// Copyright (c) 2025, Parallax Software, Inc.
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
//
|
//
|
||||||
|
|
@ -31,30 +30,28 @@
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "parasitics/SpefReaderPvt.hh"
|
#include "parasitics/SpefReaderPvt.hh"
|
||||||
#include "SpefParse.hh"
|
#include "SpefParse.hh"
|
||||||
|
#include "parasitics/SpefScanner.hh"
|
||||||
|
|
||||||
#define YY_NO_INPUT
|
#undef YY_DECL
|
||||||
|
#define YY_DECL \
|
||||||
|
int \
|
||||||
|
sta::SpefScanner::lex(sta::SpefParse::semantic_type *const yylval, \
|
||||||
|
sta::SpefParse::location_type *loc)
|
||||||
|
|
||||||
static std::string spef_token;
|
// update location on matching
|
||||||
|
#define YY_USER_ACTION loc->step(); loc->columns(yyleng);
|
||||||
void
|
|
||||||
spefFlushBuffer()
|
|
||||||
{
|
|
||||||
YY_FLUSH_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the start condition to INITIAL.
|
|
||||||
void
|
|
||||||
spefResetScanner()
|
|
||||||
{
|
|
||||||
BEGIN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
typedef sta::SpefParse::token token;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
/* %option debug */
|
%option c++
|
||||||
|
%option yyclass="sta::SpefScanner"
|
||||||
|
%option prefix="Spef"
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option nounput
|
|
||||||
%option never-interactive
|
%option never-interactive
|
||||||
|
%option stack
|
||||||
|
%option yylineno
|
||||||
|
/* %option debug */
|
||||||
|
|
||||||
%x COMMENT
|
%x COMMENT
|
||||||
%x QUOTE
|
%x QUOTE
|
||||||
|
|
@ -93,123 +90,117 @@ INDEX "*"{POS_INTEGER}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
"*BUS_DELIMITER" { return BUS_DELIMITER; }
|
"*BUS_DELIMITER" { return token::BUS_DELIMITER; }
|
||||||
"*C2_R1_C1" { return C2_R1_C1; }
|
"*C2_R1_C1" { return token::C2_R1_C1; }
|
||||||
"*C" { return KW_C; }
|
"*C" { return token::KW_C; }
|
||||||
"*CAP" { return CAP; }
|
"*CAP" { return token::CAP; }
|
||||||
"*CELL" { return CELL; }
|
"*CELL" { return token::CELL; }
|
||||||
"*CONN" { return CONN; }
|
"*CONN" { return token::CONN; }
|
||||||
"*C_UNIT" { return C_UNIT; }
|
"*C_UNIT" { return token::C_UNIT; }
|
||||||
"*SPEF" { return SPEF; }
|
"*SPEF" { return token::SPEF; }
|
||||||
"*DATE" { return DATE; }
|
"*DATE" { return token::DATE; }
|
||||||
"*DEFINE" { return DEFINE; }
|
"*DEFINE" { return token::DEFINE; }
|
||||||
"*DELIMITER" { return DELIMITER; }
|
"*DELIMITER" { return token::DELIMITER; }
|
||||||
"*DESIGN" { return DESIGN; }
|
"*DESIGN" { return token::DESIGN; }
|
||||||
"*DESIGN_FLOW" { return DESIGN_FLOW; }
|
"*DESIGN_FLOW" { return token::DESIGN_FLOW; }
|
||||||
"*DIVIDER" { return DIVIDER; }
|
"*DIVIDER" { return token::DIVIDER; }
|
||||||
"*DRIVER" { return DRIVER; }
|
"*DRIVER" { return token::DRIVER; }
|
||||||
"*D_NET" { return D_NET; }
|
"*D_NET" { return token::D_NET; }
|
||||||
"*D_PNET" { return D_PNET; }
|
"*D_PNET" { return token::D_PNET; }
|
||||||
"*D" { return KW_D; }
|
"*D" { return token::KW_D; }
|
||||||
"*END" { return END; }
|
"*END" { return token::END; }
|
||||||
"*GROUND_NETS" { return GROUND_NETS; }
|
"*GROUND_NETS" { return token::GROUND_NETS; }
|
||||||
"*INDUC" { return INDUC; }
|
"*INDUC" { return token::INDUC; }
|
||||||
"*I" { return KW_I; }
|
"*I" { return token::KW_I; }
|
||||||
"*K" { return KW_K; }
|
"*K" { return token::KW_K; }
|
||||||
"*L" { return KW_L; }
|
"*L" { return token::KW_L; }
|
||||||
"*LOADS" { return LOADS; }
|
"*LOADS" { return token::LOADS; }
|
||||||
"*L_UNIT" { return L_UNIT; }
|
"*L_UNIT" { return token::L_UNIT; }
|
||||||
"*NAME_MAP" { return NAME_MAP; }
|
"*NAME_MAP" { return token::NAME_MAP; }
|
||||||
"*N" { return KW_N; }
|
"*N" { return token::KW_N; }
|
||||||
"*PDEFINE" { return PDEFINE; }
|
"*PDEFINE" { return token::PDEFINE; }
|
||||||
"*PHYSICAL_PORTS" { return PHYSICAL_PORTS; }
|
"*PHYSICAL_PORTS" { return token::PHYSICAL_PORTS; }
|
||||||
"*PORTS" { return PORTS; }
|
"*PORTS" { return token::PORTS; }
|
||||||
"*POWER_NETS" { return POWER_NETS; }
|
"*POWER_NETS" { return token::POWER_NETS; }
|
||||||
"*PROGRAM" { return PROGRAM; }
|
"*PROGRAM" { return token::PROGRAM; }
|
||||||
"*P" { return KW_P; }
|
"*P" { return token::KW_P; }
|
||||||
"*Q" { return KW_Q; }
|
"*Q" { return token::KW_Q; }
|
||||||
"*RC" { return RC; }
|
"*RC" { return token::RC; }
|
||||||
"*RES" { return RES; }
|
"*RES" { return token::RES; }
|
||||||
"*R_NET" { return R_NET; }
|
"*R_NET" { return token::R_NET; }
|
||||||
"*R_PNET" { return R_PNET; }
|
"*R_PNET" { return token::R_PNET; }
|
||||||
"*R_UNIT" { return R_UNIT; }
|
"*R_UNIT" { return token::R_UNIT; }
|
||||||
"*S" { return KW_S; }
|
"*S" { return token::KW_S; }
|
||||||
"*T_UNIT" { return T_UNIT; }
|
"*T_UNIT" { return token::T_UNIT; }
|
||||||
"*VENDOR" { return VENDOR; }
|
"*VENDOR" { return token::VENDOR; }
|
||||||
"*VERSION" { return PVERSION; }
|
"*VERSION" { return token::PVERSION; }
|
||||||
"*V" { return KW_V; }
|
"*V" { return token::KW_V; }
|
||||||
|
|
||||||
"//".*\n { /* Single line comment */
|
"//".*\n { loc->lines(); loc->step(); } /* Single line comment */
|
||||||
sta::spef_reader->incrLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
"/*" { BEGIN COMMENT; }
|
"/*" { BEGIN COMMENT; }
|
||||||
<COMMENT>{
|
<COMMENT>{
|
||||||
|
|
||||||
.
|
.
|
||||||
|
|
||||||
\n { sta::spef_reader->incrLine(); }
|
\n { loc->lines(); loc->step(); }
|
||||||
|
|
||||||
"*/" { BEGIN INITIAL; }
|
"*/" { BEGIN INITIAL; }
|
||||||
|
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
SpefParse_error("unterminated comment");
|
error("unterminated comment");
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
yyterminate();
|
yyterminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"\"" { BEGIN QUOTE; spef_token.erase(); }
|
"\"" { BEGIN QUOTE; token_.erase(); }
|
||||||
<QUOTE>{
|
<QUOTE>{
|
||||||
|
|
||||||
\r?\n {
|
\r?\n { loc->lines(); loc->step(); }
|
||||||
sta::spef_reader->incrLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
"\\". { spef_token += yytext[1]; }
|
"\\". { token_ += yytext[1]; }
|
||||||
|
|
||||||
"\"" {
|
"\"" {
|
||||||
BEGIN INITIAL;
|
BEGIN INITIAL;
|
||||||
SpefParse_lval.string = sta::stringCopy(spef_token.c_str());
|
yylval->string = sta::stringCopy(token_.c_str());
|
||||||
return QSTRING;
|
return token::QSTRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
. { spef_token += yytext[0]; }
|
. { token_ += yytext[0]; }
|
||||||
|
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
SpefParse_error("unterminated quoted string");
|
error("unterminated quoted string");
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
yyterminate();
|
yyterminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{BLANK}*\n {
|
{BLANK}*\n { loc->lines(); loc->step(); }
|
||||||
sta::spef_reader->incrLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
{INTEGER} {
|
{INTEGER} {
|
||||||
SpefParse_lval.integer = atoi(yytext);
|
yylval->integer = atoi(yytext);
|
||||||
return INTEGER;
|
return token::INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
{FLOAT} {
|
{FLOAT} {
|
||||||
SpefParse_lval.number = static_cast<float>(atof(yytext));
|
yylval->number = static_cast<float>(atof(yytext));
|
||||||
return FLOAT;
|
return token::FLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
{IDENT} {
|
{IDENT} {
|
||||||
SpefParse_lval.string = sta::spef_reader->translated(yytext);
|
yylval->string = reader_->translated(yytext);
|
||||||
return IDENT;
|
return token::IDENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
{PATH}|{NAME_PAIR} {
|
{PATH}|{NAME_PAIR} {
|
||||||
SpefParse_lval.string = sta::spef_reader->translated(yytext);
|
yylval->string = reader_->translated(yytext);
|
||||||
return NAME;
|
return token::NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
{INDEX} {
|
{INDEX} {
|
||||||
SpefParse_lval.string = sta::stringCopy(yytext);
|
yylval->string = sta::stringCopy(yytext);
|
||||||
return INDEX;
|
return token::INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
{HCHAR} {
|
{HCHAR} {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
%{
|
|
||||||
|
|
||||||
// OpenSTA, Static Timing Analyzer
|
// OpenSTA, Static Timing Analyzer
|
||||||
// Copyright (c) 2025, Parallax Software, Inc.
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
//
|
//
|
||||||
|
|
@ -24,19 +22,41 @@
|
||||||
//
|
//
|
||||||
// This notice may not be removed or altered from any source distribution.
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
%{
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "Report.hh"
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "StringSeq.hh"
|
#include "StringSeq.hh"
|
||||||
#include "parasitics/SpefReaderPvt.hh"
|
#include "parasitics/SpefReaderPvt.hh"
|
||||||
|
#include "parasitics/SpefScanner.hh"
|
||||||
|
|
||||||
int SpefLex_lex();
|
#undef yylex
|
||||||
#define SpefParse_lex SpefLex_lex
|
#define yylex scanner->lex
|
||||||
// use yacc generated parser errors
|
|
||||||
#define YYERROR_VERBOSE
|
|
||||||
|
|
||||||
|
// warning: variable 'yynerrs_' set but not used
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
|
|
||||||
|
void
|
||||||
|
sta::SpefParse::error(const location_type &loc,
|
||||||
|
const string &msg)
|
||||||
|
{
|
||||||
|
reader->report()->fileError(164,reader->filename(),
|
||||||
|
loc.begin.line,"%s",msg.c_str());
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%require "3.2"
|
||||||
|
%skeleton "lalr1.cc"
|
||||||
|
%debug
|
||||||
|
%define api.namespace {sta}
|
||||||
|
%locations
|
||||||
|
%define api.location.file "SpefLocation.hh"
|
||||||
|
%define parse.assert
|
||||||
|
%parse-param { SpefScanner *scanner }
|
||||||
|
%parse-param { SpefReader *reader }
|
||||||
|
%define api.parser.class {SpefParse}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
char ch;
|
char ch;
|
||||||
char *string;
|
char *string;
|
||||||
|
|
@ -195,7 +215,7 @@ vendor:
|
||||||
|
|
||||||
design_flow:
|
design_flow:
|
||||||
DESIGN_FLOW qstrings
|
DESIGN_FLOW qstrings
|
||||||
{ sta::spef_reader->setDesignFlow($2); }
|
{ reader->setDesignFlow($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
qstrings:
|
qstrings:
|
||||||
|
|
@ -209,19 +229,19 @@ qstrings:
|
||||||
|
|
||||||
hierarchy_div_def:
|
hierarchy_div_def:
|
||||||
DIVIDER hchar
|
DIVIDER hchar
|
||||||
{ sta::spef_reader->setDivider($2); }
|
{ reader->setDivider($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
pin_delim_def:
|
pin_delim_def:
|
||||||
DELIMITER hchar
|
DELIMITER hchar
|
||||||
{ sta::spef_reader->setDelimiter($2); }
|
{ reader->setDelimiter($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
bus_delim_def:
|
bus_delim_def:
|
||||||
BUS_DELIMITER prefix_bus_delim
|
BUS_DELIMITER prefix_bus_delim
|
||||||
{ sta::spef_reader->setBusBrackets($2, '\0'); }
|
{ reader->setBusBrackets($2, '\0'); }
|
||||||
| BUS_DELIMITER prefix_bus_delim suffix_bus_delim
|
| BUS_DELIMITER prefix_bus_delim suffix_bus_delim
|
||||||
{ sta::spef_reader->setBusBrackets($2, $3); }
|
{ reader->setBusBrackets($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
@ -235,22 +255,22 @@ unit_def:
|
||||||
|
|
||||||
time_scale:
|
time_scale:
|
||||||
T_UNIT pos_number IDENT
|
T_UNIT pos_number IDENT
|
||||||
{ sta::spef_reader->setTimeScale($2, $3); }
|
{ reader->setTimeScale($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
cap_scale:
|
cap_scale:
|
||||||
C_UNIT pos_number IDENT
|
C_UNIT pos_number IDENT
|
||||||
{ sta::spef_reader->setCapScale($2, $3); }
|
{ reader->setCapScale($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
res_scale:
|
res_scale:
|
||||||
R_UNIT pos_number IDENT
|
R_UNIT pos_number IDENT
|
||||||
{ sta::spef_reader->setResScale($2, $3); }
|
{ reader->setResScale($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
induc_scale:
|
induc_scale:
|
||||||
L_UNIT pos_number IDENT
|
L_UNIT pos_number IDENT
|
||||||
{ sta::spef_reader->setInductScale($2, $3); }
|
{ reader->setInductScale($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
@ -267,7 +287,7 @@ name_map_entries:
|
||||||
|
|
||||||
name_map_entry:
|
name_map_entry:
|
||||||
INDEX mapped_item
|
INDEX mapped_item
|
||||||
{ sta::spef_reader->makeNameMapEntry($1, $2);
|
{ reader->makeNameMapEntry($1, $2);
|
||||||
sta::stringDelete($1);
|
sta::stringDelete($1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -330,7 +350,7 @@ port_entry:
|
||||||
|
|
||||||
direction:
|
direction:
|
||||||
IDENT
|
IDENT
|
||||||
{ $$ = sta::spef_reader->portDirection($1);
|
{ $$ = reader->portDirection($1);
|
||||||
sta::stringDelete($1);
|
sta::stringDelete($1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -474,14 +494,14 @@ nets:
|
||||||
|
|
||||||
d_net:
|
d_net:
|
||||||
D_NET net total_cap
|
D_NET net total_cap
|
||||||
{ sta::spef_reader->dspfBegin($2, $3); }
|
{ reader->dspfBegin($2, $3); }
|
||||||
routing_conf conn_sec cap_sec res_sec induc_sec END
|
routing_conf conn_sec cap_sec res_sec induc_sec END
|
||||||
{ sta::spef_reader->dspfFinish(); }
|
{ reader->dspfFinish(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
net:
|
net:
|
||||||
name_or_index
|
name_or_index
|
||||||
{ $$ = sta::spef_reader->findNet($1);
|
{ $$ = reader->findNet($1);
|
||||||
sta::stringDelete($1);
|
sta::stringDelete($1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -531,7 +551,7 @@ internal_connection:
|
||||||
|
|
||||||
pin_name:
|
pin_name:
|
||||||
name_or_index
|
name_or_index
|
||||||
{ $$ = sta::spef_reader->findPin($1);
|
{ $$ = reader->findPin($1);
|
||||||
sta::stringDelete($1);
|
sta::stringDelete($1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -565,9 +585,9 @@ cap_elems:
|
||||||
|
|
||||||
cap_elem:
|
cap_elem:
|
||||||
cap_id parasitic_node par_value
|
cap_id parasitic_node par_value
|
||||||
{ sta::spef_reader->makeCapacitor($1, $2, $3); }
|
{ reader->makeCapacitor($1, $2, $3); }
|
||||||
| cap_id parasitic_node parasitic_node par_value
|
| cap_id parasitic_node parasitic_node par_value
|
||||||
{ sta::spef_reader->makeCapacitor($1, $2, $3, $4); }
|
{ reader->makeCapacitor($1, $2, $3, $4); }
|
||||||
;
|
;
|
||||||
|
|
||||||
cap_id:
|
cap_id:
|
||||||
|
|
@ -593,7 +613,7 @@ res_elems:
|
||||||
|
|
||||||
res_elem:
|
res_elem:
|
||||||
res_id parasitic_node parasitic_node par_value
|
res_id parasitic_node parasitic_node par_value
|
||||||
{ sta::spef_reader->makeResistor($1, $2, $3, $4); }
|
{ reader->makeResistor($1, $2, $3, $4); }
|
||||||
;
|
;
|
||||||
|
|
||||||
res_id:
|
res_id:
|
||||||
|
|
@ -626,9 +646,9 @@ induc_id:
|
||||||
|
|
||||||
r_net:
|
r_net:
|
||||||
R_NET net total_cap
|
R_NET net total_cap
|
||||||
{ sta::spef_reader->rspfBegin($2, $3); }
|
{ reader->rspfBegin($2, $3); }
|
||||||
routing_conf driver_reducs END
|
routing_conf driver_reducs END
|
||||||
{ sta::spef_reader->rspfFinish(); }
|
{ reader->rspfFinish(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
driver_reducs:
|
driver_reducs:
|
||||||
|
|
@ -638,11 +658,11 @@ driver_reducs:
|
||||||
|
|
||||||
driver_reduc:
|
driver_reduc:
|
||||||
driver_pair driver_cell pi_model
|
driver_pair driver_cell pi_model
|
||||||
{ sta::spef_reader->rspfDrvrBegin($1, $3);
|
{ reader->rspfDrvrBegin($1, $3);
|
||||||
sta::stringDelete($2);
|
sta::stringDelete($2);
|
||||||
}
|
}
|
||||||
load_desc
|
load_desc
|
||||||
{ sta::spef_reader->rspfDrvrFinish(); }
|
{ reader->rspfDrvrFinish(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
driver_pair:
|
driver_pair:
|
||||||
|
|
@ -673,9 +693,9 @@ rc_descs:
|
||||||
|
|
||||||
rc_desc:
|
rc_desc:
|
||||||
RC pin_name par_value
|
RC pin_name par_value
|
||||||
{ sta::spef_reader->rspfLoad($2, $3); }
|
{ reader->rspfLoad($2, $3); }
|
||||||
| RC pin_name par_value pole_residue_desc
|
| RC pin_name par_value pole_residue_desc
|
||||||
{ sta::spef_reader->rspfLoad($2, $3); }
|
{ reader->rspfLoad($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
pole_residue_desc:
|
pole_residue_desc:
|
||||||
|
|
@ -810,7 +830,7 @@ pos_integer:
|
||||||
INTEGER
|
INTEGER
|
||||||
{ int value = $1;
|
{ int value = $1;
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
sta::spef_reader->warn(1525, "%d is not positive.", value);
|
reader->warn(1525, "%d is not positive.", value);
|
||||||
$$ = value;
|
$$ = value;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -819,13 +839,13 @@ pos_number:
|
||||||
INTEGER
|
INTEGER
|
||||||
{ float value = static_cast<float>($1);
|
{ float value = static_cast<float>($1);
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
sta::spef_reader->warn(1526, "%.4f is not positive.", value);
|
reader->warn(1526, "%.4f is not positive.", value);
|
||||||
$$ = value;
|
$$ = value;
|
||||||
}
|
}
|
||||||
| FLOAT
|
| FLOAT
|
||||||
{ float value = static_cast<float>($1);
|
{ float value = static_cast<float>($1);
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
sta::spef_reader->warn(1527, "%.4f is not positive.", value);
|
reader->warn(1527, "%.4f is not positive.", value);
|
||||||
$$ = value;
|
$$ = value;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -40,17 +40,10 @@
|
||||||
#include "ArcDelayCalc.hh"
|
#include "ArcDelayCalc.hh"
|
||||||
#include "SpefReaderPvt.hh"
|
#include "SpefReaderPvt.hh"
|
||||||
#include "SpefNamespace.hh"
|
#include "SpefNamespace.hh"
|
||||||
|
#include "parasitics/SpefScanner.hh"
|
||||||
int
|
|
||||||
SpefParse_parse();
|
|
||||||
void
|
|
||||||
spefResetScanner();
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
// Referenced by parser.
|
|
||||||
SpefReader *spef_reader;
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
readSpefFile(const char *filename,
|
readSpefFile(const char *filename,
|
||||||
Instance *instance,
|
Instance *instance,
|
||||||
|
|
@ -63,35 +56,14 @@ readSpefFile(const char *filename,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
StaState *sta)
|
StaState *sta)
|
||||||
{
|
{
|
||||||
bool success = false;
|
SpefReader reader(filename, instance, ap,
|
||||||
const ArcDelayCalc *arc_delay_calc = sta->arcDelayCalc();
|
pin_cap_included, keep_coupling_caps, coupling_cap_factor,
|
||||||
if (reduce && !arc_delay_calc->reduceSupported()) {
|
reduce, corner, min_max, sta);
|
||||||
sta->report()->warn(1658, "Delay calculator %s does not support reduction.",
|
bool success = reader.read();
|
||||||
arc_delay_calc->name());
|
|
||||||
reduce = false;
|
|
||||||
}
|
|
||||||
// Use zlib to uncompress gzip'd files automagically.
|
|
||||||
gzFile stream = gzopen(filename, "rb");
|
|
||||||
if (stream) {
|
|
||||||
Stats stats(sta->debug(), sta->report());
|
|
||||||
SpefReader reader(filename, stream, instance, ap,
|
|
||||||
pin_cap_included, keep_coupling_caps, coupling_cap_factor,
|
|
||||||
reduce, corner, min_max, sta);
|
|
||||||
spef_reader = &reader;
|
|
||||||
::spefResetScanner();
|
|
||||||
// yyparse returns 0 on success.
|
|
||||||
success = (::SpefParse_parse() == 0);
|
|
||||||
gzclose(stream);
|
|
||||||
spef_reader = nullptr;
|
|
||||||
stats.report("Read spef");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw FileNotReadable(filename);
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpefReader::SpefReader(const char *filename,
|
SpefReader::SpefReader(const char *filename,
|
||||||
gzFile stream,
|
|
||||||
Instance *instance,
|
Instance *instance,
|
||||||
ParasiticAnalysisPt *ap,
|
ParasiticAnalysisPt *ap,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
|
|
@ -110,8 +82,6 @@ SpefReader::SpefReader(const char *filename,
|
||||||
reduce_(reduce),
|
reduce_(reduce),
|
||||||
corner_(corner),
|
corner_(corner),
|
||||||
min_max_(min_max),
|
min_max_(min_max),
|
||||||
stream_(stream),
|
|
||||||
line_(1),
|
|
||||||
// defaults
|
// defaults
|
||||||
divider_('\0'),
|
divider_('\0'),
|
||||||
delimiter_('\0'),
|
delimiter_('\0'),
|
||||||
|
|
@ -141,6 +111,25 @@ SpefReader::~SpefReader()
|
||||||
stringDelete(name);
|
stringDelete(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SpefReader::read()
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
gzstream::igzstream stream(filename_);
|
||||||
|
if (stream.is_open()) {
|
||||||
|
Stats stats(debug_, report_);
|
||||||
|
SpefScanner scanner(&stream, filename_, this, report_);
|
||||||
|
scanner_ = &scanner;
|
||||||
|
SpefParse parser(&scanner, this);
|
||||||
|
// yyparse returns 0 on success.
|
||||||
|
success = (parser.parse() == 0);
|
||||||
|
stats.report("Read spef");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw FileNotReadable(filename_);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SpefReader::setDivider(char divider)
|
SpefReader::setDivider(char divider)
|
||||||
{
|
{
|
||||||
|
|
@ -154,7 +143,8 @@ SpefReader::setDelimiter(char delimiter)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SpefReader::setBusBrackets(char left, char right)
|
SpefReader::setBusBrackets(char left,
|
||||||
|
char right)
|
||||||
{
|
{
|
||||||
if (!((left == '[' && right == ']')
|
if (!((left == '[' && right == ']')
|
||||||
|| (left == '{' && right == '}')
|
|| (left == '{' && right == '}')
|
||||||
|
|
@ -196,30 +186,6 @@ SpefReader::findPortPinRelative(const char *name)
|
||||||
return network_->findPin(instance_, name);
|
return network_->findPin(instance_, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SpefReader::getChars(char *buf,
|
|
||||||
int &result,
|
|
||||||
size_t max_size)
|
|
||||||
{
|
|
||||||
char *status = gzgets(stream_, buf, max_size);
|
|
||||||
if (status == Z_NULL)
|
|
||||||
result = 0; // YY_nullptr
|
|
||||||
else
|
|
||||||
result = static_cast<int>(strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SpefReader::getChars(char *buf,
|
|
||||||
size_t &result,
|
|
||||||
size_t max_size)
|
|
||||||
{
|
|
||||||
char *status = gzgets(stream_, buf, max_size);
|
|
||||||
if (status == Z_NULL)
|
|
||||||
result = 0; // YY_nullptr
|
|
||||||
else
|
|
||||||
result = strlen(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
SpefReader::translated(const char *token)
|
SpefReader::translated(const char *token)
|
||||||
{
|
{
|
||||||
|
|
@ -227,18 +193,12 @@ SpefReader::translated(const char *token)
|
||||||
network_->pathEscape());
|
network_->pathEscape());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SpefReader::incrLine()
|
|
||||||
{
|
|
||||||
line_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SpefReader::warn(int id, const char *fmt, ...)
|
SpefReader::warn(int id, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
report_->vfileWarn(id, filename_, line_, fmt, args);
|
report_->vfileWarn(id, filename_, scanner_->line(), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -644,17 +604,23 @@ SpefTriple::value(int index) const
|
||||||
return values_[0];
|
return values_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Global namespace
|
|
||||||
|
|
||||||
void spefFlushBuffer();
|
SpefScanner::SpefScanner(std::istream *stream,
|
||||||
|
const string &filename,
|
||||||
int
|
SpefReader *reader,
|
||||||
SpefParse_error(const char *msg)
|
Report *report) :
|
||||||
|
yyFlexLexer(stream),
|
||||||
|
filename_(filename),
|
||||||
|
reader_(reader),
|
||||||
|
report_(report)
|
||||||
{
|
{
|
||||||
spefFlushBuffer();
|
|
||||||
sta::spef_reader->warn(1657, "%s.", msg);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SpefScanner::error(const char *msg)
|
||||||
|
{
|
||||||
|
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,6 @@
|
||||||
#include "ParasiticsClass.hh"
|
#include "ParasiticsClass.hh"
|
||||||
#include "StaState.hh"
|
#include "StaState.hh"
|
||||||
|
|
||||||
// Global namespace.
|
|
||||||
#define YY_INPUT(buf,result,max_size) \
|
|
||||||
sta::spef_reader->getChars(buf, result, max_size)
|
|
||||||
|
|
||||||
int
|
|
||||||
SpefParse_error(const char *msg);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
class Report;
|
class Report;
|
||||||
|
|
@ -48,6 +39,7 @@ class MinMaxAll;
|
||||||
class SpefRspfPi;
|
class SpefRspfPi;
|
||||||
class SpefTriple;
|
class SpefTriple;
|
||||||
class Corner;
|
class Corner;
|
||||||
|
class SpefScanner;
|
||||||
|
|
||||||
typedef std::map<int, char*, std::less<int>> SpefNameMap;
|
typedef std::map<int, char*, std::less<int>> SpefNameMap;
|
||||||
|
|
||||||
|
|
@ -55,7 +47,6 @@ class SpefReader : public StaState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpefReader(const char *filename,
|
SpefReader(const char *filename,
|
||||||
gzFile stream,
|
|
||||||
Instance *instance,
|
Instance *instance,
|
||||||
ParasiticAnalysisPt *ap,
|
ParasiticAnalysisPt *ap,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
|
|
@ -66,21 +57,12 @@ public:
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
StaState *sta);
|
StaState *sta);
|
||||||
virtual ~SpefReader();
|
virtual ~SpefReader();
|
||||||
|
bool read();
|
||||||
char divider() const { return divider_; }
|
char divider() const { return divider_; }
|
||||||
void setDivider(char divider);
|
void setDivider(char divider);
|
||||||
char delimiter() const { return delimiter_; }
|
char delimiter() const { return delimiter_; }
|
||||||
void setDelimiter(char delimiter);
|
void setDelimiter(char delimiter);
|
||||||
void incrLine();
|
|
||||||
int line() const { return line_; }
|
|
||||||
const char *filename() const { return filename_; }
|
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.
|
// Translate from spf/spef namespace to sta namespace.
|
||||||
char *translated(const char *token);
|
char *translated(const char *token);
|
||||||
void warn(int id,
|
void warn(int id,
|
||||||
|
|
@ -136,6 +118,7 @@ private:
|
||||||
bool local_only);
|
bool local_only);
|
||||||
|
|
||||||
const char *filename_;
|
const char *filename_;
|
||||||
|
SpefScanner *scanner_;
|
||||||
Instance *instance_;
|
Instance *instance_;
|
||||||
const ParasiticAnalysisPt *ap_;
|
const ParasiticAnalysisPt *ap_;
|
||||||
bool pin_cap_included_;
|
bool pin_cap_included_;
|
||||||
|
|
@ -144,8 +127,6 @@ private:
|
||||||
const Corner *corner_;
|
const Corner *corner_;
|
||||||
const MinMaxAll *min_max_;
|
const MinMaxAll *min_max_;
|
||||||
// Normally no need to keep device names.
|
// Normally no need to keep device names.
|
||||||
gzFile stream_;
|
|
||||||
int line_;
|
|
||||||
char divider_;
|
char divider_;
|
||||||
char delimiter_;
|
char delimiter_;
|
||||||
char bus_brkt_left_;
|
char bus_brkt_left_;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2025, 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/>.
|
||||||
|
//
|
||||||
|
// The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software.
|
||||||
|
//
|
||||||
|
// Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SpefLocation.hh"
|
||||||
|
#include "SpefParse.hh"
|
||||||
|
|
||||||
|
#ifndef __FLEX_LEXER_H
|
||||||
|
#undef yyFlexLexer
|
||||||
|
#define yyFlexLexer SpefFlexLexer
|
||||||
|
#include <FlexLexer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
class Report;
|
||||||
|
|
||||||
|
class SpefScanner : public SpefFlexLexer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpefScanner(std::istream *stream,
|
||||||
|
const string &filename,
|
||||||
|
SpefReader *reader,
|
||||||
|
Report *report);
|
||||||
|
virtual ~SpefScanner() {}
|
||||||
|
|
||||||
|
virtual int lex(SpefParse::semantic_type *const yylval,
|
||||||
|
SpefParse::location_type *yylloc);
|
||||||
|
// YY_DECL defined in SpefLex.ll
|
||||||
|
// Method body created by flex in SpefLex.cc
|
||||||
|
|
||||||
|
void error(const char *msg);
|
||||||
|
int line() const { return yylineno; }
|
||||||
|
|
||||||
|
// Get rid of override virtual function warning.
|
||||||
|
using FlexLexer::yylex;
|
||||||
|
|
||||||
|
private:
|
||||||
|
string filename_;
|
||||||
|
SpefReader *reader_;
|
||||||
|
Report *report_;
|
||||||
|
string token_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
%{
|
%{
|
||||||
|
|
||||||
// OpenSTA, Static Timing Analyzer
|
// OpenSTA, Static Timing Analyzer
|
||||||
// Copyright (c) 2025, Parallax Software, Inc.
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
//
|
//
|
||||||
|
|
@ -30,23 +29,28 @@
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "power/SaifReaderPvt.hh"
|
#include "power/SaifReaderPvt.hh"
|
||||||
#include "SaifParse.hh"
|
#include "SaifParse.hh"
|
||||||
|
#include "power/SaifScanner.hh"
|
||||||
|
|
||||||
#define YY_NO_INPUT
|
#undef YY_DECL
|
||||||
|
#define YY_DECL \
|
||||||
|
int \
|
||||||
|
sta::SaifScanner::lex(sta::SaifParse::semantic_type *const yylval, \
|
||||||
|
sta::SaifParse::location_type *loc)
|
||||||
|
|
||||||
static std::string saif_token;
|
// update location on matching
|
||||||
|
#define YY_USER_ACTION loc->step(); loc->columns(yyleng);
|
||||||
void
|
|
||||||
saifFlushBuffer()
|
|
||||||
{
|
|
||||||
YY_FLUSH_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
typedef sta::SaifParse::token token;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
/* %option debug */
|
%option c++
|
||||||
|
%option yyclass="sta::SaifScanner"
|
||||||
|
%option prefix="Saif"
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option nounput
|
|
||||||
%option never-interactive
|
%option never-interactive
|
||||||
|
%option stack
|
||||||
|
%option yylineno
|
||||||
|
/* %option debug */
|
||||||
|
|
||||||
%x COMMENT
|
%x COMMENT
|
||||||
%x QUOTE
|
%x QUOTE
|
||||||
|
|
@ -65,74 +69,74 @@ EOL \r?\n
|
||||||
"*/" { BEGIN INITIAL; }
|
"*/" { BEGIN INITIAL; }
|
||||||
|
|
||||||
.
|
.
|
||||||
{EOL} { sta::saif_reader->incrLine(); }
|
{EOL} { loc->lines(); loc->step(); }
|
||||||
|
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
SaifParse_error("unterminated comment");
|
error("unterminated comment");
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
yyterminate();
|
yyterminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"\"" { BEGIN QUOTE; saif_token.erase(); }
|
"\"" { BEGIN QUOTE; token_.clear(); }
|
||||||
<QUOTE>{
|
<QUOTE>{
|
||||||
|
|
||||||
"\\". { saif_token += yytext[1]; }
|
"\\". { token_ += yytext[1]; }
|
||||||
|
|
||||||
"\"" {
|
"\"" {
|
||||||
BEGIN INITIAL;
|
BEGIN INITIAL;
|
||||||
SaifParse_lval.string = sta::stringCopy(saif_token.c_str());
|
yylval->string = sta::stringCopy(token_.c_str());
|
||||||
return QSTRING;
|
return token::QSTRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
. { saif_token += yytext[0]; }
|
. { token_ += yytext[0]; }
|
||||||
|
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
SaifParse_error("unterminated quoted string");
|
error("unterminated quoted string");
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
yyterminate();
|
yyterminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"//"[^\n]*{EOL} { sta::saif_reader->incrLine(); }
|
"//"[^\n]*{EOL} { loc->lines(); loc->step(); }
|
||||||
|
|
||||||
[0-9]+ {
|
[0-9]+ {
|
||||||
SaifParse_lval.uint = atoll(yytext);
|
yylval->uint = atoll(yytext);
|
||||||
return UINT;
|
return token::UINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
":"|"{"|"}"|"["|"]"|","|"*"|";"|"="|"-"|"+"|"|"|"("|")"|{HCHAR} {
|
":"|"{"|"}"|"["|"]"|","|"*"|";"|"="|"-"|"+"|"|"|"("|")"|{HCHAR} {
|
||||||
return ((int) yytext[0]);
|
return ((int) yytext[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAIFILE { return SAIFILE; }
|
SAIFILE { return token::SAIFILE; }
|
||||||
SAIFVERSION { return SAIFVERSION; }
|
SAIFVERSION { return token::SAIFVERSION; }
|
||||||
DIRECTION { return DIRECTION; }
|
DIRECTION { return token::DIRECTION; }
|
||||||
DESIGN { return DESIGN; }
|
DESIGN { return token::DESIGN; }
|
||||||
DATE { return DATE; }
|
DATE { return token::DATE; }
|
||||||
VENDOR { return VENDOR; }
|
VENDOR { return token::VENDOR; }
|
||||||
PROGRAM_NAME { return PROGRAM_NAME; }
|
PROGRAM_NAME { return token::PROGRAM_NAME; }
|
||||||
VERSION { return VERSION; }
|
VERSION { return token::VERSION; }
|
||||||
DIVIDER { return DIVIDER; }
|
DIVIDER { return token::DIVIDER; }
|
||||||
TIMESCALE { return TIMESCALE; }
|
TIMESCALE { return token::TIMESCALE; }
|
||||||
DURATION { return DURATION; }
|
DURATION { return token::DURATION; }
|
||||||
INSTANCE { return INSTANCE; }
|
INSTANCE { return token::INSTANCE; }
|
||||||
NET { return NET; }
|
NET { return token::NET; }
|
||||||
PORT { return PORT; }
|
PORT { return token::PORT; }
|
||||||
T0 { return T0; }
|
T0 { return token::T0; }
|
||||||
T1 { return T1; }
|
T1 { return token::T1; }
|
||||||
TX { return TX; }
|
TX { return token::TX; }
|
||||||
TZ { return TZ; }
|
TZ { return token::TZ; }
|
||||||
TB { return TB; }
|
TB { return token::TB; }
|
||||||
TC { return TC; }
|
TC { return token::TC; }
|
||||||
IG { return IG; }
|
IG { return token::IG; }
|
||||||
|
|
||||||
{ID} {
|
{ID} {
|
||||||
SaifParse_lval.string = sta::stringCopy(yytext);
|
yylval->string = sta::stringCopy(yytext);
|
||||||
return ID;
|
return token::ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
{EOL} { sta::saif_reader->incrLine(); }
|
{EOL} { loc->lines(); loc->step(); }
|
||||||
|
|
||||||
{BLANK} { /* Ignore blanks. */ }
|
{BLANK} { /* Ignore blanks. */ }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
%{
|
|
||||||
|
|
||||||
// OpenSTA, Static Timing Analyzer
|
// OpenSTA, Static Timing Analyzer
|
||||||
// Copyright (c) 2025, Parallax Software, Inc.
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
//
|
//
|
||||||
|
|
@ -24,20 +22,41 @@
|
||||||
//
|
//
|
||||||
// This notice may not be removed or altered from any source distribution.
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
%{
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
|
#include "Report.hh"
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "power/SaifReaderPvt.hh"
|
#include "power/SaifReaderPvt.hh"
|
||||||
|
#include "power/SaifScanner.hh"
|
||||||
|
|
||||||
int SaifLex_lex();
|
#undef yylex
|
||||||
#define SaifParse_lex SaifLex_lex
|
#define yylex scanner->lex
|
||||||
// use yacc generated parser errors
|
|
||||||
#define YYERROR_VERBOSE
|
|
||||||
|
|
||||||
#define YYDEBUG 1
|
// warning: variable 'yynerrs_' set but not used
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
|
|
||||||
|
#define loc_line(loc) loc.begin.line
|
||||||
|
|
||||||
|
void
|
||||||
|
sta::SaifParse::error(const location_type &loc,
|
||||||
|
const string &msg)
|
||||||
|
{
|
||||||
|
reader->report()->fileError(164,reader->filename(),loc.begin.line,"%s",msg.c_str());
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%require "3.2"
|
||||||
|
%skeleton "lalr1.cc"
|
||||||
|
%debug
|
||||||
|
%define api.namespace {sta}
|
||||||
|
%locations
|
||||||
|
%define api.location.file "SaifLocation.hh"
|
||||||
|
%define parse.assert
|
||||||
|
%parse-param { SaifScanner *scanner }
|
||||||
|
%parse-param { SaifReader *reader }
|
||||||
|
%define api.parser.class {SaifParse}
|
||||||
|
|
||||||
// expected shift/reduce conflicts
|
// expected shift/reduce conflicts
|
||||||
%expect 2
|
%expect 2
|
||||||
|
|
||||||
|
|
@ -86,9 +105,9 @@ header_stmt:
|
||||||
| '(' VENDOR QSTRING ')' { sta::stringDelete($3); }
|
| '(' VENDOR QSTRING ')' { sta::stringDelete($3); }
|
||||||
| '(' PROGRAM_NAME QSTRING ')' { sta::stringDelete($3); }
|
| '(' PROGRAM_NAME QSTRING ')' { sta::stringDelete($3); }
|
||||||
| '(' VERSION QSTRING ')' { sta::stringDelete($3); }
|
| '(' VERSION QSTRING ')' { sta::stringDelete($3); }
|
||||||
| '(' DIVIDER hchar ')' { sta::saif_reader->setDivider($3); }
|
| '(' DIVIDER hchar ')' { reader->setDivider($3); }
|
||||||
| '(' TIMESCALE UINT ID ')' { sta::saif_reader->setTimescale($3, $4); }
|
| '(' TIMESCALE UINT ID ')' { reader->setTimescale($3, $4); }
|
||||||
| '(' DURATION UINT ')' { sta::saif_reader->setDuration($3); }
|
| '(' DURATION UINT ')' { reader->setDuration($3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
hchar:
|
hchar:
|
||||||
|
|
@ -100,13 +119,13 @@ hchar:
|
||||||
|
|
||||||
instance:
|
instance:
|
||||||
'(' INSTANCE ID
|
'(' INSTANCE ID
|
||||||
{ sta::saif_reader->instancePush($3); }
|
{ reader->instancePush($3); }
|
||||||
instance_contents ')'
|
instance_contents ')'
|
||||||
{ sta::saif_reader->instancePop(); }
|
{ reader->instancePop(); }
|
||||||
| '(' INSTANCE QSTRING ID
|
| '(' INSTANCE QSTRING ID
|
||||||
{ sta::saif_reader->instancePush($3); }
|
{ reader->instancePush($3); }
|
||||||
instance_contents ')'
|
instance_contents ')'
|
||||||
{ sta::saif_reader->instancePop(); }
|
{ reader->instancePop(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
instance_contents:
|
instance_contents:
|
||||||
|
|
@ -128,7 +147,7 @@ nets:
|
||||||
|
|
||||||
net:
|
net:
|
||||||
'(' ID state_durations ')'
|
'(' ID state_durations ')'
|
||||||
{ sta::saif_reader->setNetDurations($2, $3); }
|
{ reader->setNetDurations($2, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
|
|
|
||||||
|
|
@ -29,33 +29,27 @@
|
||||||
|
|
||||||
#include "Error.hh"
|
#include "Error.hh"
|
||||||
#include "Debug.hh"
|
#include "Debug.hh"
|
||||||
|
#include "Stats.hh"
|
||||||
#include "Report.hh"
|
#include "Report.hh"
|
||||||
#include "Network.hh"
|
#include "Network.hh"
|
||||||
#include "PortDirection.hh"
|
#include "PortDirection.hh"
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
#include "Power.hh"
|
#include "Power.hh"
|
||||||
#include "power/SaifReaderPvt.hh"
|
#include "power/SaifReaderPvt.hh"
|
||||||
|
#include "power/SaifScanner.hh"
|
||||||
#include "Sta.hh"
|
#include "Sta.hh"
|
||||||
|
|
||||||
extern int
|
|
||||||
SaifParse_parse();
|
|
||||||
extern int SaifParse_debug;
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
using std::min;
|
using std::min;
|
||||||
|
|
||||||
SaifReader *saif_reader = nullptr;
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
readSaif(const char *filename,
|
readSaif(const char *filename,
|
||||||
const char *scope,
|
const char *scope,
|
||||||
Sta *sta)
|
Sta *sta)
|
||||||
{
|
{
|
||||||
SaifReader reader(filename, scope, sta);
|
SaifReader reader(filename, scope, sta);
|
||||||
saif_reader = &reader;
|
|
||||||
bool success = reader.read();
|
bool success = reader.read();
|
||||||
saif_reader = nullptr;
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,8 +59,6 @@ SaifReader::SaifReader(const char *filename,
|
||||||
StaState(sta),
|
StaState(sta),
|
||||||
filename_(filename),
|
filename_(filename),
|
||||||
scope_(scope),
|
scope_(scope),
|
||||||
stream_(nullptr),
|
|
||||||
line_(1),
|
|
||||||
divider_('/'),
|
divider_('/'),
|
||||||
escape_('\\'),
|
escape_('\\'),
|
||||||
timescale_(1.0E-9F), // default units of ns
|
timescale_(1.0E-9F), // default units of ns
|
||||||
|
|
@ -76,23 +68,16 @@ SaifReader::SaifReader(const char *filename,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SaifReader::~SaifReader()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SaifReader::read()
|
SaifReader::read()
|
||||||
{
|
{
|
||||||
// Use zlib to uncompress gzip'd files automagically.
|
gzstream::igzstream stream(filename_);
|
||||||
stream_ = gzopen(filename_, "rb");
|
if (stream.is_open()) {
|
||||||
if (stream_) {
|
Stats stats(debug_, report_);
|
||||||
saif_scope_.clear();
|
SaifScanner scanner(&stream, filename_, this, report_);
|
||||||
in_scope_level_ = 0;
|
SaifParse parser(&scanner, this);
|
||||||
annotated_pins_.clear();
|
|
||||||
//::SaifParse_debug = 1;
|
|
||||||
// yyparse returns 0 on success.
|
// yyparse returns 0 on success.
|
||||||
bool success = (::SaifParse_parse() == 0);
|
bool success = (parser.parse() == 0);
|
||||||
gzclose(stream_);
|
|
||||||
report_->reportLine("Annotated %zu pin activities.", annotated_pins_.size());
|
report_->reportLine("Annotated %zu pin activities.", annotated_pins_.size());
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
@ -122,10 +107,10 @@ SaifReader::setTimescale(uint64_t multiplier,
|
||||||
else if (stringEq(units, "fs"))
|
else if (stringEq(units, "fs"))
|
||||||
timescale_ = multiplier * 1E-15;
|
timescale_ = multiplier * 1E-15;
|
||||||
else
|
else
|
||||||
saifError(180, "TIMESCALE units not us, ns, or ps.");
|
report_->error(180, "SAIF TIMESCALE units not us, ns, or ps.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
saifError(181, "TIMESCALE multiplier not 1, 10, or 100.");
|
report_->error(181, "SAIF TIMESCALE multiplier not 1, 10, or 100.");
|
||||||
stringDelete(units);
|
stringDelete(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,72 +206,23 @@ SaifReader::unescaped(const char *token)
|
||||||
return unescaped;
|
return unescaped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
////////////////////////////////////////////////////////////////
|
||||||
SaifReader::incrLine()
|
|
||||||
|
SaifScanner::SaifScanner(std::istream *stream,
|
||||||
|
const string &filename,
|
||||||
|
SaifReader *reader,
|
||||||
|
Report *report) :
|
||||||
|
yyFlexLexer(stream),
|
||||||
|
filename_(filename),
|
||||||
|
reader_(reader),
|
||||||
|
report_(report)
|
||||||
{
|
{
|
||||||
line_++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SaifReader::getChars(char *buf,
|
SaifScanner::error(const char *msg)
|
||||||
size_t &result,
|
|
||||||
size_t max_size)
|
|
||||||
{
|
{
|
||||||
char *status = gzgets(stream_, buf, max_size);
|
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
||||||
if (status == Z_NULL)
|
|
||||||
result = 0; // YY_nullptr
|
|
||||||
else
|
|
||||||
result = strlen(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SaifReader::getChars(char *buf,
|
|
||||||
int &result,
|
|
||||||
size_t max_size)
|
|
||||||
{
|
|
||||||
char *status = gzgets(stream_, buf, max_size);
|
|
||||||
if (status == Z_NULL)
|
|
||||||
result = 0; // YY_nullptr
|
|
||||||
else
|
|
||||||
result = strlen(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SaifReader::notSupported(const char *feature)
|
|
||||||
{
|
|
||||||
saifError(193, "%s not supported.", feature);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SaifReader::saifWarn(int id,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
report_->vfileWarn(id, filename_, line_, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SaifReader::saifError(int id,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
report_->vfileError(id, filename_, line_, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Global namespace
|
|
||||||
|
|
||||||
void saifFlushBuffer();
|
|
||||||
|
|
||||||
int
|
|
||||||
SaifParse_error(const char *msg)
|
|
||||||
{
|
|
||||||
saifFlushBuffer();
|
|
||||||
sta::saif_reader->saifError(196, "%s.\n", msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -38,15 +38,11 @@
|
||||||
|
|
||||||
// global namespace
|
// global namespace
|
||||||
|
|
||||||
#define YY_INPUT(buf,result,max_size) \
|
|
||||||
sta::saif_reader->getChars(buf, result, max_size)
|
|
||||||
int
|
|
||||||
SaifParse_error(const char *msg);
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
class Sta;
|
class Sta;
|
||||||
class Power;
|
class Power;
|
||||||
|
class SaifScanner;
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
@ -61,7 +57,6 @@ public:
|
||||||
SaifReader(const char *filename,
|
SaifReader(const char *filename,
|
||||||
const char *scope,
|
const char *scope,
|
||||||
Sta *sta);
|
Sta *sta);
|
||||||
~SaifReader();
|
|
||||||
bool read();
|
bool read();
|
||||||
|
|
||||||
void setDivider(char divider);
|
void setDivider(char divider);
|
||||||
|
|
@ -72,24 +67,7 @@ public:
|
||||||
void instancePop();
|
void instancePop();
|
||||||
void setNetDurations(const char *net_name,
|
void setNetDurations(const char *net_name,
|
||||||
SaifStateDurations &durations);
|
SaifStateDurations &durations);
|
||||||
|
|
||||||
// flex YY_INPUT yy_n_chars arg changed definition from int to size_t,
|
|
||||||
// so provide both forms.
|
|
||||||
void getChars(char *buf,
|
|
||||||
size_t &result,
|
|
||||||
size_t max_size);
|
|
||||||
void getChars(char *buf,
|
|
||||||
int &result,
|
|
||||||
size_t max_size);
|
|
||||||
void incrLine();
|
|
||||||
const char *filename() { return filename_; }
|
const char *filename() { return filename_; }
|
||||||
int line() { return line_; }
|
|
||||||
void saifWarn(int id,
|
|
||||||
const char *fmt, ...);
|
|
||||||
void saifError(int id,
|
|
||||||
const char *fmt,
|
|
||||||
...);
|
|
||||||
void notSupported(const char *feature);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string unescaped(const char *token);
|
string unescaped(const char *token);
|
||||||
|
|
@ -97,8 +75,6 @@ private:
|
||||||
const char *filename_;
|
const char *filename_;
|
||||||
const char *scope_; // Divider delimited scope to begin annotation.
|
const char *scope_; // Divider delimited scope to begin annotation.
|
||||||
|
|
||||||
gzFile stream_;
|
|
||||||
int line_;
|
|
||||||
char divider_;
|
char divider_;
|
||||||
char escape_;
|
char escape_;
|
||||||
double timescale_;
|
double timescale_;
|
||||||
|
|
@ -111,6 +87,4 @@ private:
|
||||||
Power *power_;
|
Power *power_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SaifReader *saif_reader;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2025, 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/>.
|
||||||
|
//
|
||||||
|
// The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software.
|
||||||
|
//
|
||||||
|
// Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SaifLocation.hh"
|
||||||
|
#include "SaifParse.hh"
|
||||||
|
|
||||||
|
#ifndef __FLEX_LEXER_H
|
||||||
|
#undef yyFlexLexer
|
||||||
|
#define yyFlexLexer SaifFlexLexer
|
||||||
|
#include <FlexLexer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
class Report;
|
||||||
|
|
||||||
|
class SaifScanner : public SaifFlexLexer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SaifScanner(std::istream *stream,
|
||||||
|
const string &filename,
|
||||||
|
SaifReader *reader,
|
||||||
|
Report *report);
|
||||||
|
virtual ~SaifScanner() {}
|
||||||
|
|
||||||
|
virtual int lex(SaifParse::semantic_type *const yylval,
|
||||||
|
SaifParse::location_type *yylloc);
|
||||||
|
// YY_DECL defined in SaifLex.ll
|
||||||
|
// Method body created by flex in SaifLex.cc
|
||||||
|
|
||||||
|
void error(const char *msg);
|
||||||
|
|
||||||
|
// Get rid of override virtual function warning.
|
||||||
|
using FlexLexer::yylex;
|
||||||
|
|
||||||
|
private:
|
||||||
|
string filename_;
|
||||||
|
SaifReader *reader_;
|
||||||
|
Report *report_;
|
||||||
|
string token_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -33,6 +33,14 @@
|
||||||
|
|
||||||
// warning: variable 'yynerrs_' set but not used
|
// warning: variable 'yynerrs_' set but not used
|
||||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
|
|
||||||
|
void
|
||||||
|
sta::SdfParse::error(const location_type &loc,
|
||||||
|
const string &msg)
|
||||||
|
{
|
||||||
|
reader->report()->fileError(164,reader->filename().c_str(),
|
||||||
|
loc.begin.line,"%s",msg.c_str());
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%require "3.2"
|
%require "3.2"
|
||||||
|
|
@ -44,11 +52,7 @@
|
||||||
%define parse.assert
|
%define parse.assert
|
||||||
%parse-param { SdfScanner *scanner }
|
%parse-param { SdfScanner *scanner }
|
||||||
%parse-param { SdfReader *reader }
|
%parse-param { SdfReader *reader }
|
||||||
|
%define api.parser.class {SdfParse}
|
||||||
// bison 3.0.4 for centos7
|
|
||||||
%define parser_class_name {SdfParse}
|
|
||||||
// bison 3.3.2
|
|
||||||
//%define api.parser.class {SdfParse}
|
|
||||||
|
|
||||||
// expected shift/reduce conflicts
|
// expected shift/reduce conflicts
|
||||||
%expect 4
|
%expect 4
|
||||||
|
|
|
||||||
|
|
@ -1103,14 +1103,4 @@ SdfScanner::error(const char *msg)
|
||||||
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void
|
|
||||||
SdfParse::error(const location_type &loc,
|
|
||||||
const string &msg)
|
|
||||||
{
|
|
||||||
reader->report()->fileError(164,reader->filename().c_str(),
|
|
||||||
loc.begin.line,"%s",msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "SdfLocation.hh"
|
||||||
|
#include "SdfParse.hh"
|
||||||
|
|
||||||
#ifndef __FLEX_LEXER_H
|
#ifndef __FLEX_LEXER_H
|
||||||
#undef yyFlexLexer
|
#undef yyFlexLexer
|
||||||
#define yyFlexLexer SdfFlexLexer
|
#define yyFlexLexer SdfFlexLexer
|
||||||
#include <FlexLexer.h>
|
#include <FlexLexer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "SdfLocation.hh"
|
|
||||||
#include "SdfParse.hh"
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
class Report;
|
class Report;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ void
|
||||||
sta::VerilogParse::error(const location_type &loc,
|
sta::VerilogParse::error(const location_type &loc,
|
||||||
const string &msg)
|
const string &msg)
|
||||||
{
|
{
|
||||||
reader->report()->fileError(164,reader->filename(),loc.begin.line,"%s",msg.c_str());
|
reader->report()->fileError(164,reader->filename(),loc.begin.line,
|
||||||
|
"%s",msg.c_str());
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
@ -57,11 +58,7 @@ sta::VerilogParse::error(const location_type &loc,
|
||||||
%define parse.assert
|
%define parse.assert
|
||||||
%parse-param { VerilogScanner *scanner }
|
%parse-param { VerilogScanner *scanner }
|
||||||
%parse-param { VerilogReader *reader }
|
%parse-param { VerilogReader *reader }
|
||||||
|
%define api.parser.class {VerilogParse}
|
||||||
// bison 3.0.4 for centos7
|
|
||||||
%define parser_class_name {VerilogParse}
|
|
||||||
// bison 3.3.2
|
|
||||||
//%define api.parser.class {VerilogParse}
|
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
int ival;
|
int ival;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,299 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2025, 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/>.
|
||||||
|
//
|
||||||
|
// The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software.
|
||||||
|
//
|
||||||
|
// Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "StringSet.hh"
|
||||||
|
#include "Vector.hh"
|
||||||
|
#include "Map.hh"
|
||||||
|
#include "NetworkClass.hh"
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
class VerilogScanner;
|
||||||
|
class VerilogParse;
|
||||||
|
class Debug;
|
||||||
|
class Report;
|
||||||
|
class VerilogAttrEntry;
|
||||||
|
class VerilogAttrStmt;
|
||||||
|
class VerilogReader;
|
||||||
|
class VerilogStmt;
|
||||||
|
class VerilogNet;
|
||||||
|
class VerilogNetScalar;
|
||||||
|
class VerilogModule;
|
||||||
|
class VerilogInst;
|
||||||
|
class VerilogModuleInst;
|
||||||
|
class VerilogLibertyInst;
|
||||||
|
class VerilogDcl;
|
||||||
|
class VerilogDclBus;
|
||||||
|
class VerilogDclArg;
|
||||||
|
class VerilogAssign;
|
||||||
|
class VerilogNetConcat;
|
||||||
|
class VerilogNetConstant;
|
||||||
|
class VerilogNetBitSelect;
|
||||||
|
class VerilogNetPartSelect;
|
||||||
|
class StringRegistry;
|
||||||
|
class VerilogBindingTbl;
|
||||||
|
class VerilogNetNameIterator;
|
||||||
|
class VerilogNetPortRef;
|
||||||
|
class VerilogError;
|
||||||
|
class LibertyCell;
|
||||||
|
|
||||||
|
typedef Map<Cell*, VerilogModule*> VerilogModuleMap;
|
||||||
|
typedef Vector<VerilogStmt*> VerilogStmtSeq;
|
||||||
|
typedef Vector<VerilogNet*> VerilogNetSeq;
|
||||||
|
typedef Vector<VerilogDclArg*> VerilogDclArgSeq;
|
||||||
|
typedef Vector<VerilogAttrStmt*> VerilogAttrStmtSeq;
|
||||||
|
typedef Vector<VerilogAttrEntry*> VerilogAttrEntrySeq;
|
||||||
|
typedef Vector<VerilogError*> VerilogErrorSeq;
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
using std::set;
|
||||||
|
|
||||||
|
class VerilogReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VerilogReader(NetworkReader *network);
|
||||||
|
~VerilogReader();
|
||||||
|
bool read(const char *filename);
|
||||||
|
|
||||||
|
void makeModule(const string *module_name,
|
||||||
|
VerilogNetSeq *ports,
|
||||||
|
VerilogStmtSeq *stmts,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
int line);
|
||||||
|
void makeModule(const string *module_name,
|
||||||
|
VerilogStmtSeq *port_dcls,
|
||||||
|
VerilogStmtSeq *stmts,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
int line);
|
||||||
|
VerilogDcl *makeDcl(PortDirection *dir,
|
||||||
|
VerilogDclArgSeq *args,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
int line);
|
||||||
|
VerilogDcl *makeDcl(PortDirection *dir,
|
||||||
|
VerilogDclArg *arg,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
int line);
|
||||||
|
VerilogDclArg *makeDclArg(const string *net_name);
|
||||||
|
VerilogDclArg*makeDclArg(VerilogAssign *assign);
|
||||||
|
VerilogDclBus *makeDclBus(PortDirection *dir,
|
||||||
|
int from_index,
|
||||||
|
int to_index,
|
||||||
|
VerilogDclArg *arg,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
int line);
|
||||||
|
VerilogDclBus *makeDclBus(PortDirection *dir,
|
||||||
|
int from_index,
|
||||||
|
int to_index,
|
||||||
|
VerilogDclArgSeq *args,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
int line);
|
||||||
|
VerilogInst *makeModuleInst(const string *module_name,
|
||||||
|
const string *inst_name,
|
||||||
|
VerilogNetSeq *pins,
|
||||||
|
VerilogAttrStmtSeq *attr_stmts,
|
||||||
|
const int line);
|
||||||
|
VerilogAssign *makeAssign(VerilogNet *lhs,
|
||||||
|
VerilogNet *rhs,
|
||||||
|
int line);
|
||||||
|
VerilogNetScalar *makeNetScalar(const string *name);
|
||||||
|
VerilogNetPortRef *makeNetNamedPortRefScalarNet(const string *port_vname);
|
||||||
|
VerilogNetPortRef *makeNetNamedPortRefScalarNet(const string *port_name,
|
||||||
|
const string *net_name);
|
||||||
|
VerilogNetPortRef *makeNetNamedPortRefBitSelect(const string *port_name,
|
||||||
|
const string *bus_name,
|
||||||
|
int index);
|
||||||
|
VerilogNetPortRef *makeNetNamedPortRefScalar(const string *port_name,
|
||||||
|
VerilogNet *net);
|
||||||
|
VerilogNetPortRef *makeNetNamedPortRefBit(const string *port_name,
|
||||||
|
int index,
|
||||||
|
VerilogNet *net);
|
||||||
|
VerilogNetPortRef *makeNetNamedPortRefPart(const string *port_name,
|
||||||
|
int from_index,
|
||||||
|
int to_index,
|
||||||
|
VerilogNet *net);
|
||||||
|
VerilogNetConcat *makeNetConcat(VerilogNetSeq *nets);
|
||||||
|
VerilogNetConstant *makeNetConstant(const string *constant,
|
||||||
|
int line);
|
||||||
|
VerilogNetBitSelect *makeNetBitSelect(const string *name,
|
||||||
|
int index);
|
||||||
|
VerilogNetPartSelect *makeNetPartSelect(const string *name,
|
||||||
|
int from_index,
|
||||||
|
int to_index);
|
||||||
|
VerilogModule *module(Cell *cell);
|
||||||
|
Instance *linkNetwork(const char *top_cell_name,
|
||||||
|
bool make_black_boxes);
|
||||||
|
const char *filename() const { return filename_.c_str(); }
|
||||||
|
void incrLine();
|
||||||
|
Report *report() const { return report_; }
|
||||||
|
void error(int id,
|
||||||
|
const char *filename,
|
||||||
|
int line,
|
||||||
|
const char *fmt, ...);
|
||||||
|
void warn(int id,
|
||||||
|
const char *filename,
|
||||||
|
int line,
|
||||||
|
const char *fmt, ...);
|
||||||
|
const string &zeroNetName() const { return zero_net_name_; }
|
||||||
|
const string &oneNetName() const { return one_net_name_; }
|
||||||
|
void deleteModules();
|
||||||
|
void reportStmtCounts();
|
||||||
|
const string &constant10Max() const { return constant10_max_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void init(const char *filename);
|
||||||
|
void makeCellPorts(Cell *cell,
|
||||||
|
VerilogModule *module,
|
||||||
|
VerilogNetSeq *ports);
|
||||||
|
Port *makeCellPort(Cell *cell,
|
||||||
|
VerilogModule *module,
|
||||||
|
const string &port_name);
|
||||||
|
void makeNamedPortRefCellPorts(Cell *cell,
|
||||||
|
VerilogModule *module,
|
||||||
|
VerilogNet *mod_port,
|
||||||
|
StdStringSet &port_names);
|
||||||
|
void checkModuleDcls(VerilogModule *module,
|
||||||
|
set<string> &port_names);
|
||||||
|
void makeModuleInstBody(VerilogModule *module,
|
||||||
|
Instance *inst,
|
||||||
|
VerilogBindingTbl *bindings,
|
||||||
|
bool make_black_boxes);
|
||||||
|
void makeModuleInstNetwork(VerilogModuleInst *mod_inst,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogModule *parent_module,
|
||||||
|
VerilogBindingTbl *parent_bindings,
|
||||||
|
bool make_black_boxes);
|
||||||
|
void makeLibertyInst(VerilogLibertyInst *lib_inst,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogModule *parent_module,
|
||||||
|
VerilogBindingTbl *parent_bindings);
|
||||||
|
void bindGlobalNets(VerilogBindingTbl *bindings);
|
||||||
|
void makeNamedInstPins1(Cell *cell,
|
||||||
|
Instance *inst,
|
||||||
|
VerilogModuleInst *mod_inst,
|
||||||
|
VerilogBindingTbl *bindings,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogBindingTbl *parent_bindings,
|
||||||
|
bool is_leaf);
|
||||||
|
void makeNamedInstPins(Cell *cell,
|
||||||
|
Instance *inst,
|
||||||
|
VerilogModuleInst *mod_inst,
|
||||||
|
VerilogBindingTbl *bindings,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogModule *parent_module,
|
||||||
|
VerilogBindingTbl *parent_bindings,
|
||||||
|
bool is_leaf);
|
||||||
|
void makeOrderedInstPins(Cell *cell,
|
||||||
|
Instance *inst,
|
||||||
|
VerilogModuleInst *mod_inst,
|
||||||
|
VerilogBindingTbl *bindings,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogModule *parent_module,
|
||||||
|
VerilogBindingTbl *parent_bindings,
|
||||||
|
bool is_leaf);
|
||||||
|
void mergeAssignNet(VerilogAssign *assign,
|
||||||
|
VerilogModule *module,
|
||||||
|
Instance *inst,
|
||||||
|
VerilogBindingTbl *bindings);
|
||||||
|
void makeInstPin(Instance *inst,
|
||||||
|
Port *port,
|
||||||
|
VerilogNetNameIterator *net_name_iter,
|
||||||
|
VerilogBindingTbl *bindings,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogBindingTbl *parent_bindings,
|
||||||
|
bool is_leaf);
|
||||||
|
void makeInstPin(Instance *inst,
|
||||||
|
Port *port,
|
||||||
|
const string &net_name,
|
||||||
|
VerilogBindingTbl *bindings,
|
||||||
|
Instance *parent,
|
||||||
|
VerilogBindingTbl *parent_bindings,
|
||||||
|
bool is_leaf);
|
||||||
|
void linkWarn(int id,
|
||||||
|
const char *filename,
|
||||||
|
int line,
|
||||||
|
const char *msg, ...)
|
||||||
|
__attribute__((format (printf, 5, 6)));
|
||||||
|
void linkError(int id,
|
||||||
|
const char *filename,
|
||||||
|
int line,
|
||||||
|
const char *msg, ...)
|
||||||
|
__attribute__((format (printf, 5, 6)));
|
||||||
|
bool reportLinkErrors();
|
||||||
|
bool haveLinkErrors();
|
||||||
|
Cell *makeBlackBox(VerilogModuleInst *mod_inst,
|
||||||
|
VerilogModule *parent_module);
|
||||||
|
void makeBlackBoxNamedPorts(Cell *cell,
|
||||||
|
VerilogModuleInst *mod_inst,
|
||||||
|
VerilogModule *parent_module);
|
||||||
|
void makeBlackBoxOrderedPorts(Cell *cell,
|
||||||
|
VerilogModuleInst *mod_inst,
|
||||||
|
VerilogModule *parent_module);
|
||||||
|
bool isBlackBox(Cell *cell);
|
||||||
|
bool hasScalarNamedPortRefs(LibertyCell *liberty_cell,
|
||||||
|
VerilogNetSeq *pins);
|
||||||
|
|
||||||
|
string filename_;
|
||||||
|
Report *report_;
|
||||||
|
Debug *debug_;
|
||||||
|
NetworkReader *network_;
|
||||||
|
|
||||||
|
Library *library_;
|
||||||
|
int black_box_index_;
|
||||||
|
VerilogModuleMap module_map_;
|
||||||
|
VerilogErrorSeq link_errors_;
|
||||||
|
const string zero_net_name_;
|
||||||
|
const string one_net_name_;
|
||||||
|
string constant10_max_;
|
||||||
|
ViewType *view_type_;
|
||||||
|
bool report_stmt_stats_;
|
||||||
|
int module_count_;
|
||||||
|
int inst_mod_count_;
|
||||||
|
int inst_lib_count_;
|
||||||
|
int inst_lib_net_arrays_;
|
||||||
|
int port_names_;
|
||||||
|
int inst_module_names_;
|
||||||
|
int inst_names_;
|
||||||
|
int dcl_count_;
|
||||||
|
int dcl_bus_count_;
|
||||||
|
int dcl_arg_count_;
|
||||||
|
int net_scalar_count_;
|
||||||
|
int net_scalar_names_;
|
||||||
|
int net_bus_names_;
|
||||||
|
int net_part_select_count_;
|
||||||
|
int net_bit_select_count_;
|
||||||
|
int net_port_ref_scalar_count_;
|
||||||
|
int net_port_ref_scalar_net_count_;
|
||||||
|
int net_port_ref_bit_count_;
|
||||||
|
int net_port_ref_part_count_;
|
||||||
|
int net_constant_count_;
|
||||||
|
int assign_count_;
|
||||||
|
int concat_count_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sta
|
||||||
|
|
@ -24,15 +24,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VerilogLocation.hh"
|
||||||
|
#include "VerilogParse.hh"
|
||||||
|
|
||||||
#ifndef __FLEX_LEXER_H
|
#ifndef __FLEX_LEXER_H
|
||||||
#undef yyFlexLexer
|
#undef yyFlexLexer
|
||||||
#define yyFlexLexer VerilogFlexLexer
|
#define yyFlexLexer VerilogFlexLexer
|
||||||
#include <FlexLexer.h>
|
#include <FlexLexer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "VerilogLocation.hh"
|
|
||||||
#include "VerilogParse.hh"
|
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
class Report;
|
class Report;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue