merged from latest OSTA master
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
commit
6bf6e84df6
|
|
@ -0,0 +1,80 @@
|
|||
Checks: >
|
||||
clang-diagnostic-*,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-core.NonNullParamChecker,
|
||||
-clang-analyzer-core.CallAndMessage,
|
||||
-clang-analyzer-core.uninitialized.UndefReturn,
|
||||
-clang-analyzer-cplusplus.NewDeleteLeaks,
|
||||
-clang-analyzer-optin.performance.Padding,
|
||||
readability-*,
|
||||
-readability-identifier-naming,
|
||||
-readability-braces-around-statements,
|
||||
-readability-convert-member-functions-to-static,
|
||||
-readability-else-after-return,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-inconsistent-ifelse-braces,
|
||||
-readability-identifier-length,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-isolate-declaration,
|
||||
-readability-magic-numbers,
|
||||
-readability-make-member-function-const,
|
||||
-readability-math-missing-parentheses,
|
||||
-readability-named-parameter,
|
||||
-readability-qualified-auto,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-simplify-boolean-expr,
|
||||
-readability-static-definition-in-anonymous-namespace,
|
||||
-readability-suspicious-call-argument,
|
||||
-readability-uppercase-literal-suffix,
|
||||
-readability-use-anyofallof,
|
||||
google-*,
|
||||
-google-readability-avoid-underscore-in-googletest-name,
|
||||
-google-readability-braces-around-statements,
|
||||
-google-readability-casting,
|
||||
-google-readability-todo,
|
||||
-google-runtime-references,
|
||||
-google-explicit-constructor,
|
||||
performance-*,
|
||||
-performance-enum-size,
|
||||
bugprone-*,
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-exception-escape,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-move-forwarding-reference,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-suspicious-missing-comma,
|
||||
-bugprone-throwing-static-initialization,
|
||||
modernize-*,
|
||||
-modernize-avoid-bind,
|
||||
-modernize-avoid-c-arrays,
|
||||
-modernize-concat-nested-namespaces,
|
||||
-modernize-macro-to-enum,
|
||||
-modernize-pass-by-value,
|
||||
-modernize-raw-string-literal,
|
||||
-modernize-return-braced-init-list,
|
||||
-modernize-use-auto,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-use-trailing-return-type,
|
||||
-modernize-use-transparent-functors,
|
||||
misc-*,
|
||||
-misc-const-correctness,
|
||||
-misc-multiple-inheritance,
|
||||
-misc-no-recursion,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-misc-redundant-expression,
|
||||
-misc-unused-parameters,
|
||||
-misc-use-anonymous-namespace,
|
||||
-misc-use-internal-linkage,
|
||||
-misc-include-cleaner
|
||||
|
||||
# Only report diagnostics in headers under this tree (app/, include/sta/, build-generated
|
||||
# headers, etc.).
|
||||
# Excludes system and third-party paths such as /opt/local/include.
|
||||
HeaderFilterRegex: '.*/(app|cmake|dcalc|graph|liberty|network|parasitics|power|sdc|sdf|search|spice|tcl|util|verilog|include/sta|build/include/sta)/.*'
|
||||
|
||||
# util/gzstream.hh
|
||||
# util/FlexDisableRegister.hh
|
||||
# Bison-generated parser headers (build/{Liberty,Verilog,...}Parse.hh)
|
||||
ExcludeHeaderFilterRegex: '(.*/)?(gzstream\.hh|FlexDisableRegister\.hh|(Liberty|Verilog|Sdf|Spef|Saif|LibExpr)Parse\.hh)$'
|
||||
FormatStyle: none
|
||||
|
|
@ -31,3 +31,29 @@ alwaysApply: false
|
|||
|
||||
- C++ source: `.cc`
|
||||
- C++ headers: `.hh`
|
||||
|
||||
## Include order
|
||||
|
||||
Sort `#include` lines **lexicographically by the path inside** `<>`
|
||||
or `""` (case-sensitive). Separate **groups** with a single blank line.
|
||||
|
||||
### Translation units (`*.cc`)
|
||||
|
||||
1. **Primary header(s)** for this file only:
|
||||
- `#include "Stem.hh"` where `Stem` matches the basename of the `.cc` file (e.g. `Foo.cc` → `Foo.hh`).
|
||||
- If the file uses a paired private header, include `#include "StemPvt.hh"` **immediately after** `Stem.hh` (e.g. `MakeTimingModel.cc` → `MakeTimingModel.hh` then `MakeTimingModelPvt.hh`).
|
||||
- Do **not** pull in other headers just because their names share a prefix with `Stem` (e.g. `SearchClass.hh` is not a “primary” include for `Search.cc`; it belongs in the project group below).
|
||||
|
||||
2. **System / standard library** headers: `#include <...>` lines, sorted alphabetically.
|
||||
|
||||
3. **All other project** headers: `#include "..."` lines, sorted alphabetically (including `search/Crpr.hh`-style paths and includes from `liberty/`, etc.).
|
||||
|
||||
If a **comment or special block** intentionally splits the include list (e.g. a third-party note before `#include "cudd.h"`), keep that structure; sort only within each contiguous run of `#include` lines unless merging groups is clearly safe.
|
||||
|
||||
### Headers (`*.hh`)
|
||||
|
||||
After `#pragma once` (and the file’s license block, if present):
|
||||
|
||||
1. **System** `#include <...>` lines, sorted alphabetically.
|
||||
|
||||
2. **Project** `#include "..."` lines, sorted alphabetically.
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ jobs:
|
|||
name: artifact
|
||||
path: |
|
||||
build/install/*
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload Test Result
|
||||
uses: actions/upload-artifact@v7
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
name: Check that OK files are up to date
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
No-Diffs-In-Ok-Files:
|
||||
runs-on: ${{ vars.USE_SELF_HOSTED == 'true' && 'self-hosted' || 'ubuntu-latest' }}
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Check ok files
|
||||
run: |
|
||||
set +e
|
||||
grep --include="*.ok" -Rn "Differences found "
|
||||
if [[ "$?" == "0" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -30,3 +30,7 @@ doc/messages.txt
|
|||
|
||||
# clangd turds
|
||||
.cache/
|
||||
|
||||
# test artifacts
|
||||
*/test/*.log
|
||||
**/Testing/
|
||||
|
|
|
|||
21
BUILD
21
BUILD
|
|
@ -272,7 +272,6 @@ cc_binary(
|
|||
"app/Main.cc",
|
||||
":StaApp",
|
||||
":StaTclInitVar",
|
||||
"//bazel:runfiles",
|
||||
],
|
||||
copts = [
|
||||
"-Wno-error",
|
||||
|
|
@ -297,6 +296,8 @@ cc_binary(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":opensta_lib",
|
||||
"//:tcl_readline_setup",
|
||||
"//bazel:tcl_library_init",
|
||||
"@rules_cc//cc/runfiles",
|
||||
"@tcl_lang//:tcl",
|
||||
],
|
||||
|
|
@ -338,15 +339,13 @@ cc_library(
|
|||
],
|
||||
) + [
|
||||
"app/StaMain.cc",
|
||||
"util/Machine.cc",
|
||||
":StaConfig",
|
||||
],
|
||||
#+ select({
|
||||
# "@bazel_tools//src/conditions:windows": ["util/MachineWin32.cc"],
|
||||
# "@bazel_tools//src/conditions:darwin": ["util/MachineApple.cc"],
|
||||
# "@bazel_tools//src/conditions:linux": ["util/MachineLinux.cc"],
|
||||
# "//conditions:default": ["util/MachineUnknown.cc"],
|
||||
# })
|
||||
] + select({
|
||||
"@platforms//os:osx": ["util/MachineApple.cc"],
|
||||
"@platforms//os:linux": ["util/MachineLinux.cc"],
|
||||
"@platforms//os:windows": ["util/MachineWin32.cc"],
|
||||
"//conditions:default": ["util/MachineUnknown.cc"],
|
||||
}),
|
||||
hdrs = glob(
|
||||
include = ["include/sta/*.hh"],
|
||||
) + [
|
||||
|
|
@ -392,10 +391,6 @@ cc_library(
|
|||
"util",
|
||||
"verilog",
|
||||
],
|
||||
textual_hdrs = select({
|
||||
"@platforms//os:osx": ["util/MachineApple.cc"],
|
||||
"//conditions:default": ["util/MachineLinux.cc"],
|
||||
}),
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"@cudd",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# OpenSTA, Static Timing Analyzer
|
||||
# Copyright (c) 2025, Parallax Software, Inc.
|
||||
# Copyright (c) 2026, 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
|
||||
|
|
@ -36,6 +36,9 @@ option(ENABLE_ASAN "Compile with address santizer enabled" OFF)
|
|||
# Turn on to debug compiler args.
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# Write compile_commands.json to the build directory for clang-tidy.
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(STA_HOME ${PROJECT_SOURCE_DIR})
|
||||
message(STATUS "STA version: ${PROJECT_VERSION}")
|
||||
|
||||
|
|
@ -219,7 +222,6 @@ set(STA_SOURCE
|
|||
util/Error.cc
|
||||
util/Fuzzy.cc
|
||||
util/Hash.cc
|
||||
util/Machine.cc
|
||||
util/MinMax.cc
|
||||
util/PatternMatch.cc
|
||||
util/Report.cc
|
||||
|
|
@ -236,6 +238,16 @@ set(STA_SOURCE
|
|||
verilog/VerilogWriter.cc
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND STA_SOURCE util/MachineApple.cc)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
list(APPEND STA_SOURCE util/MachineLinux.cc)
|
||||
elseif(WIN32)
|
||||
list(APPEND STA_SOURCE util/MachineWin32.cc)
|
||||
else()
|
||||
list(APPEND STA_SOURCE util/MachineUnknown.cc)
|
||||
endif()
|
||||
|
||||
# Source files.
|
||||
set(STA_TCL_FILES
|
||||
tcl/Init.tcl
|
||||
|
|
@ -598,13 +610,13 @@ set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls
|
|||
if(ENABLE_TSAN)
|
||||
message(STATUS "Thread sanitizer: ${ENABLE_TSAN}")
|
||||
set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=thread")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=thread")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=thread")
|
||||
endif()
|
||||
|
||||
if(ENABLE_ASAN)
|
||||
message(STATUS "Address sanitizer: ${ENABLE_ASAN}")
|
||||
set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=address")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=address")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=address")
|
||||
endif()
|
||||
|
||||
target_compile_options(OpenSTA
|
||||
|
|
@ -630,6 +642,7 @@ message(STATUS "STA library: ${CMAKE_BINARY_DIR}/libOpenSTA.a")
|
|||
add_executable(sta app/Main.cc)
|
||||
|
||||
target_link_libraries(sta
|
||||
PRIVATE
|
||||
sta_swig
|
||||
OpenSTA
|
||||
)
|
||||
|
|
|
|||
25
app/Main.cc
25
app/Main.cc
|
|
@ -30,6 +30,12 @@
|
|||
#include <filesystem>
|
||||
#include <string_view>
|
||||
#include <tcl.h>
|
||||
|
||||
#ifdef BAZEL_CURRENT_REPOSITORY
|
||||
#include "bazel/tcl_library_init.h"
|
||||
#include "src/tcl_readline_setup.h"
|
||||
#endif
|
||||
|
||||
#if TCL_READLINE
|
||||
#include <tclreadline.h>
|
||||
#endif
|
||||
|
|
@ -109,16 +115,28 @@ staTclAppInit(int argc,
|
|||
std::string_view init_filename,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
#ifdef BAZEL_CURRENT_REPOSITORY
|
||||
if (in_bazel::SetupTclEnvironment(interp) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// source init.tcl
|
||||
if (Tcl_Init(interp) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
|
||||
bool has_readline = false;
|
||||
#ifdef BAZEL_CURRENT_REPOSITORY
|
||||
has_readline = (ord::SetupTclReadlineLibrary(interp) == TCL_OK);
|
||||
#endif
|
||||
#if TCL_READLINE
|
||||
if (Tclreadline_Init(interp) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
Tcl_StaticPackage(interp, "tclreadline", Tclreadline_Init, Tclreadline_SafeInit);
|
||||
if (Tcl_EvalFile(interp, TCLRL_LIBRARY "/tclreadlineInit.tcl") != TCL_OK)
|
||||
printf("Failed to load tclreadline.tcl\n");
|
||||
else
|
||||
has_readline = true;
|
||||
#endif
|
||||
|
||||
initStaApp(argc, argv, interp);
|
||||
|
|
@ -156,11 +174,8 @@ staTclAppInit(int argc,
|
|||
}
|
||||
}
|
||||
}
|
||||
#if TCL_READLINE
|
||||
return Tcl_Eval(interp, "::tclreadline::Loop");
|
||||
#else
|
||||
return TCL_OK;
|
||||
#endif
|
||||
|
||||
return has_readline ? Tcl_Eval(interp, "::tclreadline::Loop") : TCL_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -148,4 +148,4 @@ unencode(const char *inits[])
|
|||
return unencoded;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
# searching OSX system directories before unix directories.
|
||||
|
||||
set(TCL_POSSIBLE_NAMES
|
||||
#tcl90 tcl9.0
|
||||
tcl87 tcl8.7
|
||||
tcl86 tcl8.6
|
||||
tcl85 tcl8.5
|
||||
|
|
@ -32,6 +33,7 @@ set(TCL_POSSIBLE_NAMES
|
|||
if (NOT TCL_LIB_PATHS)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(TCL_LIB_PATHS
|
||||
#/opt/homebrew/Cellar/tcl-tk/9.0.3/lib
|
||||
/opt/homebrew/Cellar/tcl-tk@8/8.6.17/lib
|
||||
/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib
|
||||
/opt/homebrew/opt/tcl-tk/lib /usr/local/lib)
|
||||
|
|
|
|||
|
|
@ -22,16 +22,16 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ArcDcalcWaveforms.hh"
|
||||
|
||||
#include "Report.hh"
|
||||
#include <memory>
|
||||
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "Graph.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Report.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -83,4 +83,4 @@ ArcDcalcWaveforms::inputWaveform(ArcDcalcArg &dcalc_arg,
|
|||
return Waveform();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -51,5 +51,5 @@ protected:
|
|||
const StaState *sta);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@
|
|||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include "StringUtil.hh"
|
||||
#include "Units.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Units.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ ArcDcalcArg::ArcDcalcArg(const Pin *in_pin,
|
|||
const Pin *drvr_pin,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
const Slew in_slew,
|
||||
Slew in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic) :
|
||||
in_pin_(in_pin),
|
||||
|
|
@ -165,17 +165,7 @@ ArcDcalcArg::ArcDcalcArg(const Pin *in_pin,
|
|||
{
|
||||
}
|
||||
|
||||
ArcDcalcArg::ArcDcalcArg(const ArcDcalcArg &arg) :
|
||||
in_pin_(arg.in_pin_),
|
||||
drvr_pin_(arg.drvr_pin_),
|
||||
edge_(arg.edge_),
|
||||
arc_(arg.arc_),
|
||||
in_slew_(arg.in_slew_),
|
||||
load_cap_(arg.load_cap_),
|
||||
parasitic_(arg.parasitic_),
|
||||
input_delay_(arg.input_delay_)
|
||||
{
|
||||
}
|
||||
ArcDcalcArg::ArcDcalcArg(const ArcDcalcArg &arg) = default;
|
||||
|
||||
const RiseFall *
|
||||
ArcDcalcArg::inEdge() const
|
||||
|
|
@ -305,4 +295,4 @@ ArcDcalcResult::setLoadSlew(size_t load_idx,
|
|||
load_slews_[load_idx] = load_slew;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class arnoldi1
|
|||
public:
|
||||
arnoldi1() { order=0; n=0; d=nullptr; e=nullptr; U=nullptr; ctot=0.0; sqc=0.0; }
|
||||
~arnoldi1();
|
||||
double elmore(int term_index);
|
||||
double elmore(int k);
|
||||
|
||||
//
|
||||
// calculate poles/residues for given rdrive
|
||||
|
|
@ -70,12 +70,12 @@ class rcmodel : public ConcreteParasitic,
|
|||
{
|
||||
public:
|
||||
rcmodel();
|
||||
virtual ~rcmodel();
|
||||
virtual float capacitance() const;
|
||||
virtual PinSet unannotatedLoads(const Pin *drvr_pin,
|
||||
const Parasitics *parasitics) const;
|
||||
~rcmodel() override;
|
||||
float capacitance() const override;
|
||||
PinSet unannotatedLoads(const Pin *drvr_pin,
|
||||
const Parasitics *parasitics) const override;
|
||||
|
||||
const Pin **pinV; // [n]
|
||||
const Pin **pinV{nullptr}; // [n]
|
||||
};
|
||||
|
||||
struct timing_table
|
||||
|
|
@ -86,4 +86,4 @@ struct timing_table
|
|||
float in_slew;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -28,30 +28,34 @@
|
|||
|
||||
#include "ArnoldiDelayCalc.hh"
|
||||
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <cmath> // abs
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <numbers>
|
||||
|
||||
#include "Report.hh"
|
||||
#include "Debug.hh"
|
||||
#include "Units.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "TimingModel.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "DelayCalc.hh"
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Variables.hh"
|
||||
#include "Arnoldi.hh"
|
||||
#include "ArnoldiReduce.hh"
|
||||
#include "Debug.hh"
|
||||
#include "DelayCalc.hh"
|
||||
#include "Graph.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Report.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TimingModel.hh"
|
||||
#include "Units.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
// NOLINTBEGIN(modernize-avoid-c-style-cast)
|
||||
|
||||
// wireload8 is n^2
|
||||
// do not delete arnoldi parasitics
|
||||
|
|
@ -76,7 +80,11 @@ delay_work_get_residues(delay_work *D,
|
|||
int term_index);
|
||||
|
||||
static bool
|
||||
tridiagEV(int n,double *d,double *e,double *p,double **v);
|
||||
tridiagEV(int n,
|
||||
const double *din,
|
||||
const double *ein,
|
||||
double *d,
|
||||
double **v);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -229,14 +237,13 @@ private:
|
|||
double *c_x1,
|
||||
double *c_y1);
|
||||
|
||||
rcmodel *rcmodel_;
|
||||
rcmodel *rcmodel_{nullptr};
|
||||
int _pinNmax;
|
||||
double *_delayV;
|
||||
double *_slewV;
|
||||
int pin_n_;
|
||||
ArnoldiReduce *reduce_;
|
||||
delay_work *delay_work_;
|
||||
std::vector<rcmodel*> unsaved_parasitics_;
|
||||
};
|
||||
|
||||
ArcDelayCalc *
|
||||
|
|
@ -267,6 +274,7 @@ ArnoldiDelayCalc::~ArnoldiDelayCalc()
|
|||
free(_delayV);
|
||||
free(_slewV);
|
||||
delete reduce_;
|
||||
delete rcmodel_;
|
||||
}
|
||||
|
||||
Parasitic *
|
||||
|
|
@ -297,12 +305,11 @@ ArnoldiDelayCalc::findParasitic(const Pin *drvr_pin,
|
|||
}
|
||||
|
||||
if (parasitic_network) {
|
||||
rcmodel *rcmodel = reduce_->reduceToArnoldi(parasitic_network, drvr_pin,
|
||||
parasitics->couplingCapFactor(),
|
||||
drvr_rf, scene, min_max);
|
||||
rcmodel_ = reduce_->reduceToArnoldi(parasitic_network, drvr_pin,
|
||||
parasitics->couplingCapFactor(),
|
||||
drvr_rf, scene, min_max);
|
||||
// Arnoldi parasitics are their own class that are not saved in the parasitic db.
|
||||
unsaved_parasitics_.push_back(rcmodel);
|
||||
parasitic = rcmodel;
|
||||
parasitic = rcmodel_;
|
||||
}
|
||||
return parasitic;
|
||||
}
|
||||
|
|
@ -321,9 +328,8 @@ ArnoldiDelayCalc::reduceParasitic(const Parasitic *,
|
|||
void
|
||||
ArnoldiDelayCalc::finishDrvrPin()
|
||||
{
|
||||
for (auto parasitic : unsaved_parasitics_)
|
||||
delete parasitic;
|
||||
unsaved_parasitics_.clear();
|
||||
delete rcmodel_;
|
||||
rcmodel_ = nullptr;
|
||||
}
|
||||
|
||||
ArcDcalcResult
|
||||
|
|
@ -363,7 +369,7 @@ ArnoldiDelayCalc::inputPortDelay(const Pin *,
|
|||
|
||||
for (int j=1;j<pin_n_;j++) {
|
||||
double elmore = rcmodel_->elmore(j);
|
||||
double wire_delay = 0.6931472*elmore;
|
||||
double wire_delay = std::numbers::ln2 * elmore;
|
||||
double load_slew = in_slew + c_log*elmore/slew_derate;
|
||||
_delayV[j] = wire_delay;
|
||||
_slewV[j] = load_slew;
|
||||
|
|
@ -488,7 +494,7 @@ ArnoldiDelayCalc::reportGateDelay(const Pin *drvr_pin,
|
|||
arnoldi1::~arnoldi1()
|
||||
{
|
||||
free(d);
|
||||
free(U);
|
||||
free(reinterpret_cast<void *>(U));
|
||||
}
|
||||
|
||||
double
|
||||
|
|
@ -507,13 +513,16 @@ delay_work_create()
|
|||
int j;
|
||||
delay_work *D = (delay_work*)malloc(sizeof(delay_work));
|
||||
D->nmax = 256;
|
||||
D->resi = (double**)malloc(D->nmax*sizeof(double*));
|
||||
D->resi[0] = (double*)malloc(D->nmax*32*sizeof(double));
|
||||
for (j=1;j<D->nmax;j++) D->resi[j] = D->resi[0] + j*32;
|
||||
D->v[0] = (double*)malloc(32*32*sizeof(double));
|
||||
for (j=1;j<32;j++) D->v[j] = D->v[0] + j*32;
|
||||
D->w[0] = (double*)malloc(32*D->nmax*sizeof(double));
|
||||
for (j=1;j<32;j++) D->w[j] = D->w[0] + j*D->nmax;
|
||||
D->resi = (double**)malloc(static_cast<size_t>(D->nmax) * sizeof(double *));
|
||||
D->resi[0] = (double*)malloc(static_cast<size_t>(D->nmax) * 32u * sizeof(double));
|
||||
for (j=1;j<D->nmax;j++)
|
||||
D->resi[j] = D->resi[0] + static_cast<ptrdiff_t>(j) * 32;
|
||||
D->v[0] = (double*)malloc(static_cast<size_t>(32) * 32u * sizeof(double));
|
||||
for (j=1;j<32;j++)
|
||||
D->v[j] = D->v[0] + static_cast<ptrdiff_t>(j) * 32;
|
||||
D->w[0] = (double*)malloc(32u * static_cast<size_t>(D->nmax) * sizeof(double));
|
||||
for (j=1;j<32;j++)
|
||||
D->w[j] = D->w[0] + static_cast<ptrdiff_t>(j) * D->nmax;
|
||||
D->lo_thresh = 0.0;
|
||||
D->hi_thresh = 0.0;
|
||||
D->slew_derate = 0.0;
|
||||
|
|
@ -536,7 +545,7 @@ static void
|
|||
delay_work_destroy(delay_work *D)
|
||||
{
|
||||
free(D->resi[0]);
|
||||
free(D->resi);
|
||||
free(reinterpret_cast<void *>(D->resi));
|
||||
free(D->v[0]);
|
||||
free(D->w[0]);
|
||||
free(D);
|
||||
|
|
@ -548,15 +557,17 @@ delay_work_alloc(delay_work *D,int n)
|
|||
if (n<=D->nmax) return;
|
||||
free(D->w[0]);
|
||||
free(D->resi[0]);
|
||||
free(D->resi);
|
||||
free(reinterpret_cast<void *>(D->resi));
|
||||
D->nmax *= 2;
|
||||
if (n > D->nmax) D->nmax = n;
|
||||
D->nmax = std::max(n, D->nmax);
|
||||
int j;
|
||||
D->resi = (double**)malloc(D->nmax*sizeof(double*));
|
||||
D->resi[0] = (double*)malloc(D->nmax*32*sizeof(double));
|
||||
for (j=1;j<D->nmax;j++) D->resi[j] = D->resi[0] + j*32;
|
||||
D->w[0] = (double*)malloc(32*D->nmax*sizeof(double));
|
||||
for (j=1;j<32;j++) D->w[j] = D->w[0] + j*D->nmax;
|
||||
D->resi = (double**)malloc(static_cast<size_t>(D->nmax) * sizeof(double *));
|
||||
D->resi[0] = (double*)malloc(static_cast<size_t>(D->nmax) * 32u * sizeof(double));
|
||||
for (j=1;j<D->nmax;j++)
|
||||
D->resi[j] = D->resi[0] + static_cast<ptrdiff_t>(j) * 32;
|
||||
D->w[0] = (double*)malloc(32u * static_cast<size_t>(D->nmax) * sizeof(double));
|
||||
for (j=1;j<32;j++)
|
||||
D->w[j] = D->w[0] + static_cast<ptrdiff_t>(j) * D->nmax;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -623,8 +634,7 @@ void arnoldi1::calculate_poles_res(delay_work *D,
|
|||
d[0] = dsave;
|
||||
|
||||
for (h=0;h<order;h++) {
|
||||
if (p[h]<1e-14) // .01ps
|
||||
p[h]=1e-14;
|
||||
p[h] = std::max(p[h], 1e-14); // .01ps floor
|
||||
p[h] = 1.0/p[h];
|
||||
}
|
||||
|
||||
|
|
@ -654,10 +664,10 @@ void arnoldi1::calculate_poles_res(delay_work *D,
|
|||
// tridiagonal eigenvalues and eigenvectors
|
||||
// assuming all eigenvalues are positive
|
||||
//
|
||||
// tridiagEV(int n,double *d,double *e,double *p,double **v)
|
||||
// d[0]..d[n-1] diagonal elements
|
||||
// e[0]..e[n-2] off-diagonal elements
|
||||
// p[0],..p[n-1] the eigenvalues
|
||||
// tridiagEV(n, din, ein, d, v)
|
||||
// din[0]..din[n-1] diagonal elements (input)
|
||||
// ein[0]..ein[n-2] off-diagonal elements (input)
|
||||
// d[0],..d[n-1] the eigenvalues (output)
|
||||
// v[0],..v[n-1] the eigenvectors
|
||||
// M*v[j] = p[j]*v[j]
|
||||
//
|
||||
|
|
@ -666,7 +676,11 @@ void arnoldi1::calculate_poles_res(delay_work *D,
|
|||
// (M*v[j])[n-1] = d[n-1]*v[j][n-1]+e[n-2]*v[j][n-2]
|
||||
//
|
||||
static bool
|
||||
tridiagEV(int n,double *din,double *ein,double *d,double **v)
|
||||
tridiagEV(int n,
|
||||
const double *din,
|
||||
const double *ein,
|
||||
double *d,
|
||||
double **v)
|
||||
{
|
||||
int j,k;
|
||||
for (j=0;j<n;j++) for (k=0;k<n;k++) v[j][k]=0.0;
|
||||
|
|
@ -748,7 +762,12 @@ tridiagEV(int n,double *din,double *ein,double *d,double **v)
|
|||
|
||||
// get a waveform point
|
||||
static void
|
||||
pr_get_v(double t, double s, int order, double *p, double *rr, double *va)
|
||||
pr_get_v(double t,
|
||||
double s,
|
||||
int order,
|
||||
const double *p,
|
||||
const double *rr,
|
||||
double *va)
|
||||
{
|
||||
*va = 0.0;
|
||||
int h;
|
||||
|
|
@ -766,8 +785,13 @@ pr_get_v(double t, double s, int order, double *p, double *rr, double *va)
|
|||
}
|
||||
|
||||
static void
|
||||
get_dv(double t, double s, int order, double *p, double *rr,
|
||||
double *va, double *dva)
|
||||
get_dv(double t,
|
||||
double s,
|
||||
int order,
|
||||
const double *p,
|
||||
const double *rr,
|
||||
double *va,
|
||||
double *dva)
|
||||
{
|
||||
*va = 0.0;
|
||||
*dva = 0.0;
|
||||
|
|
@ -791,12 +815,19 @@ get_dv(double t, double s, int order, double *p, double *rr,
|
|||
}
|
||||
|
||||
static double
|
||||
solve_t_bracketed(double s,int order,double *p,double *rr,
|
||||
double val,double x1,double x2,double v1,double v2)
|
||||
solve_t_bracketed(double s,
|
||||
int order,
|
||||
const double *p,
|
||||
const double *rr,
|
||||
double val,
|
||||
double x1,
|
||||
double x2,
|
||||
double v1,
|
||||
double v2)
|
||||
{
|
||||
int j;
|
||||
double df,dx,dxold,f,f2,f1;
|
||||
double temp,xh,xl,rts;
|
||||
double temp,xh,x_lo,rts;
|
||||
double xacc = .001e-12; // .001ps
|
||||
f1 = v1-val;
|
||||
f2 = v2-val;
|
||||
|
|
@ -804,12 +835,12 @@ solve_t_bracketed(double s,int order,double *p,double *rr,
|
|||
if (f2==0.0) return x2;
|
||||
rts = (f1*x2-f2*x1)/(f1-f2);
|
||||
if (f1<f2) {
|
||||
xl = x1;
|
||||
x_lo = x1;
|
||||
xh = x2;
|
||||
if (0.0<f1) return x1;
|
||||
if (f2<0.0) return x2;
|
||||
} else {
|
||||
xl = x2;
|
||||
x_lo = x2;
|
||||
xh = x1;
|
||||
if (0.0<f2) return x2;
|
||||
if (f1<0.0) return x1;
|
||||
|
|
@ -820,19 +851,19 @@ solve_t_bracketed(double s,int order,double *p,double *rr,
|
|||
f -= val;
|
||||
double flast = 0.0;
|
||||
for (j=1;j<10;j++) {
|
||||
if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0)
|
||||
if ((((rts-xh)*df-f)*((rts-x_lo)*df-f) >= 0.0)
|
||||
|| (std::abs(2.0*f) > std::abs(dxold*df))) {
|
||||
dxold = dx;
|
||||
dx = 0.5*(xh-xl);
|
||||
dx = 0.5*(xh-x_lo);
|
||||
if (flast*f >0.0) {
|
||||
// 2 successive bisections in same direction,
|
||||
// accelerate
|
||||
if (f<0.0) dx = 0.9348*(xh-xl);
|
||||
else dx = 0.0625*(xh-xl);
|
||||
if (f<0.0) dx = 0.9348*(xh-x_lo);
|
||||
else dx = 0.0625*(xh-x_lo);
|
||||
}
|
||||
flast = f;
|
||||
rts = xl+dx;
|
||||
if (xl == rts) {
|
||||
rts = x_lo+dx;
|
||||
if (x_lo == rts) {
|
||||
return rts;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -850,13 +881,13 @@ solve_t_bracketed(double s,int order,double *p,double *rr,
|
|||
}
|
||||
get_dv(rts,s,order,p,rr,&f,&df); f -= val;
|
||||
if (f<0.0)
|
||||
xl = rts;
|
||||
x_lo = rts;
|
||||
else
|
||||
xh = rts;
|
||||
}
|
||||
if (std::abs(f)<1e-6) // 1uV
|
||||
return rts;
|
||||
return 0.5*(xl+xh);
|
||||
return 0.5*(x_lo+xh);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -950,8 +981,7 @@ ArnoldiDelayCalc::pr_solve3(double s,
|
|||
for (h=1;h<order;h++) if (rr[h]>0.3 && rr[h]>rr[0]) { h0 = h; break; }
|
||||
}
|
||||
double p0 = p[h0];
|
||||
if (p0>10e+9) // 1/10ns
|
||||
p0=10e+9;
|
||||
p0 = std::min(p0, 10e+9); // 1/10ns cap
|
||||
double ps,vs,ta,va;
|
||||
vs = 0.0;
|
||||
for (h=0;h<order;h++) {
|
||||
|
|
@ -1035,7 +1065,9 @@ ArnoldiDelayCalc::pr_solve3(double s,
|
|||
ta = s + 0.7/p0;
|
||||
pr_get_v(ta,s,order,p,rr,&va);
|
||||
while (va>vmid) {
|
||||
tmin5 = tmin8 = ta; vmin5 = tmin8 = va;
|
||||
tmin5 = ta;
|
||||
tmin8 = ta;
|
||||
vmin5 = va;
|
||||
ta += 0.7/p0;
|
||||
pr_get_v(ta,s,order,p,rr,&va);
|
||||
}
|
||||
|
|
@ -1065,18 +1097,14 @@ ArnoldiDelayCalc::pr_solve3(double s,
|
|||
pr_get_v(ta,s,order,p,rr,&va);
|
||||
}
|
||||
tmax2 = ta; vmax2 = va;
|
||||
if (va < vmid) {
|
||||
tmax5 = ta; vmax5 = va;
|
||||
} else while (va > vmid) {
|
||||
while (va > vmid) {
|
||||
tmin5 = tmin8 = ta;
|
||||
vmin5 = vmin8 = va;
|
||||
ta += 1.0/p0;
|
||||
pr_get_v(ta,s,order,p,rr,&va);
|
||||
}
|
||||
tmax5 = ta; vmax5 = va;
|
||||
if (va < vlo) {
|
||||
tmax8 = ta; vmax8 = va;
|
||||
} else while (va > vlo) {
|
||||
while (va > vlo) {
|
||||
tmin8 = ta;
|
||||
vmin8 = va;
|
||||
ta += 1.0/p0;
|
||||
|
|
@ -1249,11 +1277,12 @@ ArnoldiDelayCalc::ra_solve_for_s(delay_work *D,
|
|||
|
||||
if (x <= x1) {
|
||||
y = y1 - 0.5*(x-x1);
|
||||
if (y>1.0) y=1.0;
|
||||
y = std::min(y, 1.0);
|
||||
} else {
|
||||
y = y1 - (x-x1)*(0.5 + 8*(x-x1));
|
||||
if (y<y2) y=y2;
|
||||
y = std::max(y, y2);
|
||||
}
|
||||
(void)y;
|
||||
|
||||
ra_solve_for_pt(p*s,vlo,&ptlo,&dlo);
|
||||
ra_solve_for_pt(p*s,vhi,&pthi,&dhi);
|
||||
|
|
@ -1406,7 +1435,6 @@ ArnoldiDelayCalc::ar1_ceff_delay(delay_work *D,
|
|||
if (rdelay == 0.0) {
|
||||
rdelay = 1e+3; // 1kohm
|
||||
}
|
||||
r = rdelay;
|
||||
r = ra_get_r(D,tab,rdelay,ctot);
|
||||
if (! (r>0.0
|
||||
&& r<100e+3)) // 100khom
|
||||
|
|
@ -1437,9 +1465,6 @@ ArnoldiDelayCalc::ar1_ceff_delay(delay_work *D,
|
|||
units_->timeUnit()->asString(tlox-thix));
|
||||
}
|
||||
ceff = ctot;
|
||||
tab->table->gateDelay(tab->pvt, tab->in_slew, ceff, df, sf);
|
||||
t50_sy = delayAsFloat(df);
|
||||
t50_sr = ra_solve_for_t(1.0/(r*ceff),s,0.5);
|
||||
|
||||
// calculate s,r,mod -> t50_srmod,
|
||||
// then t50_srmod+t50_sy-t50_sr
|
||||
|
|
@ -1489,4 +1514,5 @@ ArnoldiDelayCalc::ar1_ceff_delay(delay_work *D,
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
// NOLINTEND(modernize-avoid-c-style-cast)
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -32,4 +32,4 @@ class StaState;
|
|||
ArcDelayCalc *
|
||||
makeArnoldiDelayCalc(StaState *sta);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -28,19 +28,22 @@
|
|||
|
||||
#include "ArnoldiReduce.hh"
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Network.hh"
|
||||
#include "Units.hh"
|
||||
#include <algorithm>
|
||||
|
||||
#include "Arnoldi.hh"
|
||||
#include "Debug.hh"
|
||||
#include "Format.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Network.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Units.hh"
|
||||
#include "parasitics/ConcreteParasiticsPvt.hh"
|
||||
|
||||
namespace sta {
|
||||
// This is legacy C-style code.
|
||||
// NOLINTBEGIN(modernize-avoid-c-style-cast, bugprone-multi-level-implicit-pointer-conversion, bugprone-implicit-widening-of-multiplication-result)
|
||||
|
||||
rcmodel::rcmodel() :
|
||||
pinV(nullptr)
|
||||
rcmodel::rcmodel()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -87,11 +90,7 @@ const int ArnoldiReduce::ts_point_count_incr_ = 1024;
|
|||
const int ArnoldiReduce::ts_edge_count_incr_ = 1024;
|
||||
|
||||
ArnoldiReduce::ArnoldiReduce(StaState *sta) :
|
||||
StaState(sta),
|
||||
ts_pointNmax(1024),
|
||||
ts_edgeNmax(1024),
|
||||
termNmax(256),
|
||||
dNmax(8)
|
||||
StaState(sta)
|
||||
{
|
||||
ts_pointV = (ts_point *)malloc(ts_pointNmax * sizeof(ts_point));
|
||||
ts_ordV = (int *)malloc(ts_pointNmax * sizeof(int));
|
||||
|
|
@ -351,14 +350,14 @@ ArnoldiReduce::makeRcmodelDfs(ts_point *pdrv)
|
|||
ts_point *p0 = ts_pointV;
|
||||
ts_point *pend = p0 + ts_pointN;
|
||||
for (p = p0; p != pend; p++)
|
||||
p->visited = 0;
|
||||
p->visited = false;
|
||||
ts_edge *e;
|
||||
|
||||
ts_edge **stackV = ts_stackV;
|
||||
int stackN = 1;
|
||||
stackV[0] = e = pdrv->eV[0];
|
||||
ts_orient(pdrv, e);
|
||||
pdrv->visited = 1;
|
||||
pdrv->visited = true;
|
||||
pdrv->in_edge = nullptr;
|
||||
pdrv->ts = 0;
|
||||
ts_ordV[0] = pdrv - p0;
|
||||
|
|
@ -376,7 +375,7 @@ ArnoldiReduce::makeRcmodelDfs(ts_point *pdrv)
|
|||
}
|
||||
else {
|
||||
// try to descend
|
||||
q->visited = 1;
|
||||
q->visited = true;
|
||||
q->ts = ts_ordN++;
|
||||
ts_pordV[q->ts] = q;
|
||||
ts_ordV[q->ts] = q - p0;
|
||||
|
|
@ -531,9 +530,7 @@ ArnoldiReduce::makeRcmodelFromTs()
|
|||
u0 = _u0;
|
||||
u1 = _u1;
|
||||
double sum, e1;
|
||||
order = max_order;
|
||||
if (n < order)
|
||||
order = n;
|
||||
order = std::min(n, max_order);
|
||||
|
||||
par[0] = -1;
|
||||
r[0] = 0.0;
|
||||
|
|
@ -682,4 +679,5 @@ ArnoldiReduce::makeRcmodelFromW()
|
|||
return mod;
|
||||
}
|
||||
|
||||
// NOLINTEND(modernize-avoid-c-style-cast, bugprone-multi-level-implicit-pointer-conversion, bugprone-implicit-widening-of-multiplication-result)
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class ArnoldiReduce : public StaState
|
|||
{
|
||||
public:
|
||||
ArnoldiReduce(StaState *sta);
|
||||
~ArnoldiReduce();
|
||||
~ArnoldiReduce() override;
|
||||
rcmodel *reduceToArnoldi(Parasitic *parasitic,
|
||||
const Pin *drvr_pin,
|
||||
float coupling_cap_factor,
|
||||
|
|
@ -86,11 +86,11 @@ protected:
|
|||
// rcWork
|
||||
ts_point *ts_pointV;
|
||||
int ts_pointN;
|
||||
int ts_pointNmax;
|
||||
int ts_pointNmax{1024};
|
||||
static const int ts_point_count_incr_;
|
||||
ts_edge *ts_edgeV;
|
||||
int ts_edgeN;
|
||||
int ts_edgeNmax;
|
||||
int ts_edgeNmax{1024};
|
||||
static const int ts_edge_count_incr_;
|
||||
ts_edge **ts_eV;
|
||||
ts_edge **ts_stackV;
|
||||
|
|
@ -98,14 +98,14 @@ protected:
|
|||
ts_point **ts_pordV;
|
||||
int ts_ordN;
|
||||
|
||||
int termNmax;
|
||||
int termNmax{256};
|
||||
int termN;
|
||||
ts_point *pterm0;
|
||||
const Pin **pinV; // fixed order, offset from pterm0
|
||||
int *termV; // from drv-ordered to fixed order
|
||||
int *outV; // from drv-ordered to ts_pordV
|
||||
|
||||
int dNmax;
|
||||
int dNmax{8};
|
||||
double *d;
|
||||
double *e;
|
||||
double *U0;
|
||||
|
|
@ -120,4 +120,4 @@ protected:
|
|||
int order;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,19 +24,20 @@
|
|||
|
||||
#include "CcsCeffDelayCalc.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "Units.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "DmpDelayCalc.hh"
|
||||
#include "FindRoot.hh"
|
||||
#include "Graph.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "Scene.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Units.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -53,10 +54,6 @@ makeCcsCeffDelayCalc(StaState *sta)
|
|||
|
||||
CcsCeffDelayCalc::CcsCeffDelayCalc(StaState *sta) :
|
||||
LumpedCapDelayCalc(sta),
|
||||
output_waveforms_(nullptr),
|
||||
// Includes the Vh:Vdd region.
|
||||
region_count_(0),
|
||||
vl_fail_(false),
|
||||
watch_pin_values_(network_),
|
||||
capacitance_unit_(units_->capacitanceUnit()),
|
||||
table_dcalc_(makeDmpCeffElmoreDelayCalc(sta))
|
||||
|
|
@ -176,8 +173,8 @@ CcsCeffDelayCalc::gateDelaySlew(const LibertyLibrary *drvr_library,
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < region_count_; i++) {
|
||||
double v1 = region_volts_[i];
|
||||
double v2 = region_volts_[i + 1];
|
||||
double seg_v1 = region_volts_[i];
|
||||
double seg_v2 = region_volts_[i + 1];
|
||||
double t1 = region_times_[i];
|
||||
double t2 = region_times_[i + 1];
|
||||
|
||||
|
|
@ -186,11 +183,11 @@ CcsCeffDelayCalc::gateDelaySlew(const LibertyLibrary *drvr_library,
|
|||
// for the charge on c1 from previous segments so it does not
|
||||
// work well.
|
||||
double c1_v1, c1_v2, ignore;
|
||||
vl(t1, rpi_ * c1_, c1_v1, ignore);
|
||||
vl(t2, rpi_ * c1_, c1_v2, ignore);
|
||||
double q1 = v1 * c2_ + c1_v1 * c1_;
|
||||
double q2 = v2 * c2_ + c1_v2 * c1_;
|
||||
double ceff = (q2 - q1) / (v2 - v1);
|
||||
vLoad(t1, rpi_ * c1_, c1_v1, ignore);
|
||||
vLoad(t2, rpi_ * c1_, c1_v2, ignore);
|
||||
double q1 = seg_v1 * c2_ + c1_v1 * c1_;
|
||||
double q2 = seg_v2 * c2_ + c1_v2 * c1_;
|
||||
double ceff = (q2 - q1) / (seg_v2 - seg_v1);
|
||||
|
||||
debugPrint(debug_, "ccs_dcalc", 2, "ceff {}",
|
||||
capacitance_unit_->asString(ceff));
|
||||
|
|
@ -297,7 +294,7 @@ CcsCeffDelayCalc::initRegions(const LibertyLibrary *drvr_library,
|
|||
report_->error(1701, "unsupported ccs region count.");
|
||||
break;
|
||||
}
|
||||
fill(region_ceff_.begin(), region_ceff_.end(), c2_ + c1_);
|
||||
std::ranges::fill(region_ceff_, c2_ + c1_);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -402,11 +399,11 @@ rampElmoreV(double t,
|
|||
|
||||
// Elmore (one pole) response to 2 segment ramps [0, vth] slew1, [vth, vdd] slew2.
|
||||
void
|
||||
CcsCeffDelayCalc::vl(double t,
|
||||
double elmore,
|
||||
// Return values.
|
||||
double &vl,
|
||||
double &dvl_dt)
|
||||
CcsCeffDelayCalc::vLoad(double t,
|
||||
double elmore,
|
||||
// Return values.
|
||||
double &vl,
|
||||
double &dvl_dt)
|
||||
{
|
||||
vl = 0.0;
|
||||
dvl_dt = 0.0;
|
||||
|
|
@ -431,11 +428,11 @@ CcsCeffDelayCalc::vl(double t,
|
|||
|
||||
// for debugging
|
||||
double
|
||||
CcsCeffDelayCalc::vl(double t,
|
||||
double elmore)
|
||||
CcsCeffDelayCalc::vLoad(double t,
|
||||
double elmore)
|
||||
{
|
||||
double vl1, dvl_dt;
|
||||
vl(t, elmore, vl1, dvl_dt);
|
||||
vLoad(t, elmore, vl1, dvl_dt);
|
||||
return vl1;
|
||||
}
|
||||
|
||||
|
|
@ -445,14 +442,13 @@ CcsCeffDelayCalc::findVlTime(double v,
|
|||
{
|
||||
double t_init = region_ramp_times_[0];
|
||||
double t_final = region_ramp_times_[region_count_];
|
||||
bool root_fail = false;
|
||||
double time = findRoot(
|
||||
[&](double t, double &y, double &dy) {
|
||||
vl(t, elmore, y, dy);
|
||||
y -= v;
|
||||
},
|
||||
t_init, t_final + elmore * 3.0, .001, 20, root_fail);
|
||||
vl_fail_ |= root_fail;
|
||||
auto [time, failed] =
|
||||
findRoot([&](double t, double &y, double &dy) {
|
||||
vLoad(t, elmore, y, dy);
|
||||
y -= v;
|
||||
},
|
||||
t_init, t_final + elmore * 3.0, .001, 20);
|
||||
vl_fail_ |= failed;
|
||||
return time;
|
||||
}
|
||||
|
||||
|
|
@ -540,7 +536,7 @@ CcsCeffDelayCalc::loadWaveform(const Pin *load_pin)
|
|||
load_times->push_back(t);
|
||||
|
||||
double ignore;
|
||||
vl(t, elmore, v, ignore);
|
||||
vLoad(t, elmore, v, ignore);
|
||||
double v1 = (drvr_rf_ == RiseFall::rise()) ? v : vdd_ - v;
|
||||
load_volts->push_back(v1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "ArcDcalcWaveforms.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ class CcsCeffDelayCalc : public LumpedCapDelayCalc,
|
|||
{
|
||||
public:
|
||||
CcsCeffDelayCalc(StaState *sta);
|
||||
virtual ~CcsCeffDelayCalc();
|
||||
~CcsCeffDelayCalc() override;
|
||||
ArcDelayCalc *copy() override;
|
||||
std::string_view name() const override { return "ccs_ceff"; }
|
||||
bool reduceSupported() const override { return true; }
|
||||
|
|
@ -68,7 +68,7 @@ public:
|
|||
Waveform watchWaveform(const Pin *pin) override;
|
||||
|
||||
protected:
|
||||
typedef std::vector<double> Region;
|
||||
using Region = std::vector<double>;
|
||||
|
||||
void gateDelaySlew(const LibertyLibrary *drvr_library,
|
||||
// Return values.
|
||||
|
|
@ -106,13 +106,13 @@ protected:
|
|||
const Pin *load_pin,
|
||||
const Scene *scene,
|
||||
const MinMax *min_max);
|
||||
void vl(double t,
|
||||
double elmore,
|
||||
// Return values.
|
||||
double &vl,
|
||||
double &dvl_dt);
|
||||
double vl(double t,
|
||||
double elmore);
|
||||
void vLoad(double t,
|
||||
double elmore,
|
||||
// Return values.
|
||||
double &vl,
|
||||
double &dvl_dt);
|
||||
double vLoad(double t,
|
||||
double elmore);
|
||||
void fail(std::string_view reason);
|
||||
|
||||
const Pin *drvr_pin_;
|
||||
|
|
@ -122,7 +122,7 @@ protected:
|
|||
Parasitics *parasitics_;
|
||||
const Parasitic *parasitic_;
|
||||
|
||||
OutputWaveforms *output_waveforms_;
|
||||
OutputWaveforms *output_waveforms_{nullptr};
|
||||
double ref_time_;
|
||||
float vdd_;
|
||||
float vth_;
|
||||
|
|
@ -133,7 +133,7 @@ protected:
|
|||
float rpi_;
|
||||
float c1_;
|
||||
|
||||
size_t region_count_;
|
||||
size_t region_count_{0};
|
||||
size_t region_vl_idx_;
|
||||
size_t region_vth_idx_;
|
||||
size_t region_vh_idx_;
|
||||
|
|
@ -146,7 +146,7 @@ protected:
|
|||
Region region_time_offsets_;
|
||||
Region region_ramp_times_;
|
||||
Region region_ramp_slopes_;
|
||||
bool vl_fail_;
|
||||
bool vl_fail_{false};
|
||||
// Waveform recording.
|
||||
WatchPinValuesMap watch_pin_values_;
|
||||
|
||||
|
|
@ -155,4 +155,4 @@ protected:
|
|||
ArcDelayCalc *table_dcalc_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
#include "StaConfig.hh"
|
||||
#include "Fuzzy.hh"
|
||||
#include "Units.hh"
|
||||
#include "StaConfig.hh"
|
||||
#include "StaState.hh"
|
||||
#include "Units.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -43,18 +43,18 @@ initDelayConstants()
|
|||
delay_init_values[MinMax::maxIndex()] = MinMax::max()->initValue();
|
||||
}
|
||||
|
||||
Delay::Delay() :
|
||||
Delay::Delay() noexcept :
|
||||
values_{0.0, 0.0, 0.0, 0.0}
|
||||
{
|
||||
}
|
||||
|
||||
Delay::Delay(float mean) :
|
||||
Delay::Delay(float mean) noexcept :
|
||||
values_{mean, 0.0, 0.0, 0.0}
|
||||
{
|
||||
}
|
||||
|
||||
Delay::Delay(float mean,
|
||||
float std_dev2) :
|
||||
float std_dev2) noexcept :
|
||||
values_{mean, 0.0, std_dev2, 0.0}
|
||||
{
|
||||
}
|
||||
|
|
@ -62,18 +62,19 @@ Delay::Delay(float mean,
|
|||
Delay::Delay(float mean,
|
||||
float mean_shift,
|
||||
float std_dev2,
|
||||
float skewness) :
|
||||
float skewness) noexcept :
|
||||
values_{mean, mean_shift, std_dev2, skewness}
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Delay &
|
||||
Delay::operator=(float delay)
|
||||
{
|
||||
values_[0] = delay;
|
||||
values_[1] = 0.0;
|
||||
values_[2] = 0.0;
|
||||
values_[3] = 0.0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -126,12 +127,12 @@ Delay::setSkewness(float skewness)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
DelayDbl::DelayDbl() :
|
||||
DelayDbl::DelayDbl() noexcept :
|
||||
values_{0.0, 0.0, 0.0, 0.0}
|
||||
{
|
||||
}
|
||||
|
||||
DelayDbl::DelayDbl(double mean) :
|
||||
DelayDbl::DelayDbl(double mean) noexcept :
|
||||
values_{mean, 0.0, 0.0, 0.0}
|
||||
{
|
||||
}
|
||||
|
|
@ -166,13 +167,14 @@ DelayDbl::setValues(double mean,
|
|||
values_[3] = skewnes;
|
||||
}
|
||||
|
||||
void
|
||||
DelayDbl &
|
||||
DelayDbl::operator=(double delay)
|
||||
{
|
||||
values_[0] = delay;
|
||||
values_[1] = 0.0;
|
||||
values_[2] = 0.0;
|
||||
values_[3] = 0.0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -520,4 +522,4 @@ delayStdDev2(const Delay &delay,
|
|||
return sta->delayOps()->stdDev2(delay, early_late);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -27,18 +27,18 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "ContainerHelpers.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "UnitDelayCalc.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "DmpDelayCalc.hh"
|
||||
#include "ArnoldiDelayCalc.hh"
|
||||
#include "CcsCeffDelayCalc.hh"
|
||||
#include "ContainerHelpers.hh"
|
||||
#include "DmpDelayCalc.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "PrimaDelayCalc.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "UnitDelayCalc.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
typedef std::map<std::string, MakeArcDelayCalc, std::less<>> DelayCalcMap;
|
||||
using DelayCalcMap = std::map<std::string, MakeArcDelayCalc, std::less<>>;
|
||||
|
||||
static DelayCalcMap delay_calcs;
|
||||
|
||||
|
|
@ -93,4 +93,4 @@ delayCalcNames()
|
|||
return names;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -22,17 +22,15 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module dcalc
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
|
||||
#include "DelayCalc.hh"
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "DelayCalc.hh"
|
||||
#include "Sta.hh"
|
||||
#include "dcalc/ArcDcalcWaveforms.hh"
|
||||
#include "dcalc/PrimaDelayCalc.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,16 +24,16 @@
|
|||
|
||||
#include "DelayCalcBase.hh"
|
||||
|
||||
#include "Graph.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TimingModel.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Scene.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TimingModel.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -239,4 +239,4 @@ DelayCalcBase::setDcalcArgParasiticSlew(ArcDcalcArgSeq &gates,
|
|||
setDcalcArgParasiticSlew(gate, scene, min_max);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ protected:
|
|||
void thresholdAdjust(const Pin *load_pin,
|
||||
const LibertyLibrary *drvr_library,
|
||||
const RiseFall *rf,
|
||||
double &load_delay,
|
||||
double &wire_delay,
|
||||
double &load_slew);
|
||||
// Helper function for input ports driving dspf parasitic.
|
||||
void dspfWireDelaySlew(const Pin *load_pin,
|
||||
|
|
@ -89,4 +89,4 @@ protected:
|
|||
using ArcDelayCalc::reduceParasitic;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -27,10 +27,10 @@
|
|||
#include <cmath> // sqrt
|
||||
|
||||
#include "Error.hh"
|
||||
#include "Fuzzy.hh"
|
||||
#include "Units.hh"
|
||||
#include "Format.hh"
|
||||
#include "Fuzzy.hh"
|
||||
#include "StaState.hh"
|
||||
#include "Units.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -229,4 +229,4 @@ DelayOpsNormal::asStringVariance(const Delay &delay,
|
|||
unit->asString(delay.stdDev(), digits));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -27,8 +27,8 @@
|
|||
#include "DelayScalar.hh"
|
||||
|
||||
#include "Fuzzy.hh"
|
||||
#include "Units.hh"
|
||||
#include "StaState.hh"
|
||||
#include "Units.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -202,5 +202,5 @@ DelayOpsScalar::asStringVariance(const Delay &delay,
|
|||
return unit->asString(delay.mean(), digits);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -27,10 +27,10 @@
|
|||
#include <cmath> // sqrt
|
||||
|
||||
#include "Error.hh"
|
||||
#include "Fuzzy.hh"
|
||||
#include "Units.hh"
|
||||
#include "Format.hh"
|
||||
#include "Fuzzy.hh"
|
||||
#include "StaState.hh"
|
||||
#include "Units.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -290,4 +290,4 @@ DelayOpsSkewNormal::asStringVariance(const Delay &delay,
|
|||
sta->units()->scalarUnit()->asString(delay.skewness(), digits));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
934
dcalc/DmpCeff.cc
934
dcalc/DmpCeff.cc
File diff suppressed because it is too large
Load Diff
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "LibertyClass.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
|
||||
|
|
@ -41,7 +44,7 @@ class DmpCeffDelayCalc : public LumpedCapDelayCalc
|
|||
{
|
||||
public:
|
||||
DmpCeffDelayCalc(StaState *sta);
|
||||
virtual ~DmpCeffDelayCalc();
|
||||
~DmpCeffDelayCalc() override;
|
||||
bool reduceSupported() const override { return true; }
|
||||
ArcDcalcResult gateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
|
|
@ -71,13 +74,10 @@ protected:
|
|||
// Return values.
|
||||
double &wire_delay,
|
||||
double &load_slew) = 0;
|
||||
void gateDelaySlew(// Return values.
|
||||
double &delay,
|
||||
double &slew);
|
||||
void loadDelaySlewElmore(const Pin *load_pin,
|
||||
double elmore,
|
||||
double &delay,
|
||||
double &slew);
|
||||
std::pair<double, double> gateDelaySlew();
|
||||
std::optional<std::pair<double, double>>
|
||||
loadDelaySlewElmore(const Pin *load_pin,
|
||||
double elmore);
|
||||
// Select the appropriate special case Dartu/Menezes/Pileggi algorithm.
|
||||
void setCeffAlgorithm(const LibertyLibrary *library,
|
||||
const LibertyCell *cell,
|
||||
|
|
@ -98,7 +98,7 @@ private:
|
|||
DmpCap *dmp_cap_;
|
||||
DmpPi *dmp_pi_;
|
||||
DmpZeroC2 *dmp_zero_c2_;
|
||||
DmpAlg *dmp_alg_;
|
||||
DmpAlg *dmp_alg_{nullptr};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,15 +24,15 @@
|
|||
|
||||
#include "DmpDelayCalc.hh"
|
||||
|
||||
#include "DmpCeff.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Network.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "DmpCeff.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -125,8 +125,12 @@ DmpCeffElmoreDelayCalc::loadDelaySlew(const Pin *load_pin,
|
|||
float elmore = 0.0;
|
||||
if (parasitic)
|
||||
parasitics_->findElmore(parasitic, load_pin, elmore, elmore_exists);
|
||||
if (elmore_exists)
|
||||
loadDelaySlewElmore(load_pin, elmore, wire_delay, load_slew);
|
||||
if (elmore_exists) {
|
||||
if (auto r = loadDelaySlewElmore(load_pin, elmore)) {
|
||||
wire_delay = r->first;
|
||||
load_slew = r->second;
|
||||
}
|
||||
}
|
||||
thresholdAdjust(load_pin, drvr_library, rf, wire_delay, load_slew);
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +164,7 @@ public:
|
|||
const Scene *scene,
|
||||
const MinMax *min_max) override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
void loadDelaySlew(const Pin *load_pin,
|
||||
double drvr_slew,
|
||||
const RiseFall *rf,
|
||||
|
|
@ -169,6 +173,8 @@ private:
|
|||
// Return values.
|
||||
double &wire_delay,
|
||||
double &load_slew) override;
|
||||
|
||||
private:
|
||||
void loadDelay(double drvr_slew,
|
||||
Parasitic *pole_residue,
|
||||
double p1,
|
||||
|
|
@ -186,11 +192,11 @@ private:
|
|||
double tt,
|
||||
double y_tt);
|
||||
|
||||
bool parasitic_is_pole_residue_;
|
||||
float vth_;
|
||||
float vl_;
|
||||
float vh_;
|
||||
float slew_derate_;
|
||||
bool parasitic_is_pole_residue_{false};
|
||||
float vth_{0.0F};
|
||||
float vl_{0.0F};
|
||||
float vh_{0.0F};
|
||||
float slew_derate_{0.0F};
|
||||
};
|
||||
|
||||
ArcDelayCalc *
|
||||
|
|
@ -200,12 +206,7 @@ makeDmpCeffTwoPoleDelayCalc(StaState *sta)
|
|||
}
|
||||
|
||||
DmpCeffTwoPoleDelayCalc::DmpCeffTwoPoleDelayCalc(StaState *sta) :
|
||||
DmpCeffDelayCalc(sta),
|
||||
parasitic_is_pole_residue_(false),
|
||||
vth_(0.0),
|
||||
vl_(0.0),
|
||||
vh_(0.0),
|
||||
slew_derate_(0.0)
|
||||
DmpCeffDelayCalc(sta)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +331,7 @@ DmpCeffTwoPoleDelayCalc::loadDelaySlew(const Pin *load_pin,
|
|||
// Should handle PiElmore parasitic.
|
||||
wire_delay = 0.0;
|
||||
load_slew = drvr_slew;
|
||||
Parasitic *pole_residue = 0;
|
||||
Parasitic *pole_residue = nullptr;
|
||||
if (parasitic_is_pole_residue_)
|
||||
pole_residue = parasitics_->findPoleResidue(parasitic, load_pin);
|
||||
if (pole_residue) {
|
||||
|
|
@ -432,4 +433,4 @@ DmpCeffTwoPoleDelayCalc::loadDelay(double vth,
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -34,4 +34,4 @@ makeDmpCeffElmoreDelayCalc(StaState *sta);
|
|||
ArcDelayCalc *
|
||||
makeDmpCeffTwoPoleDelayCalc(StaState *sta);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -28,47 +28,38 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
double
|
||||
findRoot(FindRootFunc func,
|
||||
std::pair<double, bool>
|
||||
findRoot(const FindRootFunc &func,
|
||||
double x1,
|
||||
double x2,
|
||||
double x_tol,
|
||||
int max_iter,
|
||||
// Return value.
|
||||
bool &fail)
|
||||
int max_iter)
|
||||
{
|
||||
double y1, y2, dy1;
|
||||
func(x1, y1, dy1);
|
||||
func(x2, y2, dy1);
|
||||
return findRoot(func, x1, y1, x2, y2, x_tol, max_iter, fail);
|
||||
return findRoot(func, x1, y1, x2, y2, x_tol, max_iter);
|
||||
}
|
||||
|
||||
double
|
||||
findRoot(FindRootFunc func,
|
||||
std::pair<double, bool>
|
||||
findRoot(const FindRootFunc &func,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x_tol,
|
||||
int max_iter,
|
||||
// Return value.
|
||||
bool &fail)
|
||||
int max_iter)
|
||||
{
|
||||
if ((y1 > 0.0 && y2 > 0.0) || (y1 < 0.0 && y2 < 0.0)) {
|
||||
// Initial bounds do not surround a root.
|
||||
fail = true;
|
||||
return 0.0;
|
||||
return {0.0, true};
|
||||
}
|
||||
|
||||
if (y1 == 0.0) {
|
||||
fail = false;
|
||||
return x1;
|
||||
}
|
||||
if (y1 == 0.0)
|
||||
return {x1, false};
|
||||
|
||||
if (y2 == 0.0) {
|
||||
fail = false;
|
||||
return x2;
|
||||
}
|
||||
if (y2 == 0.0)
|
||||
return {x2, false};
|
||||
|
||||
if (y1 > 0.0)
|
||||
// Swap x1/x2 so func(x1) < 0.
|
||||
|
|
@ -95,8 +86,7 @@ findRoot(FindRootFunc func,
|
|||
}
|
||||
if (std::abs(dx) <= x_tol * std::abs(root)) {
|
||||
// Converged.
|
||||
fail = false;
|
||||
return root;
|
||||
return {root, false};
|
||||
}
|
||||
|
||||
func(root, y, dy);
|
||||
|
|
@ -105,8 +95,7 @@ findRoot(FindRootFunc func,
|
|||
else
|
||||
x2 = root;
|
||||
}
|
||||
fail = true;
|
||||
return root;
|
||||
return {root, true};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -33,24 +34,22 @@ using FindRootFunc = const std::function<void (double x,
|
|||
double &y,
|
||||
double &dy)>;
|
||||
|
||||
double
|
||||
findRoot(FindRootFunc func,
|
||||
// first: root estimate; second: true if the search failed.
|
||||
std::pair<double, bool>
|
||||
findRoot(const FindRootFunc &func,
|
||||
double x1,
|
||||
double x2,
|
||||
double x_tol,
|
||||
int max_iter,
|
||||
// Return value.
|
||||
bool &fail);
|
||||
int max_iter);
|
||||
|
||||
double
|
||||
findRoot(FindRootFunc func,
|
||||
// first: root estimate; second: true if the search failed.
|
||||
std::pair<double, bool>
|
||||
findRoot(const FindRootFunc &func,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x_tol,
|
||||
int max_iter,
|
||||
// Return value.
|
||||
bool &fail);
|
||||
int max_iter);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,35 +24,35 @@
|
|||
|
||||
#include "GraphDelayCalc.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "Bfs.hh"
|
||||
#include "ClkNetwork.hh"
|
||||
#include "ContainerHelpers.hh"
|
||||
#include "Debug.hh"
|
||||
#include "Stats.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Mutex.hh"
|
||||
#include "TimingRole.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Network.hh"
|
||||
#include "InputDrive.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Mode.hh"
|
||||
#include "Graph.hh"
|
||||
#include "InputDrive.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Mode.hh"
|
||||
#include "Mutex.hh"
|
||||
#include "NetCaps.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "search/Levelize.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Scene.hh"
|
||||
#include "SearchPred.hh"
|
||||
#include "Bfs.hh"
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "NetCaps.hh"
|
||||
#include "ClkNetwork.hh"
|
||||
#include "Stats.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TimingRole.hh"
|
||||
#include "Variables.hh"
|
||||
#include "search/Latches.hh"
|
||||
#include "search/Levelize.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -143,15 +143,10 @@ DcalcNonLatchPred::searchThru(Edge *edge,
|
|||
|
||||
GraphDelayCalc::GraphDelayCalc(StaState *sta) :
|
||||
StaState(sta),
|
||||
observer_(nullptr),
|
||||
delays_seeded_(false),
|
||||
incremental_(false),
|
||||
delays_exist_(false),
|
||||
invalid_delays_(makeVertexSet(this)),
|
||||
search_pred_(new DcalcPred(sta)),
|
||||
search_non_latch_pred_(new DcalcNonLatchPred(sta)),
|
||||
iter_(new BfsFwdIterator(BfsIndex::dcalc, search_non_latch_pred_, sta)),
|
||||
incremental_delay_tolerance_(0.0)
|
||||
iter_(new BfsFwdIterator(BfsIndex::dcalc, search_non_latch_pred_, sta))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -297,9 +292,9 @@ class FindVertexDelays : public VertexVisitor
|
|||
{
|
||||
public:
|
||||
FindVertexDelays(GraphDelayCalc *graph_delay_calc1);
|
||||
virtual ~FindVertexDelays();
|
||||
virtual void visit(Vertex *vertex);
|
||||
virtual VertexVisitor *copy() const;
|
||||
~FindVertexDelays() override;
|
||||
void visit(Vertex *vertex) override;
|
||||
VertexVisitor *copy() const override;
|
||||
|
||||
protected:
|
||||
GraphDelayCalc *graph_delay_calc_;
|
||||
|
|
@ -419,7 +414,7 @@ GraphDelayCalc::seedDrvrSlew(Vertex *drvr_vertex,
|
|||
if (drive) {
|
||||
const LibertyCell *drvr_cell;
|
||||
const LibertyPort *from_port, *to_port;
|
||||
float *from_slews;
|
||||
const DriveCellSlews *from_slews;
|
||||
drive->driveCell(rf, min_max, drvr_cell, from_port,
|
||||
from_slews, to_port);
|
||||
if (drvr_cell) {
|
||||
|
|
@ -562,7 +557,7 @@ LibertyPort *
|
|||
GraphDelayCalc::driveCellDefaultFromPort(const LibertyCell *cell,
|
||||
const LibertyPort *to_port)
|
||||
{
|
||||
LibertyPort *from_port = 0;
|
||||
LibertyPort *from_port = nullptr;
|
||||
int from_port_index = 0;
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsTo(to_port)) {
|
||||
LibertyPort *set_from_port = arc_set->from();
|
||||
|
|
@ -599,7 +594,7 @@ GraphDelayCalc::findInputDriverDelay(const LibertyCell *drvr_cell,
|
|||
Vertex *drvr_vertex,
|
||||
const RiseFall *rf,
|
||||
const LibertyPort *from_port,
|
||||
float *from_slews,
|
||||
const DriveCellSlews *from_slews,
|
||||
const LibertyPort *to_port,
|
||||
const Scene *scene,
|
||||
const MinMax *min_max,
|
||||
|
|
@ -611,7 +606,7 @@ GraphDelayCalc::findInputDriverDelay(const LibertyCell *drvr_cell,
|
|||
for (TimingArcSet *arc_set : drvr_cell->timingArcSets(from_port, to_port)) {
|
||||
for (TimingArc *arc : arc_set->arcs()) {
|
||||
if (arc->toEdge()->asRiseFall() == rf) {
|
||||
float from_slew = from_slews[arc->fromEdge()->index()];
|
||||
float from_slew = (*from_slews)[arc->fromEdge()->index()];
|
||||
findInputArcDelay(drvr_pin, drvr_vertex, arc, from_slew, scene, min_max,
|
||||
arc_delay_calc);
|
||||
}
|
||||
|
|
@ -648,12 +643,12 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin,
|
|||
|
||||
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
|
||||
ArcDcalcResult intrinsic_result =
|
||||
arc_delay_calc->gateDelay(drvr_pin, arc, Slew(from_slew), 0.0, nullptr,
|
||||
arc_delay_calc->gateDelay(drvr_pin, arc, from_slew, 0.0, nullptr,
|
||||
load_pin_index_map, scene, min_max);
|
||||
const ArcDelay &intrinsic_delay = intrinsic_result.gateDelay();
|
||||
|
||||
ArcDcalcResult gate_result = arc_delay_calc->gateDelay(drvr_pin, arc,
|
||||
Slew(from_slew), load_cap,
|
||||
from_slew, load_cap,
|
||||
parasitic,
|
||||
load_pin_index_map,
|
||||
scene, min_max);
|
||||
|
|
@ -1270,19 +1265,19 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
|||
bool load_changed = false;
|
||||
if (!load_vertex->slewAnnotated(drvr_rf, min_max)) {
|
||||
if (drvr_vertex->slewAnnotated(drvr_rf, min_max)) {
|
||||
// Copy the driver slew to the load if it is annotated.
|
||||
const Slew drvr_slew = graph_->slew(drvr_vertex,drvr_rf,ap_index);
|
||||
graph_->setSlew(load_vertex, drvr_rf, ap_index, drvr_slew);
|
||||
// Copy the driver slew to the load if it is annotated.
|
||||
const Slew drvr_slew = graph_->slew(drvr_vertex, drvr_rf, ap_index);
|
||||
graph_->setSlew(load_vertex, drvr_rf, ap_index, drvr_slew);
|
||||
load_changed = true;
|
||||
}
|
||||
else {
|
||||
const Slew slew = graph_->slew(load_vertex, drvr_rf, ap_index);
|
||||
if (!merge
|
||||
}
|
||||
else {
|
||||
const Slew slew = graph_->slew(load_vertex, drvr_rf, ap_index);
|
||||
if (!merge
|
||||
|| delayGreater(load_slew, slew, min_max, this)) {
|
||||
graph_->setSlew(load_vertex, drvr_rf, ap_index, load_slew);
|
||||
graph_->setSlew(load_vertex, drvr_rf, ap_index, load_slew);
|
||||
load_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!graph_->wireDelayAnnotated(wire_edge, drvr_rf, ap_index)) {
|
||||
// Multiple timing arcs with the same output transition
|
||||
|
|
@ -1594,9 +1589,9 @@ GraphDelayCalc::findCheckEdgeDelays(Edge *edge,
|
|||
const RiseFall *to_rf = arc->toEdge()->asRiseFall();
|
||||
if (from_rf && to_rf) {
|
||||
const LibertyPort *related_out_port = arc_set->relatedOut();
|
||||
const Pin *related_out_pin = 0;
|
||||
const Pin *related_out_pin = nullptr;
|
||||
if (related_out_port)
|
||||
related_out_pin = network_->findPin(inst, related_out_port);
|
||||
related_out_pin = network_->findPin(inst, related_out_port);
|
||||
|
||||
for (Scene *scene : scenes_) {
|
||||
for (const MinMax *min_max : MinMax::range()) {
|
||||
|
|
@ -1677,7 +1672,7 @@ GraphDelayCalc::reportDelayCalc(const Edge *edge,
|
|||
const RiseFall *to_rf = arc->toEdge()->asRiseFall();
|
||||
if (from_rf && to_rf) {
|
||||
const LibertyPort *related_out_port = arc_set->relatedOut();
|
||||
const Pin *related_out_pin = 0;
|
||||
const Pin *related_out_pin = nullptr;
|
||||
if (related_out_port)
|
||||
related_out_pin = network_->findPin(inst, related_out_port);
|
||||
float related_out_cap = 0.0;
|
||||
|
|
@ -1767,11 +1762,6 @@ GraphDelayCalc::minPeriod(const Pin *pin,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
MultiDrvrNet::MultiDrvrNet() :
|
||||
dcalc_drvr_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MultiDrvrNet::netCaps(const RiseFall *drvr_rf,
|
||||
const Scene *scene,
|
||||
|
|
@ -1828,4 +1818,4 @@ MultiDrvrNet::parallelGates(const Network *network) const
|
|||
return network->direction(dcalc_drvr_->pin())->isOutput();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@
|
|||
#include <cmath> // isnan
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "Units.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TimingModel.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Network.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Units.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -203,4 +203,4 @@ LumpedCapDelayCalc::reportGateDelay(const Pin *check_pin,
|
|||
return "";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const Scene *scene,
|
||||
const MinMax *min_max) override;
|
||||
std::string reportGateDelay(const Pin *drvr_pin,
|
||||
std::string reportGateDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
|
|
@ -84,4 +84,4 @@ protected:
|
|||
ArcDelayCalc *
|
||||
makeLumpedCapDelayCalc(StaState *sta);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
NetCaps::NetCaps()
|
||||
{
|
||||
}
|
||||
|
||||
NetCaps::NetCaps(float pin_cap,
|
||||
float wire_cap,
|
||||
float fanout,
|
||||
|
|
@ -53,4 +49,4 @@ NetCaps::init(float pin_cap,
|
|||
has_net_load_ = has_net_load;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace sta {
|
|||
class NetCaps
|
||||
{
|
||||
public:
|
||||
NetCaps();
|
||||
NetCaps() = default;
|
||||
NetCaps(float pin_cap,
|
||||
float wire_cap,
|
||||
float fanout,
|
||||
|
|
@ -51,4 +51,4 @@ private:
|
|||
bool has_net_load_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@
|
|||
|
||||
#include "ParallelDelayCalc.hh"
|
||||
|
||||
#include "TimingArc.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TimingArc.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -118,4 +118,4 @@ ParallelDelayCalc::gateDelaysParallel(ArcDcalcArgSeq &dcalc_args,
|
|||
return dcalc_results;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "DelayCalcBase.hh"
|
||||
|
||||
|
|
@ -47,4 +47,4 @@ protected:
|
|||
const MinMax *min_max);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,32 +24,27 @@
|
|||
|
||||
#include "PrimaDelayCalc.hh"
|
||||
|
||||
#include <Eigen/LU>
|
||||
#include <Eigen/QR>
|
||||
#include <cmath> // abs
|
||||
#include <string_view>
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "Units.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Network.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "DmpDelayCalc.hh"
|
||||
#include "Format.hh"
|
||||
|
||||
#include <Eigen/LU>
|
||||
#include <Eigen/QR>
|
||||
#include "Graph.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Parasitics.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Units.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
using Eigen::ColPivHouseholderQR;
|
||||
using Eigen::HouseholderQR;
|
||||
using Eigen::SparseLU;
|
||||
|
||||
// Lawrence Pillage - “Electronic Circuit & System Simulation Methods” 1998
|
||||
// McGraw-Hill, Inc. New York, NY.
|
||||
|
||||
|
|
@ -61,17 +56,7 @@ makePrimaDelayCalc(StaState *sta)
|
|||
|
||||
PrimaDelayCalc::PrimaDelayCalc(StaState *sta) :
|
||||
DelayCalcBase(sta),
|
||||
dcalc_args_(nullptr),
|
||||
scene_(nullptr),
|
||||
min_max_(nullptr),
|
||||
parasitics_(nullptr),
|
||||
parasitic_network_(nullptr),
|
||||
load_pin_index_map_(nullptr),
|
||||
pin_node_map_(network_),
|
||||
prima_order_(3),
|
||||
make_waveforms_(false),
|
||||
waveform_drvr_pin_(nullptr),
|
||||
waveform_load_pin_(nullptr),
|
||||
watch_pin_values_(network_),
|
||||
table_dcalc_(makeDmpCeffElmoreDelayCalc(sta))
|
||||
{
|
||||
|
|
@ -79,20 +64,18 @@ PrimaDelayCalc::PrimaDelayCalc(StaState *sta) :
|
|||
|
||||
PrimaDelayCalc::PrimaDelayCalc(const PrimaDelayCalc &dcalc) :
|
||||
DelayCalcBase(dcalc),
|
||||
dcalc_args_(nullptr),
|
||||
load_pin_index_map_(nullptr),
|
||||
pin_node_map_(network_),
|
||||
node_index_map_(dcalc.node_index_map_),
|
||||
prima_order_(dcalc.prima_order_),
|
||||
make_waveforms_(false),
|
||||
waveform_drvr_pin_(nullptr),
|
||||
waveform_load_pin_(nullptr),
|
||||
watch_pin_values_(network_),
|
||||
table_dcalc_(makeDmpCeffElmoreDelayCalc(this))
|
||||
{
|
||||
}
|
||||
|
||||
PrimaDelayCalc::~PrimaDelayCalc() { delete table_dcalc_; }
|
||||
PrimaDelayCalc::~PrimaDelayCalc()
|
||||
{
|
||||
delete table_dcalc_;
|
||||
}
|
||||
|
||||
ArcDelayCalc *
|
||||
PrimaDelayCalc::copy()
|
||||
|
|
@ -194,8 +177,8 @@ PrimaDelayCalc::gateDelay(const Pin *drvr_pin,
|
|||
ArcDcalcArgSeq dcalc_args;
|
||||
dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, load_cap,
|
||||
parasitic);
|
||||
ArcDcalcResultSeq dcalc_results =
|
||||
gateDelays(dcalc_args, load_pin_index_map, scene, min_max);
|
||||
ArcDcalcResultSeq dcalc_results = gateDelays(dcalc_args, load_pin_index_map,
|
||||
scene, min_max);
|
||||
return dcalc_results[0];
|
||||
}
|
||||
|
||||
|
|
@ -216,43 +199,8 @@ PrimaDelayCalc::gateDelays(ArcDcalcArgSeq &dcalc_args,
|
|||
parasitics_ = scene->parasitics(min_max);
|
||||
node_index_map_ = NodeIndexMap(ParasiticNodeLess(parasitics_, network_));
|
||||
|
||||
bool failed = false;
|
||||
output_waveforms_.resize(drvr_count_);
|
||||
for (size_t drvr_idx = 0; drvr_idx < drvr_count_; drvr_idx++) {
|
||||
ArcDcalcArg &dcalc_arg = dcalc_args[drvr_idx];
|
||||
GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene, min_max);
|
||||
if (table_model && dcalc_arg.parasitic()) {
|
||||
OutputWaveforms *output_waveforms = table_model->outputWaveforms();
|
||||
float in_slew = dcalc_arg.inSlewFlt();
|
||||
if (output_waveforms
|
||||
// Bounds check because extrapolating waveforms does not work for shit.
|
||||
&& output_waveforms->slewAxis()->inBounds(in_slew)
|
||||
&& output_waveforms->capAxis()->inBounds(dcalc_arg.loadCap())) {
|
||||
output_waveforms_[drvr_idx] = output_waveforms;
|
||||
debugPrint(debug_, "ccs_dcalc", 1, "{} {}", dcalc_arg.drvrCell()->name(),
|
||||
drvr_rf_->shortName());
|
||||
LibertyCell *drvr_cell = dcalc_arg.drvrCell();
|
||||
const LibertyLibrary *drvr_library = drvr_cell->libertyLibrary();
|
||||
bool vdd_exists;
|
||||
drvr_library->supplyVoltage("VDD", vdd_, vdd_exists);
|
||||
if (!vdd_exists)
|
||||
report_->error(1720, "VDD not defined in library {}",
|
||||
drvr_library->name());
|
||||
drvr_cell->ensureVoltageWaveforms(scenes_);
|
||||
if (drvr_idx == 0) {
|
||||
vth_ = drvr_library->outputThreshold(drvr_rf_) * vdd_;
|
||||
vl_ = drvr_library->slewLowerThreshold(drvr_rf_) * vdd_;
|
||||
vh_ = drvr_library->slewUpperThreshold(drvr_rf_) * vdd_;
|
||||
}
|
||||
}
|
||||
else
|
||||
failed = true;
|
||||
}
|
||||
else
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
bool arg_fail = checkArgs(dcalc_args, scene, min_max);
|
||||
if (arg_fail)
|
||||
return tableDcalcResults();
|
||||
else {
|
||||
simulate();
|
||||
|
|
@ -260,6 +208,100 @@ PrimaDelayCalc::gateDelays(ArcDcalcArgSeq &dcalc_args,
|
|||
}
|
||||
}
|
||||
|
||||
// Return true on failure.
|
||||
// Use falureReason() to get failure string.
|
||||
bool
|
||||
PrimaDelayCalc::checkArgs(ArcDcalcArgSeq &dcalc_args,
|
||||
const Scene *scene,
|
||||
const MinMax *min_max)
|
||||
{
|
||||
drvr_count_ = dcalc_args.size();
|
||||
output_waveforms_.resize(drvr_count_);
|
||||
failure_reason_ = nullptr;
|
||||
failure_arg_ = nullptr;
|
||||
for (size_t drvr_idx = 0; drvr_idx < drvr_count_; drvr_idx++) {
|
||||
ArcDcalcArg &dcalc_arg = dcalc_args[drvr_idx];
|
||||
GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene, min_max);
|
||||
if (table_model) {
|
||||
if (dcalc_arg.parasitic()) {
|
||||
OutputWaveforms *output_waveforms = table_model->outputWaveforms();
|
||||
float in_slew = dcalc_arg.inSlewFlt();
|
||||
if (output_waveforms) {
|
||||
const LibertyLibrary *drvr_library = dcalc_arg.drvrLibrary();
|
||||
float vdd;
|
||||
bool vdd_exists;
|
||||
drvr_library->supplyVoltage("VDD", vdd, vdd_exists);
|
||||
if (vdd_exists) {
|
||||
if (drvr_idx == 0) {
|
||||
// Assume drivers are in the same library.
|
||||
const RiseFall *drvr_rf = dcalc_arg.drvrEdge();
|
||||
vdd_ = vdd;
|
||||
vth_ = drvr_library->outputThreshold(drvr_rf) * vdd_;
|
||||
vl_ = drvr_library->slewLowerThreshold(drvr_rf) * vdd_;
|
||||
vh_ = drvr_library->slewUpperThreshold(drvr_rf) * vdd_;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failure_reason_ = "vdd not defined";
|
||||
failure_arg_ = &dcalc_arg;
|
||||
}
|
||||
|
||||
// Bounds check because extrapolating waveforms does not work for shit.
|
||||
if (output_waveforms->slewAxis()->inBounds(in_slew)) {
|
||||
if (output_waveforms->capAxis()->inBounds(dcalc_arg.loadCap())) {
|
||||
output_waveforms_[drvr_idx] = output_waveforms;
|
||||
debugPrint(debug_, "prima", 1, "{} {}",
|
||||
dcalc_arg.drvrCell()->name(),
|
||||
dcalc_arg.drvrEdge()->to_string().c_str());
|
||||
LibertyCell *drvr_cell = dcalc_arg.drvrCell();
|
||||
drvr_cell->ensureVoltageWaveforms(scenes_);
|
||||
}
|
||||
else {
|
||||
failure_reason_ = "load cap out of bounds";
|
||||
failure_arg_ = &dcalc_arg;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failure_reason_ = "input slew out of bounds";
|
||||
failure_arg_ = &dcalc_arg;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failure_reason_ = "no output waveforms";
|
||||
failure_arg_ = &dcalc_arg;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failure_reason_ = "no parasitic";
|
||||
failure_arg_ = &dcalc_arg;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failure_reason_ = "no table model";
|
||||
failure_arg_ = &dcalc_arg;
|
||||
}
|
||||
}
|
||||
if (failure_reason_) {
|
||||
std::string reason = failureReason();
|
||||
debugPrint(debug_,"prima", 1, "arg check failed {}.", reason.c_str());
|
||||
}
|
||||
return failure_reason_ != nullptr;
|
||||
}
|
||||
|
||||
std::string
|
||||
PrimaDelayCalc::failureReason()
|
||||
{
|
||||
const Pin *drvr_pin = failure_arg_->drvrPin();
|
||||
const Instance *inst = network_->instance(drvr_pin);
|
||||
LibertyPort *from = failure_arg_->arc()->from();
|
||||
LibertyPort *to = failure_arg_->arc()->to();
|
||||
return sta::format("{} {} -> {} {}",
|
||||
sdc_network_->pathName(inst),
|
||||
from->name(),
|
||||
to->name(),
|
||||
failure_reason_);
|
||||
}
|
||||
|
||||
ArcDcalcResultSeq
|
||||
PrimaDelayCalc::tableDcalcResults()
|
||||
{
|
||||
|
|
@ -300,7 +342,7 @@ PrimaDelayCalc::simulate1(const MatrixSd &G,
|
|||
const Eigen::MatrixXd &B,
|
||||
const Eigen::VectorXd &x_init,
|
||||
const Eigen::MatrixXd &x_to_v,
|
||||
const size_t order)
|
||||
size_t order)
|
||||
{
|
||||
Eigen::VectorXd x(order);
|
||||
Eigen::VectorXd x_prev(order);
|
||||
|
|
@ -320,7 +362,7 @@ PrimaDelayCalc::simulate1(const MatrixSd &G,
|
|||
MatrixSd A(order, order);
|
||||
A = G + (2.0 / time_step_) * C;
|
||||
A.makeCompressed();
|
||||
SparseLU<MatrixSd> A_solver;
|
||||
Eigen::SparseLU<MatrixSd> A_solver;
|
||||
A_solver.compute(A);
|
||||
|
||||
// Initial time depends on ceff which impact delay, so use a sim step
|
||||
|
|
@ -344,7 +386,10 @@ PrimaDelayCalc::simulate1(const MatrixSd &G,
|
|||
if (make_waveforms_)
|
||||
recordWaveformStep(time_begin);
|
||||
|
||||
for (double time = time_begin; time <= time_end; time += time_step_) {
|
||||
for (size_t step = 0;; ++step) {
|
||||
const double time = time_begin + step * time_step_;
|
||||
if (time > time_end)
|
||||
break;
|
||||
setPortCurrents();
|
||||
rhs = B * u_ + (1.0 / time_step_) * C * (3.0 * x_prev - x_prev2);
|
||||
x = A_solver.solve(rhs);
|
||||
|
|
@ -399,6 +444,7 @@ void
|
|||
PrimaDelayCalc::initSim()
|
||||
{
|
||||
ceff_.resize(drvr_count_);
|
||||
ceff_vth_.resize(drvr_count_);
|
||||
drvr_current_.resize(drvr_count_);
|
||||
|
||||
findNodeCount();
|
||||
|
|
@ -615,8 +661,12 @@ PrimaDelayCalc::updateCeffIdrvr()
|
|||
if (drvr_rf_ == RiseFall::rise()) {
|
||||
if (drvr_current != 0.0 && dv > 0.0) {
|
||||
double ceff = drvr_current * time_step_ / dv;
|
||||
if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff))
|
||||
if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) {
|
||||
ceff_[drvr_idx] = ceff;
|
||||
// Record the Ceff at Vth.
|
||||
if (v1 >= vth_ && v2 < vth_)
|
||||
ceff_vth_[drvr_idx] = ceff;
|
||||
}
|
||||
}
|
||||
if (v1 > (vdd_ - .01))
|
||||
// Whoa partner. Head'n for the weeds.
|
||||
|
|
@ -628,8 +678,12 @@ PrimaDelayCalc::updateCeffIdrvr()
|
|||
else {
|
||||
if (drvr_current != 0.0 && dv < 0.0) {
|
||||
double ceff = drvr_current * time_step_ / dv;
|
||||
if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff))
|
||||
if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) {
|
||||
ceff_[drvr_idx] = ceff;
|
||||
// Record the Ceff at Vth.
|
||||
if (v1 <= vth_ && v2 > vth_)
|
||||
ceff_vth_[drvr_idx] = ceff;
|
||||
}
|
||||
}
|
||||
if (v1 < 0.01) {
|
||||
// Whoa partner. Head'n for the weeds.
|
||||
|
|
@ -711,8 +765,13 @@ PrimaDelayCalc::dcalcResults()
|
|||
float ref_time = output_waveforms_[drvr_idx]->referenceTime(dcalc_arg.inSlewFlt());
|
||||
double gate_delay = drvr_times[threshold_vth] - ref_time;
|
||||
double drvr_slew = std::abs(drvr_times[threshold_vh] - drvr_times[threshold_vl]);
|
||||
dcalc_result.setGateDelay(gate_delay);
|
||||
dcalc_result.setDrvrSlew(drvr_slew);
|
||||
|
||||
ArcDelay gate_delay2(gate_delay);
|
||||
Slew drvr_slew2(drvr_slew);
|
||||
delaySlewPocv(dcalc_arg, drvr_idx, gate_delay2, drvr_slew2);
|
||||
dcalc_result.setGateDelay(gate_delay2);
|
||||
dcalc_result.setDrvrSlew(drvr_slew2);
|
||||
|
||||
debugPrint(debug_, "ccs_dcalc", 2, "{} gate delay {} slew {}",
|
||||
network_->pathName(drvr_pin), delayAsString(gate_delay, this),
|
||||
delayAsString(drvr_slew, this));
|
||||
|
|
@ -740,6 +799,28 @@ PrimaDelayCalc::dcalcResults()
|
|||
return dcalc_results;
|
||||
}
|
||||
|
||||
// Fill in pocv parameters in gate_delay/drvr_slew.
|
||||
void
|
||||
PrimaDelayCalc::delaySlewPocv(ArcDcalcArg &dcalc_arg,
|
||||
size_t drvr_idx,
|
||||
ArcDelay &gate_delay,
|
||||
Slew &drvr_slew)
|
||||
{
|
||||
if (variables_->pocvEnabled()) {
|
||||
GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene_, min_max_);
|
||||
if (table_model) {
|
||||
double ceff = ceff_vth_[drvr_idx];
|
||||
if (ceff == 0.0)
|
||||
ceff = dcalc_arg.loadCap();
|
||||
float in_slew = delayAsFloat(dcalc_arg.inSlew());
|
||||
const Pvt *pvt = pinPvt(dcalc_arg.drvrPin(), scene_, min_max_);
|
||||
table_model->gateDelayPocv(pvt, in_slew, ceff, min_max_,
|
||||
variables_->pocvMode(),
|
||||
gate_delay, drvr_slew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
|
@ -755,7 +836,7 @@ PrimaDelayCalc::primaReduce()
|
|||
{
|
||||
G_.makeCompressed();
|
||||
// Step 3: solve G*R = B for R
|
||||
SparseLU<MatrixSd> G_solver(G_);
|
||||
Eigen::SparseLU<MatrixSd> G_solver(G_);
|
||||
if (G_solver.info() != Eigen::Success)
|
||||
report_->error(1752, "G matrix is singular.");
|
||||
Eigen::MatrixXd R(order_, port_count_);
|
||||
|
|
@ -896,20 +977,35 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin,
|
|||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *,
|
||||
const LoadPinIndexMap &,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const Scene *scene,
|
||||
const MinMax *min_max,
|
||||
int digits)
|
||||
{
|
||||
GateTimingModel *model = arc->gateModel(scene, min_max);
|
||||
if (model) {
|
||||
ArcDcalcArgSeq dcalc_args;
|
||||
dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew,
|
||||
load_cap, parasitic);
|
||||
bool arg_fail = checkArgs(dcalc_args, scene, min_max);
|
||||
if (arg_fail) {
|
||||
const RiseFall *rf = arc->toEdge()->asRiseFall();
|
||||
const Parasitic *reduced = table_dcalc_->findParasitic(drvr_pin, rf,
|
||||
scene, min_max);
|
||||
return table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap,
|
||||
reduced, load_pin_index_map, scene,
|
||||
min_max, digits);
|
||||
}
|
||||
else {
|
||||
GateTimingModel *model = arc->gateModel(scene, min_max);
|
||||
// Delay calc to find ceff.
|
||||
gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic,
|
||||
load_pin_index_map, scene, min_max);
|
||||
float in_slew1 = delayAsFloat(in_slew);
|
||||
float ceff = ceff_vth_[0];
|
||||
return model->reportGateDelay(pinPvt(drvr_pin, scene, min_max),
|
||||
in_slew1, load_cap, min_max,
|
||||
in_slew1, ceff, min_max,
|
||||
PocvMode::scalar, digits);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -932,7 +1028,7 @@ PinSeq
|
|||
PrimaDelayCalc::watchPins() const
|
||||
{
|
||||
PinSeq pins;
|
||||
for (auto pin_values : watch_pin_values_) {
|
||||
for (const auto &pin_values : watch_pin_values_) {
|
||||
const Pin *pin = pin_values.first;
|
||||
pins.push_back(pin);
|
||||
}
|
||||
|
|
@ -1011,10 +1107,8 @@ void
|
|||
PrimaDelayCalc::reportMatrix(Eigen::VectorXd &matrix)
|
||||
{
|
||||
std::string line = "| ";
|
||||
for (Eigen::Index i = 0; i < matrix.rows(); i++) {
|
||||
std::string entry =
|
||||
for (Eigen::Index i = 0; i < matrix.rows(); i++)
|
||||
line += sta::format("{:10.3e}", matrix.coeff(i)) + " ";
|
||||
}
|
||||
line += "|";
|
||||
report_->reportLine(line);
|
||||
}
|
||||
|
|
@ -1023,8 +1117,8 @@ void
|
|||
PrimaDelayCalc::reportVector(std::vector<double> &matrix)
|
||||
{
|
||||
std::string line = "| ";
|
||||
for (size_t i = 0; i < matrix.size(); i++)
|
||||
line += sta::format("{:10.3e}", matrix[i]) + " ";
|
||||
for (const double &entry : matrix)
|
||||
line += sta::format("{:10.3e}", entry) + " ";
|
||||
line += "|";
|
||||
report_->reportLine(line);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <Eigen/SparseCore>
|
||||
#include <Eigen/SparseLU>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "ArcDcalcWaveforms.hh"
|
||||
#include "LumpedCapDelayCalc.hh"
|
||||
#include "Parasitics.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -57,7 +58,7 @@ class PrimaDelayCalc : public DelayCalcBase,
|
|||
public:
|
||||
PrimaDelayCalc(StaState *sta);
|
||||
PrimaDelayCalc(const PrimaDelayCalc &dcalc);
|
||||
~PrimaDelayCalc();
|
||||
~PrimaDelayCalc() override;
|
||||
ArcDelayCalc *copy() override;
|
||||
void copyState(const StaState *sta) override;
|
||||
std::string_view name() const override { return "prima"; }
|
||||
|
|
@ -100,6 +101,10 @@ public:
|
|||
const Scene *scene,
|
||||
const MinMax *min_max,
|
||||
int digits) override;
|
||||
bool checkArgs(ArcDcalcArgSeq &dcalc_args,
|
||||
const Scene *scene,
|
||||
const MinMax *min_max);
|
||||
std::string failureReason();
|
||||
|
||||
// Record waveform for drvr/load pin.
|
||||
void watchPin(const Pin *pin) override;
|
||||
|
|
@ -108,6 +113,10 @@ public:
|
|||
Waveform watchWaveform(const Pin *pin) override;
|
||||
|
||||
protected:
|
||||
void delaySlewPocv(ArcDcalcArg &dcalc_arg,
|
||||
size_t drvr_idx,
|
||||
ArcDelay &gate_delay,
|
||||
Slew &drvr_slew);
|
||||
ArcDcalcResultSeq tableDcalcResults();
|
||||
void simulate();
|
||||
void simulate1(const MatrixSd &G,
|
||||
|
|
@ -115,7 +124,7 @@ protected:
|
|||
const Eigen::MatrixXd &B,
|
||||
const Eigen::VectorXd &x_init,
|
||||
const Eigen::MatrixXd &x_to_v,
|
||||
const size_t order);
|
||||
size_t order);
|
||||
double maxTime();
|
||||
double timeStep();
|
||||
float driverResistance();
|
||||
|
|
@ -170,15 +179,15 @@ protected:
|
|||
void reportMatrix(Eigen::VectorXd &matrix);
|
||||
void reportVector(std::vector<double> &matrix);
|
||||
|
||||
ArcDcalcArgSeq *dcalc_args_;
|
||||
ArcDcalcArgSeq *dcalc_args_{nullptr};
|
||||
size_t drvr_count_;
|
||||
float load_cap_;
|
||||
const Scene *scene_;
|
||||
const MinMax *min_max_;
|
||||
Parasitics *parasitics_;
|
||||
const Parasitic *parasitic_network_;
|
||||
const Scene *scene_{nullptr};
|
||||
const MinMax *min_max_{nullptr};
|
||||
Parasitics *parasitics_{nullptr};
|
||||
const Parasitic *parasitic_network_{nullptr};
|
||||
const RiseFall *drvr_rf_;
|
||||
const LoadPinIndexMap *load_pin_index_map_;
|
||||
const LoadPinIndexMap *load_pin_index_map_{nullptr};
|
||||
|
||||
PinNodeMap pin_node_map_; // Parasitic pin -> array index
|
||||
NodeIndexMap node_index_map_; // Parasitic node -> array index
|
||||
|
|
@ -202,7 +211,7 @@ protected:
|
|||
Eigen::VectorXd u_;
|
||||
|
||||
// Prima reduced MNA eqns
|
||||
size_t prima_order_;
|
||||
size_t prima_order_{3};
|
||||
Eigen::MatrixXd Vq_;
|
||||
MatrixSd Gq_;
|
||||
MatrixSd Cq_;
|
||||
|
|
@ -215,15 +224,17 @@ protected:
|
|||
|
||||
// Indexed by driver index.
|
||||
std::vector<double> ceff_;
|
||||
// Ceff at Vth
|
||||
std::vector<double> ceff_vth_;
|
||||
std::vector<double> drvr_current_;
|
||||
|
||||
double time_step_;
|
||||
double time_step_prev_;
|
||||
|
||||
// Waveform recording.
|
||||
bool make_waveforms_;
|
||||
const Pin *waveform_drvr_pin_;
|
||||
const Pin *waveform_load_pin_;
|
||||
bool make_waveforms_{false};
|
||||
const Pin *waveform_drvr_pin_{nullptr};
|
||||
const Pin *waveform_load_pin_{nullptr};
|
||||
FloatSeq drvr_voltages_;
|
||||
FloatSeq load_voltages_;
|
||||
WatchPinValuesMap watch_pin_values_;
|
||||
|
|
@ -238,7 +249,7 @@ protected:
|
|||
static constexpr size_t threshold_vth = 1;
|
||||
static constexpr size_t threshold_vh = 2;
|
||||
static constexpr size_t measure_threshold_count_ = 3;
|
||||
typedef std::array<double, measure_threshold_count_> ThresholdTimes;
|
||||
using ThresholdTimes = std::array<double, measure_threshold_count_>;
|
||||
// Vl Vth Vh
|
||||
ThresholdTimes measure_thresholds_;
|
||||
// Indexed by node number.
|
||||
|
|
@ -247,7 +258,10 @@ protected:
|
|||
// Delay calculator to use when ccs waveforms are missing from liberty.
|
||||
ArcDelayCalc *table_dcalc_;
|
||||
|
||||
const char *failure_reason_;
|
||||
ArcDcalcArg *failure_arg_;
|
||||
|
||||
using ArcDelayCalc::reduceParasitic;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -187,4 +187,4 @@ UnitDelayCalc::finishDrvrPin()
|
|||
{
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -109,4 +109,4 @@ protected:
|
|||
ArcDelayCalc *
|
||||
makeUnitDelayCalc(StaState *sta);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1 +1,6 @@
|
|||
sta_module_tests("dcalc"
|
||||
TESTS
|
||||
prima_report
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
|
|
|
|||
|
|
@ -166,9 +166,8 @@ TEST_F(FindRootAdditionalTest, RootAtX1) {
|
|||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 5-5 = 0, y2 = 10-5 = 5
|
||||
double root = findRoot(func, 5.0, 0.0, 10.0, 5.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 5.0, 0.0, 10.0, 5.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-8);
|
||||
}
|
||||
|
|
@ -179,9 +178,8 @@ TEST_F(FindRootAdditionalTest, RootAtX2) {
|
|||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 0-5 = -5, y2 = 5-5 = 0
|
||||
double root = findRoot(func, 0.0, -5.0, 5.0, 0.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, -5.0, 5.0, 0.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-8);
|
||||
}
|
||||
|
|
@ -192,9 +190,8 @@ TEST_F(FindRootAdditionalTest, BothPositiveFails) {
|
|||
y = x * x + 1.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 2, y2 = 5 -- both positive
|
||||
findRoot(func, 1.0, 2.0, 2.0, 5.0, 1e-10, 100, fail);
|
||||
auto [root_, fail] = findRoot(func, 1.0, 2.0, 2.0, 5.0, 1e-10, 100);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -204,8 +201,7 @@ TEST_F(FindRootAdditionalTest, BothNegativeFails) {
|
|||
y = -x * x - 1.0;
|
||||
dy = -2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, 1.0, -2.0, 2.0, -5.0, 1e-10, 100, fail);
|
||||
auto [root_, fail] = findRoot(func, 1.0, -2.0, 2.0, -5.0, 1e-10, 100);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -215,9 +211,8 @@ TEST_F(FindRootAdditionalTest, MaxIterationsExceeded) {
|
|||
y = x * x - 2.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
// Very tight tolerance with only 1 iteration
|
||||
findRoot(func, 0.0, 3.0, 1e-15, 1, fail);
|
||||
auto [root_, fail] = findRoot(func, 0.0, 3.0, 1e-15, 1);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -227,9 +222,8 @@ TEST_F(FindRootAdditionalTest, SwapWhenY1Positive) {
|
|||
y = x - 3.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 2.0 > 0, y2 = -2.0 < 0 => swap internally
|
||||
double root = findRoot(func, 5.0, 2.0, 1.0, -2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 5.0, 2.0, 1.0, -2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -240,8 +234,7 @@ TEST_F(FindRootAdditionalTest, CubicRoot) {
|
|||
y = x * x * x - 8.0;
|
||||
dy = 3.0 * x * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -252,8 +245,7 @@ TEST_F(FindRootAdditionalTest, TwoArgOverloadCubic) {
|
|||
y = x * x * x - 27.0;
|
||||
dy = 3.0 * x * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 2.0, 4.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.0, 4.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -1467,15 +1459,14 @@ TEST_F(ArcDcalcResultTest, CopyResult) {
|
|||
EXPECT_FLOAT_EQ(delayAsFloat(copy.loadSlew(1)), 6e-12f);
|
||||
}
|
||||
|
||||
// Test ArcDcalcArg assignment
|
||||
TEST_F(ArcDcalcArgTest, Assignment) {
|
||||
// Test ArcDcalcArg copy construction with alternate values
|
||||
TEST_F(ArcDcalcArgTest, CopyConstructionAltValues) {
|
||||
ArcDcalcArg arg;
|
||||
arg.setLoadCap(3.5e-12f);
|
||||
arg.setInputDelay(1.5e-9f);
|
||||
arg.setInSlew(200e-12f);
|
||||
|
||||
ArcDcalcArg other;
|
||||
other = arg;
|
||||
ArcDcalcArg other(arg);
|
||||
EXPECT_FLOAT_EQ(other.loadCap(), 3.5e-12f);
|
||||
EXPECT_FLOAT_EQ(other.inputDelay(), 1.5e-9f);
|
||||
EXPECT_FLOAT_EQ(other.inSlewFlt(), 200e-12f);
|
||||
|
|
@ -1503,9 +1494,8 @@ TEST_F(FindRootAdditionalTest, FlatDerivative) {
|
|||
y = (x - 2.0) * (x - 2.0) * (x - 2.0);
|
||||
dy = 3.0 * (x - 2.0) * (x - 2.0);
|
||||
};
|
||||
bool fail = false;
|
||||
// y at x=1 = -1, y at x=3 = 1
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-8, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-8, 100);
|
||||
if (!fail) {
|
||||
EXPECT_NEAR(root, 2.0, 1e-4);
|
||||
}
|
||||
|
|
@ -1517,8 +1507,7 @@ TEST_F(FindRootAdditionalTest, LinearFunction) {
|
|||
y = 2.0 * x - 6.0;
|
||||
dy = 2.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 10.0, 1e-12, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, 10.0, 1e-12, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -1529,9 +1518,8 @@ TEST_F(FindRootAdditionalTest, FourArgNormalBracket) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 1-4 = -3, y2 = 9-4 = 5
|
||||
double root = findRoot(func, 1.0, -3.0, 3.0, 5.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, -3.0, 3.0, 5.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -1715,7 +1703,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(250.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 500.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 500.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
design_loaded_ = true;
|
||||
}
|
||||
|
|
@ -2092,9 +2080,8 @@ TEST_F(FindRootAdditionalTest, TightBoundsLinear) {
|
|||
y = 2.0 * x - 6.0;
|
||||
dy = 2.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 2*2.9-6 = -0.2, y2 = 2*3.1-6 = 0.2
|
||||
double root = findRoot(func, 2.9, -0.2, 3.1, 0.2, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.9, -0.2, 3.1, 0.2, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2106,8 +2093,7 @@ TEST_F(FindRootAdditionalTest, NewtonOutOfBracket) {
|
|||
y = x * x * x - x - 2.0;
|
||||
dy = 3.0 * x * x - 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
// Root is near 1.52138
|
||||
EXPECT_NEAR(root, 1.52138, 1e-4);
|
||||
|
|
@ -2119,9 +2105,8 @@ TEST_F(FindRootAdditionalTest, SinRoot) {
|
|||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
// Root near pi
|
||||
double root = findRoot(func, 3.0, 3.3, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 3.0, 3.3, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, M_PI, 1e-8);
|
||||
}
|
||||
|
|
@ -2132,8 +2117,7 @@ TEST_F(FindRootAdditionalTest, ExpMinusConst) {
|
|||
y = exp(x) - 3.0;
|
||||
dy = exp(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, 2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, log(3.0), 1e-8);
|
||||
}
|
||||
|
|
@ -2395,8 +2379,7 @@ TEST_F(FindRootAdditionalTest, QuadraticExact) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2407,9 +2390,8 @@ TEST_F(FindRootAdditionalTest, QuadraticFourArg) {
|
|||
y = x * x - 9.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
// y(2.5) = 6.25-9 = -2.75, y(3.5) = 12.25-9 = 3.25
|
||||
double root = findRoot(func, 2.5, -2.75, 3.5, 3.25, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.5, -2.75, 3.5, 3.25, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2590,8 +2572,7 @@ TEST_F(FindRootAdditionalTest, LinearFunction2) {
|
|||
y = 2.0 * x - 10.0;
|
||||
dy = 2.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 10.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, 10.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2601,9 +2582,8 @@ TEST_F(FindRootAdditionalTest, FourArgLinear) {
|
|||
y = 3.0 * x - 6.0;
|
||||
dy = 3.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y(1.0) = -3, y(3.0) = 3
|
||||
double root = findRoot(func, 1.0, -3.0, 3.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, -3.0, 3.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2613,8 +2593,7 @@ TEST_F(FindRootAdditionalTest, HighOrderPoly) {
|
|||
y = x * x * x * x - 16.0;
|
||||
dy = 4.0 * x * x * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-6);
|
||||
}
|
||||
|
|
@ -2624,8 +2603,7 @@ TEST_F(FindRootAdditionalTest, NegativeRoot) {
|
|||
y = x + 3.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -5.0, -1.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -5.0, -1.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2635,9 +2613,8 @@ TEST_F(FindRootAdditionalTest, TrigFunction) {
|
|||
y = std::cos(x);
|
||||
dy = -std::sin(x);
|
||||
};
|
||||
bool fail = false;
|
||||
// Root at pi/2
|
||||
double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, M_PI / 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2647,8 +2624,7 @@ TEST_F(FindRootAdditionalTest, VeryTightBounds) {
|
|||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 4.999, 5.001, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 4.999, 5.001, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2658,8 +2634,7 @@ TEST_F(FindRootAdditionalTest, ExpFunction) {
|
|||
y = std::exp(x) - 10.0;
|
||||
dy = std::exp(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, std::log(10.0), 1e-8);
|
||||
}
|
||||
|
|
@ -2669,9 +2644,8 @@ TEST_F(FindRootAdditionalTest, FourArgSwap) {
|
|||
y = x - 7.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 3.0 > 0, y2 = -7.0 < 0 => internal swap
|
||||
double root = findRoot(func, 10.0, 3.0, 0.0, -7.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 10.0, 3.0, 0.0, -7.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 7.0, 1e-8);
|
||||
}
|
||||
|
|
@ -2829,14 +2803,13 @@ TEST_F(ArcDcalcArgTest, InputDelayConstructorZero) {
|
|||
EXPECT_FLOAT_EQ(arg.inputDelay(), 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(ArcDcalcArgTest, CopyAssignment) {
|
||||
TEST_F(ArcDcalcArgTest, CopyConstructionAltValues2) {
|
||||
ArcDcalcArg arg;
|
||||
arg.setLoadCap(3.0e-12f);
|
||||
arg.setInputDelay(2.0e-9f);
|
||||
arg.setInSlew(75e-12f);
|
||||
|
||||
ArcDcalcArg copy;
|
||||
copy = arg;
|
||||
ArcDcalcArg copy(arg);
|
||||
EXPECT_FLOAT_EQ(copy.loadCap(), 3.0e-12f);
|
||||
EXPECT_FLOAT_EQ(copy.inputDelay(), 2.0e-9f);
|
||||
EXPECT_FLOAT_EQ(copy.inSlewFlt(), 75e-12f);
|
||||
|
|
@ -3369,8 +3342,7 @@ TEST_F(FindRootAdditionalTest, SteepDerivative) {
|
|||
y = 1000.0 * x - 500.0;
|
||||
dy = 1000.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 1.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, 1.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 0.5, 1e-8);
|
||||
}
|
||||
|
|
@ -3381,8 +3353,7 @@ TEST_F(FindRootAdditionalTest, QuarticRoot) {
|
|||
y = x*x*x*x - 81.0;
|
||||
dy = 4.0*x*x*x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 2.0, 4.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.0, 4.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-6);
|
||||
}
|
||||
|
|
@ -3393,8 +3364,7 @@ TEST_F(FindRootAdditionalTest, FourArgNegBracket) {
|
|||
y = x + 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -8.0, -3.0, -2.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -8.0, -3.0, -2.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -5.0, 1e-8);
|
||||
}
|
||||
|
|
@ -4204,7 +4174,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 10.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
// Set input/output delay constraints to create constrained timing paths
|
||||
Clock *clk = sta_->cmdSdc()->findClock("clk");
|
||||
|
|
@ -4448,7 +4418,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 10.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
Clock *clk = sta_->cmdSdc()->findClock("clk");
|
||||
ASSERT_NE(clk, nullptr);
|
||||
|
|
@ -4629,7 +4599,7 @@ TEST_F(MultiDriverDcalcTest, IncrementalClockPeriodChange) {
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(1.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 2.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 2.0f, *waveform, "", sta_->cmdMode());
|
||||
sta_->updateTiming(true);
|
||||
Slack slack2 = sta_->worstSlack(MinMax::max());
|
||||
|
||||
|
|
@ -4765,7 +4735,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 10.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
// Set input/output delay constraints to create constrained timing paths
|
||||
Clock *clk = sta_->cmdSdc()->findClock("clk");
|
||||
|
|
@ -4891,7 +4861,7 @@ TEST_F(DesignDcalcTest, IncrementalWithSpef) {
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(50.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 100.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 100.0f, *waveform, "", sta_->cmdMode());
|
||||
sta_->updateTiming(true);
|
||||
Slack slack2 = sta_->worstSlack(MinMax::max());
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ TEST_F(FindRootTest, QuadraticPositiveRoot) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -29,8 +28,7 @@ TEST_F(FindRootTest, QuadraticNegativeRoot) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -3.0, -1.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -3.0, -1.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -41,8 +39,7 @@ TEST_F(FindRootTest, LinearRoot) {
|
|||
y = x - 1.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, 2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-8);
|
||||
}
|
||||
|
|
@ -53,8 +50,7 @@ TEST_F(FindRootTest, SinRoot) {
|
|||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 2.5, 3.8, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.5, 3.8, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, M_PI, 1e-6);
|
||||
}
|
||||
|
|
@ -65,8 +61,7 @@ TEST_F(FindRootTest, ExponentialRoot) {
|
|||
y = exp(x) - 2.0;
|
||||
dy = exp(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 1.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.0, 1.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, log(2.0), 1e-8);
|
||||
}
|
||||
|
|
@ -77,8 +72,7 @@ TEST_F(FindRootTest, TightTolerance) {
|
|||
y = x * x - 2.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 2.0, 1e-14, 200, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-14, 200);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, sqrt(2.0), 1e-12);
|
||||
}
|
||||
|
|
@ -89,9 +83,8 @@ TEST_F(FindRootTest, WithPrecomputedY) {
|
|||
y = x * x - 9.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
// x1=2, y1=4-9=-5, x2=4, y2=16-9=7
|
||||
double root = findRoot(func, 2.0, -5.0, 4.0, 7.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.0, -5.0, 4.0, 7.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
@ -106,8 +99,7 @@ TEST_F(FindRootTest, VeryTightTolerance) {
|
|||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 3.0, 7.0, 1e-15, 500, fail);
|
||||
auto [root, fail] = findRoot(func, 3.0, 7.0, 1e-15, 500);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-13);
|
||||
}
|
||||
|
|
@ -118,8 +110,7 @@ TEST_F(FindRootTest, LooseTolerance) {
|
|||
y = x * x - 25.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 3.0, 7.0, 1e-1, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 3.0, 7.0, 1e-1, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
// With 10% relative tolerance, result should still be in the right ballpark
|
||||
EXPECT_NEAR(root, 5.0, 0.6);
|
||||
|
|
@ -132,8 +123,7 @@ TEST_F(FindRootTest, ZeroTolerance) {
|
|||
y = x - 3.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 5.0, 0.0, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 5.0, 0.0, 100);
|
||||
// May or may not converge -- for a linear function Newton converges in 1 step
|
||||
// so dx can be exactly 0. Accept either outcome.
|
||||
if (!fail) {
|
||||
|
|
@ -152,8 +142,7 @@ TEST_F(FindRootTest, OneIteration) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 1, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 1);
|
||||
// With only 1 iteration, a quadratic likely won't converge to tight tol
|
||||
// The algorithm may or may not fail depending on initial bisection step
|
||||
// Root should still be a finite number within the bracket
|
||||
|
|
@ -169,8 +158,7 @@ TEST_F(FindRootTest, TwoIterations) {
|
|||
y = x - 7.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 5.0, 9.0, 1e-10, 2, fail);
|
||||
auto [root, fail] = findRoot(func, 5.0, 9.0, 1e-10, 2);
|
||||
// Linear function: Newton should converge very fast
|
||||
// After the initial midpoint (7.0), Newton step should nail it
|
||||
if (!fail) {
|
||||
|
|
@ -184,8 +172,7 @@ TEST_F(FindRootTest, ZeroMaxIterations) {
|
|||
y = x - 1.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, 0.0, 2.0, 1e-10, 0, fail);
|
||||
auto [root_, fail] = findRoot(func, 0.0, 2.0, 1e-10, 0);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -195,8 +182,7 @@ TEST_F(FindRootTest, LargeMaxIter) {
|
|||
y = x * x - 16.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 10.0, 1e-12, 10000, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 10.0, 1e-12, 10000);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 4.0, 1e-10);
|
||||
}
|
||||
|
|
@ -211,8 +197,7 @@ TEST_F(FindRootTest, CubicRoot) {
|
|||
y = x * x * x - 8.0;
|
||||
dy = 3.0 * x * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -223,8 +208,7 @@ TEST_F(FindRootTest, QuarticRoot) {
|
|||
y = x * x * x * x - 16.0;
|
||||
dy = 4.0 * x * x * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -235,8 +219,7 @@ TEST_F(FindRootTest, ExponentialRoot2) {
|
|||
y = exp(x) - 10.0;
|
||||
dy = exp(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 4.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 4.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, log(10.0), 1e-8);
|
||||
}
|
||||
|
|
@ -248,8 +231,7 @@ TEST_F(FindRootTest, SqrtFunctionRoot) {
|
|||
y = sqrt(x) - 3.0;
|
||||
dy = 0.5 / sqrt(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 20.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 20.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 9.0, 1e-6);
|
||||
}
|
||||
|
|
@ -267,8 +249,7 @@ TEST_F(FindRootTest, NearZeroRootLinear) {
|
|||
y = x - 1e-10;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1.0, 1.0, 1e-6, 200, fail);
|
||||
auto [root, fail] = findRoot(func, -1.0, 1.0, 1e-6, 200);
|
||||
// Newton on a linear function converges in 1-2 steps regardless of root location
|
||||
if (!fail) {
|
||||
EXPECT_NEAR(root, 1e-10, 1e-6);
|
||||
|
|
@ -283,8 +264,7 @@ TEST_F(FindRootTest, RootExactlyAtZero) {
|
|||
y = x;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1.0, 1.0, 1e-10, 200, fail);
|
||||
auto [root, fail] = findRoot(func, -1.0, 1.0, 1e-10, 200);
|
||||
// Even if fail is true, root should be very close to 0
|
||||
EXPECT_NEAR(root, 0.0, 1e-6);
|
||||
}
|
||||
|
|
@ -299,8 +279,7 @@ TEST_F(FindRootTest, NegativeDomainRoot) {
|
|||
y = x + 100.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -200.0, 0.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -200.0, 0.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -100.0, 1e-6);
|
||||
}
|
||||
|
|
@ -311,8 +290,7 @@ TEST_F(FindRootTest, NegativeBracketRoot) {
|
|||
y = x * x - 1.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -2.0, -0.5, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -2.0, -0.5, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -1.0, 1e-8);
|
||||
}
|
||||
|
|
@ -327,8 +305,7 @@ TEST_F(FindRootTest, SinRootAtZero) {
|
|||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1.0, 1.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -1.0, 1.0, 1e-10, 100);
|
||||
// Root at 0 has the relative-tolerance issue, but Newton converges fast for sin
|
||||
EXPECT_NEAR(root, 0.0, 1e-4);
|
||||
}
|
||||
|
|
@ -339,8 +316,7 @@ TEST_F(FindRootTest, SinRootAt2Pi) {
|
|||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 5.5, 7.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 5.5, 7.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0 * M_PI, 1e-6);
|
||||
}
|
||||
|
|
@ -351,8 +327,7 @@ TEST_F(FindRootTest, CosRootAtPiOver2) {
|
|||
y = cos(x);
|
||||
dy = -sin(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, M_PI / 2.0, 1e-6);
|
||||
}
|
||||
|
|
@ -368,8 +343,7 @@ TEST_F(FindRootTest, MultipleRootsFindFirst) {
|
|||
y = (x - 1.0) * (x - 2.0);
|
||||
dy = 2.0 * x - 3.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.5, 1.5, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.5, 1.5, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-8);
|
||||
}
|
||||
|
|
@ -380,8 +354,7 @@ TEST_F(FindRootTest, MultipleRootsFindSecond) {
|
|||
y = (x - 1.0) * (x - 2.0);
|
||||
dy = 2.0 * x - 3.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.5, 2.5, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.5, 2.5, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -397,8 +370,7 @@ TEST_F(FindRootTest, AbsValueRoot) {
|
|||
y = fabs(x) - 1.0;
|
||||
dy = (x >= 0.0) ? 1.0 : -1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.5, 2.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.5, 2.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-8);
|
||||
}
|
||||
|
|
@ -409,8 +381,7 @@ TEST_F(FindRootTest, AbsValueNegativeRoot) {
|
|||
y = fabs(x) - 1.0;
|
||||
dy = (x >= 0.0) ? 1.0 : -1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -2.0, -0.5, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -2.0, -0.5, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -1.0, 1e-8);
|
||||
}
|
||||
|
|
@ -430,8 +401,7 @@ TEST_F(FindRootTest, FlatFifthOrderRootFails) {
|
|||
y = d4 * d; // (x-3)^5
|
||||
dy = 5.0 * d4; // 5*(x-3)^4
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, 2.0, 4.0, 1e-6, 500, fail);
|
||||
auto [root_, fail] = findRoot(func, 2.0, 4.0, 1e-6, 500);
|
||||
// The algorithm is expected to fail because dy -> 0 at the root
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
|
@ -444,8 +414,7 @@ TEST_F(FindRootTest, FlatSinhRoot) {
|
|||
y = sinh(x - 3.0);
|
||||
dy = cosh(x - 3.0);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 2.0, 4.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.0, 4.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-6);
|
||||
}
|
||||
|
|
@ -460,8 +429,7 @@ TEST_F(FindRootTest, SteepLinearRoot) {
|
|||
y = 1000.0 * (x - 5.0);
|
||||
dy = 1000.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 3.0, 7.0, 1e-12, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 3.0, 7.0, 1e-12, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-10);
|
||||
}
|
||||
|
|
@ -472,8 +440,7 @@ TEST_F(FindRootTest, VerySteepLinearRoot) {
|
|||
y = 1e6 * (x - 2.0);
|
||||
dy = 1e6;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-14, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-14, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-12);
|
||||
}
|
||||
|
|
@ -488,8 +455,7 @@ TEST_F(FindRootTest, LargeBracket) {
|
|||
y = x - 42.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1000.0, 1000.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -1000.0, 1000.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 42.0, 1e-6);
|
||||
}
|
||||
|
|
@ -500,8 +466,7 @@ TEST_F(FindRootTest, LargeBracketQuadratic) {
|
|||
y = x * x - 100.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 1000.0, 1e-10, 200, fail);
|
||||
auto [root, fail] = findRoot(func, 1.0, 1000.0, 1e-10, 200);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 10.0, 1e-6);
|
||||
}
|
||||
|
|
@ -516,8 +481,7 @@ TEST_F(FindRootTest, SmallBracket) {
|
|||
y = x - 1.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.999999, 1.000001, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.999999, 1.000001, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-6);
|
||||
}
|
||||
|
|
@ -528,8 +492,7 @@ TEST_F(FindRootTest, SmallBracketQuadratic) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.9999, 2.0001, 1e-12, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 1.9999, 2.0001, 1e-12, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -545,14 +508,12 @@ TEST_F(FindRootTest, OverloadsProduceSameResult) {
|
|||
dy = 3.0 * x * x;
|
||||
};
|
||||
|
||||
bool fail_2arg = false;
|
||||
double root_2arg = findRoot(func, 2.0, 4.0, 1e-12, 100, fail_2arg);
|
||||
auto [root_2arg, fail_2arg] = findRoot(func, 2.0, 4.0, 1e-12, 100);
|
||||
|
||||
// Pre-compute y values for 4-arg version
|
||||
double y1 = 2.0 * 2.0 * 2.0 - 27.0; // 8 - 27 = -19
|
||||
double y2 = 4.0 * 4.0 * 4.0 - 27.0; // 64 - 27 = 37
|
||||
bool fail_4arg = false;
|
||||
double root_4arg = findRoot(func, 2.0, y1, 4.0, y2, 1e-12, 100, fail_4arg);
|
||||
auto [root_4arg, fail_4arg] = findRoot(func, 2.0, y1, 4.0, y2, 1e-12, 100);
|
||||
|
||||
EXPECT_FALSE(fail_2arg);
|
||||
EXPECT_FALSE(fail_4arg);
|
||||
|
|
@ -567,9 +528,8 @@ TEST_F(FindRootTest, FourArgX1IsRoot) {
|
|||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y1 = 5 - 5 = 0
|
||||
double root = findRoot(func, 5.0, 0.0, 8.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 5.0, 0.0, 8.0, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_DOUBLE_EQ(root, 5.0);
|
||||
}
|
||||
|
|
@ -580,9 +540,8 @@ TEST_F(FindRootTest, FourArgX2IsRoot) {
|
|||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// y2 = 5 - 5 = 0
|
||||
double root = findRoot(func, 2.0, -3.0, 5.0, 0.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 2.0, -3.0, 5.0, 0.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_DOUBLE_EQ(root, 5.0);
|
||||
}
|
||||
|
|
@ -597,8 +556,7 @@ TEST_F(FindRootTest, BothEndpointsPositiveFails) {
|
|||
y = x * x + 1.0; // Always positive, no real root
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root_, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -608,8 +566,7 @@ TEST_F(FindRootTest, BothEndpointsNegativeFails) {
|
|||
y = -x * x - 1.0; // Always negative
|
||||
dy = -2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, -3.0, 3.0, 1e-10, 100, fail);
|
||||
auto [root_, fail] = findRoot(func, -3.0, 3.0, 1e-10, 100);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -619,9 +576,8 @@ TEST_F(FindRootTest, FourArgSameSignFails) {
|
|||
y = x * x;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
// Both y values positive
|
||||
findRoot(func, 1.0, 1.0, 2.0, 4.0, 1e-10, 100, fail);
|
||||
auto [root_, fail] = findRoot(func, 1.0, 1.0, 2.0, 4.0, 1e-10, 100);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
|
|
@ -635,8 +591,7 @@ TEST_F(FindRootTest, SymmetryPositiveBracket) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.5, 3.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 0.5, 3.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -646,8 +601,7 @@ TEST_F(FindRootTest, SymmetryNegativeBracket) {
|
|||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -3.0, -0.5, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, -3.0, -0.5, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -2.0, 1e-8);
|
||||
}
|
||||
|
|
@ -662,9 +616,8 @@ TEST_F(FindRootTest, SwappedBracketOrder) {
|
|||
y = x - 3.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
// x1=5 > x2=1 (reversed order)
|
||||
double root = findRoot(func, 5.0, 1.0, 1e-10, 100, fail);
|
||||
auto [root, fail] = findRoot(func, 5.0, 1.0, 1e-10, 100);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13178, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13211, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13244, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13277, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13310, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13343, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13376, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14772, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14805, timing group from output port.
|
||||
Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14838, timing group from output port.
|
||||
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: max
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ r2/CLK (DFFHQx4_ASAP7_75t_R)
|
||||
52.65 52.65 ^ r2/Q (DFFHQx4_ASAP7_75t_R)
|
||||
49.30 101.95 ^ u1/Y (BUFx2_ASAP7_75t_R)
|
||||
61.03 162.97 ^ u2/Y (AND2x2_ASAP7_75t_R)
|
||||
15.77 178.74 ^ r3/D (DFFHQx4_ASAP7_75t_R)
|
||||
178.74 data arrival time
|
||||
|
||||
500.00 500.00 clock clk (rise edge)
|
||||
0.00 500.00 clock network delay (ideal)
|
||||
0.00 500.00 clock reconvergence pessimism
|
||||
500.00 ^ r3/CLK (DFFHQx4_ASAP7_75t_R)
|
||||
-13.66 486.34 library setup time
|
||||
486.34 data required time
|
||||
---------------------------------------------------------
|
||||
486.34 data required time
|
||||
-178.74 data arrival time
|
||||
---------------------------------------------------------
|
||||
307.59 slack (MET)
|
||||
|
||||
|
||||
Library: asap7sc7p5t_INVBUF_RVT_FF_nldm_211120
|
||||
Cell: BUFx2_ASAP7_75t_R
|
||||
Arc sense: positive_unate
|
||||
Arc type: combinational
|
||||
A ^ -> Y ^
|
||||
Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.50
|
||||
P = 1.00 V = 0.77 T = 0.00
|
||||
------- input_net_transition = 50.73
|
||||
| total_output_net_capacitance = 10.50
|
||||
| 5.76 11.52
|
||||
v --------------------
|
||||
40.00 | 27.29 35.12
|
||||
80.00 | 32.30 40.08
|
||||
Table value = 35.06
|
||||
PVT scale factor = 1.00
|
||||
Delay = 35.06
|
||||
|
||||
------- input_net_transition = 50.73
|
||||
| total_output_net_capacitance = 10.50
|
||||
| 5.76 11.52
|
||||
v --------------------
|
||||
40.00 | 20.70 37.28
|
||||
80.00 | 21.40 38.13
|
||||
Table value = 34.55
|
||||
PVT scale factor = 1.00
|
||||
Slew = 34.55
|
||||
Driver waveform slew = 47.36
|
||||
|
||||
.............................................
|
||||
|
||||
A v -> Y v
|
||||
Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.09
|
||||
P = 1.00 V = 0.77 T = 0.00
|
||||
------- input_net_transition = 48.72
|
||||
| total_output_net_capacitance = 10.09
|
||||
| 5.76 11.52
|
||||
v --------------------
|
||||
40.00 | 29.18 36.17
|
||||
80.00 | 36.09 43.28
|
||||
Table value = 35.97
|
||||
PVT scale factor = 1.00
|
||||
Delay = 35.97
|
||||
|
||||
------- input_net_transition = 48.72
|
||||
| total_output_net_capacitance = 10.09
|
||||
| 5.76 11.52
|
||||
v --------------------
|
||||
40.00 | 18.15 31.72
|
||||
80.00 | 19.36 32.63
|
||||
Table value = 28.57
|
||||
PVT scale factor = 1.00
|
||||
Slew = 28.57
|
||||
Driver waveform slew = 40.66
|
||||
|
||||
.............................................
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Prima report_dcalc with -name spef
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz
|
||||
read_liberty ../../test/asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz
|
||||
read_verilog ../../test/reg1_asap7.v
|
||||
link_design top
|
||||
|
||||
read_spef -name spef -reduce ../../test/reg1_asap7.spef
|
||||
create_clock -name clk -period 500 -waveform {0 250} {clk1 clk2 clk3}
|
||||
|
||||
set_delay_calculator prima
|
||||
read_spef -name spef ../../test/reg1_asap7.spef
|
||||
|
||||
# read_spef -name <spef> only parks the parasitics under <spef> in the
|
||||
# parasitics_name_map_; it does NOT bind them to any Scene (this is the
|
||||
# deferred-binding flow for MCMM -- see examples/mcmm3.tcl and Sta::readSpef
|
||||
# in search/Sta.cc). Without an explicit Scene binding, report_dcalc /
|
||||
# report_checks would see only pin capacitance (~0.57 fF here) and produce
|
||||
# incorrect table lookups, instead of the wire-cap-annotated ~13.97 fF we
|
||||
# expect for this design. define_scene with -spef spef creates a Scene
|
||||
# bound to the -name'd Parasitics via Scene::setParasitics and makes it the
|
||||
# current Scene, so Prima receives the full RC network.
|
||||
define_scene scene1 \
|
||||
-liberty {asap7sc7p5t_SEQ_RVT_FF_nldm_220123 \
|
||||
asap7sc7p5t_INVBUF_RVT_FF_nldm_211120 \
|
||||
asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120 \
|
||||
asap7sc7p5t_OA_RVT_FF_nldm_211120 \
|
||||
asap7sc7p5t_AO_RVT_FF_nldm_211120} \
|
||||
-spef spef
|
||||
|
||||
report_checks
|
||||
report_dcalc -from u1/A -to u1/Y
|
||||
|
|
@ -108,9 +108,6 @@ in a class derived from Sta. Because the components refer to each
|
|||
other, Sta::updateComponentsState() must be called to notify the
|
||||
components if any of them are changed after creation.
|
||||
|
||||
The file liberty/LibertyExt.cc contains an example that shows how the
|
||||
liberty reader is replaced with a custom one on the Sta object.
|
||||
|
||||
Units
|
||||
-----
|
||||
|
||||
|
|
@ -291,7 +288,7 @@ in this arc set:
|
|||
S r -> Z f
|
||||
|
||||
The liberty file reader can be customized to read attributes that are
|
||||
not used by the STA. See liberty/LibertyExt.cc for an example.
|
||||
not used by the STA.
|
||||
|
||||
Graph
|
||||
-----
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ elif [[ "$OSTYPE" == "darwin"* ]]; then
|
|||
numThreads=$(sysctl -n hw.ncpu)
|
||||
else
|
||||
cat << EOF
|
||||
WARNING: Unsupported OSTYPE: cannot determine number of host CPUs"
|
||||
Defaulting to 2 threads. Use -threads=N to use N threads"
|
||||
WARNING: Unsupported OSTYPE: cannot determine number of host CPUs
|
||||
Defaulting to 2 threads. Use -threads=N to use N threads
|
||||
EOF
|
||||
numThreads=2
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -26,16 +26,16 @@
|
|||
|
||||
#include "ContainerHelpers.hh"
|
||||
#include "Debug.hh"
|
||||
#include "Stats.hh"
|
||||
#include "FuncExpr.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Mutex.hh"
|
||||
#include "Transition.hh"
|
||||
#include "TimingRole.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Network.hh"
|
||||
#include "FuncExpr.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Stats.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TimingRole.hh"
|
||||
#include "Transition.hh"
|
||||
#include "Variables.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -49,8 +49,6 @@ namespace sta {
|
|||
Graph::Graph(StaState *sta,
|
||||
DcalcAPIndex ap_count) :
|
||||
StaState(sta),
|
||||
vertices_(nullptr),
|
||||
edges_(nullptr),
|
||||
ap_count_(ap_count),
|
||||
period_check_annotations_(network_),
|
||||
reg_clk_vertices_(makeVertexSet(this))
|
||||
|
|
@ -342,11 +340,10 @@ class MakeEdgesThruHierPin : public HierPinThruVisitor
|
|||
{
|
||||
public:
|
||||
MakeEdgesThruHierPin(Graph *graph);
|
||||
|
||||
private:
|
||||
void visit(const Pin *drvr,
|
||||
const Pin *load) override;
|
||||
|
||||
private:
|
||||
Graph *graph_;
|
||||
};
|
||||
|
||||
|
|
@ -585,7 +582,7 @@ Graph::slew(const Vertex *vertex,
|
|||
size_t slew_index = ap_index * RiseFall::index_count + rf->index();
|
||||
const float *slews_flt = vertex->slewsFloat();
|
||||
if (variables_->pocvEnabled()) {
|
||||
const Slew *slews = std::bit_cast<const Slew*>(slews_flt);
|
||||
const Slew *slews = reinterpret_cast<const Slew*>(slews_flt);
|
||||
return slews[slew_index];
|
||||
}
|
||||
else
|
||||
|
|
@ -598,7 +595,7 @@ Graph::slew(const Vertex *vertex,
|
|||
{
|
||||
const float *slews_flt = vertex->slewsFloat();
|
||||
if (variables_->pocvEnabled()) {
|
||||
const Slew *slews = std::bit_cast<const Slew*>(slews_flt);
|
||||
const Slew *slews = reinterpret_cast<const Slew*>(slews_flt);
|
||||
return slews[index];
|
||||
}
|
||||
else
|
||||
|
|
@ -678,7 +675,7 @@ Graph::arcDelay(const Edge *edge,
|
|||
{
|
||||
size_t index = arc->index() * ap_count_ + ap_index;
|
||||
if (variables_->pocvEnabled()) {
|
||||
ArcDelay *delays = std::bit_cast<ArcDelay*>(edge->arcDelays());
|
||||
const ArcDelay *delays = reinterpret_cast<const ArcDelay*>(edge->arcDelays());
|
||||
return delays[index];
|
||||
}
|
||||
else {
|
||||
|
|
@ -695,7 +692,7 @@ Graph::setArcDelay(Edge *edge,
|
|||
{
|
||||
size_t index = arc->index() * ap_count_ + ap_index;
|
||||
if (variables_->pocvEnabled()) {
|
||||
ArcDelay *delays = std::bit_cast<ArcDelay*>(edge->arcDelays());
|
||||
ArcDelay *delays = reinterpret_cast<ArcDelay*>(edge->arcDelays());
|
||||
delays[index] = delay;
|
||||
}
|
||||
else {
|
||||
|
|
@ -711,7 +708,7 @@ Graph::wireArcDelay(const Edge *edge,
|
|||
{
|
||||
size_t index = rf->index() * ap_count_ + ap_index;
|
||||
if (variables_->pocvEnabled()) {
|
||||
ArcDelay *delays = std::bit_cast<ArcDelay*>(edge->arcDelays());
|
||||
const ArcDelay *delays = reinterpret_cast<const ArcDelay*>(edge->arcDelays());
|
||||
return delays[index];
|
||||
}
|
||||
else {
|
||||
|
|
@ -728,7 +725,7 @@ Graph::setWireArcDelay(Edge *edge,
|
|||
{
|
||||
size_t index = rf->index() * ap_count_ + ap_index;
|
||||
if (variables_->pocvEnabled()) {
|
||||
ArcDelay *delays = std::bit_cast<ArcDelay*>(edge->arcDelays());
|
||||
ArcDelay *delays = reinterpret_cast<ArcDelay*>(edge->arcDelays());
|
||||
delays[index] = delay;
|
||||
}
|
||||
else {
|
||||
|
|
@ -753,7 +750,7 @@ Graph::setArcDelayAnnotated(Edge *edge,
|
|||
DcalcAPIndex ap_index,
|
||||
bool annotated)
|
||||
{
|
||||
return edge->setArcDelayAnnotated(arc, ap_index, ap_count_, annotated);
|
||||
edge->setArcDelayAnnotated(arc, ap_index, ap_count_, annotated);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -774,7 +771,7 @@ Graph::setWireDelayAnnotated(Edge *edge,
|
|||
{
|
||||
int arc_index = TimingArcSet::wireArcIndex(rf);
|
||||
TimingArc *arc = TimingArcSet::wireTimingArcSet()->findTimingArc(arc_index);
|
||||
return edge->setArcDelayAnnotated(arc, ap_index, ap_count_, annotated);
|
||||
edge->setArcDelayAnnotated(arc, ap_index, ap_count_, annotated);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -819,7 +816,7 @@ Graph::initSlews(Vertex *vertex)
|
|||
{
|
||||
size_t slew_count = slewCount();
|
||||
if (variables_->pocvEnabled()) {
|
||||
float *slews = std::bit_cast<float*>(new Slew[slew_count]{});
|
||||
float *slews = reinterpret_cast<float*>(new Slew[slew_count]{});
|
||||
vertex->setSlews(slews);
|
||||
}
|
||||
else {
|
||||
|
|
@ -840,7 +837,7 @@ Graph::initArcDelays(Edge *edge)
|
|||
size_t arc_count = edge->timingArcSet()->arcCount();
|
||||
size_t delay_count = arc_count * ap_count_;
|
||||
if (variables_->pocvEnabled()) {
|
||||
float *delays = std::bit_cast<float*>(new ArcDelay[delay_count]{});
|
||||
float *delays = reinterpret_cast<float*>(new ArcDelay[delay_count]{});
|
||||
edge->setArcDelays(delays);
|
||||
}
|
||||
else {
|
||||
|
|
@ -1187,7 +1184,7 @@ Vertex::setHasDownstreamClkPin(bool has_clk_pin)
|
|||
bool
|
||||
Vertex::bfsInQueue(BfsIndex index) const
|
||||
{
|
||||
return (bfs_in_queue_ >> unsigned(index)) & 1;
|
||||
return (bfs_in_queue_ >> static_cast<unsigned>(index)) & 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1195,9 +1192,9 @@ Vertex::setBfsInQueue(BfsIndex index,
|
|||
bool value)
|
||||
{
|
||||
if (value)
|
||||
bfs_in_queue_ |= 1 << int(index);
|
||||
bfs_in_queue_ |= 1 << static_cast<unsigned>(index);
|
||||
else
|
||||
bfs_in_queue_ &= ~(1 << int(index));
|
||||
bfs_in_queue_ &= ~(1 << static_cast<unsigned>(index));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1400,10 +1397,7 @@ VertexIterator::VertexIterator(Graph *graph) :
|
|||
graph_(graph),
|
||||
network_(graph->network()),
|
||||
top_inst_(network_->topInstance()),
|
||||
inst_iter_(network_->leafInstanceIterator()),
|
||||
pin_iter_(nullptr),
|
||||
vertex_(nullptr),
|
||||
bidir_vertex_(nullptr)
|
||||
inst_iter_(network_->leafInstanceIterator())
|
||||
{
|
||||
if (inst_iter_)
|
||||
findNext();
|
||||
|
|
@ -1580,4 +1574,4 @@ VertexIdLess::operator()(const Vertex *vertex1,
|
|||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -22,20 +22,18 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module graph
|
||||
|
||||
%{
|
||||
#include "Graph.hh"
|
||||
#include "Clock.hh"
|
||||
#include "FuncExpr.hh"
|
||||
#include "TimingRole.hh"
|
||||
#include "Graph.hh"
|
||||
#include "search/Levelize.hh"
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Clock.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Search.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "Sta.hh"
|
||||
#include "TimingRole.hh"
|
||||
|
||||
using namespace sta;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,12 +22,13 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include "GraphCmp.hh"
|
||||
|
||||
#include "ContainerHelpers.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Network.hh"
|
||||
#include "NetworkCmp.hh"
|
||||
#include "Graph.hh"
|
||||
#include "GraphCmp.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -73,4 +74,4 @@ sortEdges(EdgeSeq *edges,
|
|||
sort(edges, EdgeLess(network, graph));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ sta_module_tests("graph"
|
|||
delay_corners
|
||||
delete_modify
|
||||
incremental
|
||||
make_verify
|
||||
modify
|
||||
operations
|
||||
timing_edges
|
||||
|
|
|
|||
|
|
@ -1075,7 +1075,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 10.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
Clock *clk = sta_->cmdSdc()->findClock("clk");
|
||||
ASSERT_NE(clk, nullptr);
|
||||
|
|
@ -1455,7 +1455,7 @@ protected:
|
|||
FloatSeq *wave1 = new FloatSeq;
|
||||
wave1->push_back(0.0f);
|
||||
wave1->push_back(5.0f);
|
||||
sta_->makeClock("clk1", clk1_pins, false, 10.0f, wave1, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk1", *clk1_pins, false, 10.0f, *wave1, "", sta_->cmdMode());
|
||||
|
||||
// Create clock2
|
||||
Pin *clk2_pin = network->findPin(top, "clk2");
|
||||
|
|
@ -1465,7 +1465,7 @@ protected:
|
|||
FloatSeq *wave2 = new FloatSeq;
|
||||
wave2->push_back(0.0f);
|
||||
wave2->push_back(2.5f);
|
||||
sta_->makeClock("clk2", clk2_pins, false, 5.0f, wave2, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk2", *clk2_pins, false, 5.0f, *wave2, "", sta_->cmdMode());
|
||||
|
||||
// Input delays
|
||||
Clock *clk1 = sta_->cmdSdc()->findClock("clk1");
|
||||
|
|
@ -1664,7 +1664,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 10.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
Clock *clk = sta_->cmdSdc()->findClock("clk");
|
||||
ASSERT_NE(clk, nullptr);
|
||||
|
|
@ -1929,7 +1929,7 @@ protected:
|
|||
FloatSeq *waveform = new FloatSeq;
|
||||
waveform->push_back(0.0f);
|
||||
waveform->push_back(5.0f);
|
||||
sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode());
|
||||
sta_->makeClock("clk", *clk_pins, false, 10.0f, *waveform, "", sta_->cmdMode());
|
||||
|
||||
Clock *clk = sta_->cmdSdc()->findClock("clk");
|
||||
ASSERT_NE(clk, nullptr);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ No paths found.
|
|||
No paths found.
|
||||
No paths found.
|
||||
--- Test 3: report with fields ---
|
||||
Warning 168: graph_bidirect.tcl line 1, unknown field nets.
|
||||
Startpoint: d1 (input port clocked by clk)
|
||||
Endpoint: reg2 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
|
|
@ -80,12 +79,16 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 v input external delay
|
||||
1 0.88 0.10 0.00 0.00 v d1 (in)
|
||||
d1 (net)
|
||||
0.10 0.00 0.00 v buf1/A (BUF_X1)
|
||||
2 1.67 0.01 0.06 0.06 v buf1/Z (BUF_X1)
|
||||
n1 (net)
|
||||
0.01 0.00 0.06 v or1/A1 (OR2_X1)
|
||||
2 1.96 0.01 0.05 0.10 v or1/ZN (OR2_X1)
|
||||
n6 (net)
|
||||
0.01 0.00 0.10 v and2/A2 (AND2_X1)
|
||||
1 1.06 0.01 0.03 0.13 v and2/ZN (AND2_X1)
|
||||
n9 (net)
|
||||
0.01 0.00 0.13 v reg2/D (DFF_X1)
|
||||
0.13 data arrival time
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ report_checks -from [get_ports d3] -to [get_ports q4]
|
|||
# Test 3: Fields that exercise graph delay/slew queries
|
||||
#---------------------------------------------------------------
|
||||
puts "--- Test 3: report with fields ---"
|
||||
report_checks -fields {slew cap input_pins nets fanout}
|
||||
report_checks -fields {slew cap input_pins net fanout}
|
||||
|
||||
report_checks -format full_clock
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ Path Type: min
|
|||
1.03 slack (MET)
|
||||
|
||||
|
||||
Warning 168: graph_delete_modify.tcl line 1, unknown field nets.
|
||||
Startpoint: d2 (input port clocked by clk)
|
||||
Endpoint: reg2 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
|
|
@ -70,12 +69,16 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 0.00 clock network delay (ideal)
|
||||
1.00 1.00 v input external delay
|
||||
1 0.88 0.10 0.00 1.00 v d2 (in)
|
||||
d2 (net)
|
||||
0.10 0.00 1.00 v buf2/A (BUF_X1)
|
||||
2 1.69 0.01 0.06 1.06 v buf2/Z (BUF_X1)
|
||||
n2 (net)
|
||||
0.01 0.00 1.06 v or1/A1 (OR2_X1)
|
||||
2 2.56 0.01 0.05 1.11 v or1/ZN (OR2_X1)
|
||||
n6 (net)
|
||||
0.01 0.00 1.11 v nand1/A2 (NAND2_X1)
|
||||
1 1.14 0.01 0.02 1.12 ^ nand1/ZN (NAND2_X1)
|
||||
n7 (net)
|
||||
0.01 0.00 1.12 ^ reg2/D (DFF_X1)
|
||||
1.12 data arrival time
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ report_checks
|
|||
|
||||
report_checks -path_delay min
|
||||
|
||||
report_checks -fields {slew cap input_pins nets fanout}
|
||||
report_checks -fields {slew cap input_pins net fanout}
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Test 2: Add multiple instances and nets, then delete
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
No paths found.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
# Read liberty and design, make graph, verify
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
read_verilog graph_test1.v
|
||||
link_design graph_test1
|
||||
|
||||
# Creating the timing graph implicitly tests graph construction
|
||||
create_clock -name clk -period 10 [get_ports clk]
|
||||
|
||||
# report_checks exercises the graph
|
||||
report_checks -from [get_ports d] -to [get_ports q]
|
||||
|
|
@ -2551,7 +2551,6 @@ A2 -> ZN combinational
|
|||
^ -> ^ 0.02:0.02:0.09:0.09
|
||||
v -> v 0.02:0.02:0.16:0.16
|
||||
--- fields per corner ---
|
||||
Warning 168: graph_modify.tcl line 1, unknown field nets.
|
||||
Startpoint: d1 (input port clocked by clk1)
|
||||
Endpoint: q3 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
|
|
@ -2564,14 +2563,19 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 0.00 clock network delay (ideal)
|
||||
1.00 1.00 v input external delay
|
||||
1 0.91 0.10 0.00 1.00 v d1 (in)
|
||||
d1 (net)
|
||||
0.10 0.00 1.00 v buf1/A (BUF_X1)
|
||||
2 2.36 0.01 0.04 1.04 v buf1/Z (BUF_X1)
|
||||
n1 (net)
|
||||
0.01 0.00 1.04 v and1/A1 (AND2_X1)
|
||||
1 1.60 0.00 0.02 1.06 v and1/ZN (AND2_X1)
|
||||
n5 (net)
|
||||
0.00 0.00 1.06 v nand1/A1 (NAND2_X1)
|
||||
3 6.91 0.01 0.01 1.07 ^ nand1/ZN (NAND2_X1)
|
||||
n7 (net)
|
||||
0.01 0.00 1.07 ^ buf4/A (BUF_X4)
|
||||
1 0.00 0.00 0.01 1.09 ^ buf4/Z (BUF_X4)
|
||||
q3 (net)
|
||||
0.00 0.00 1.09 ^ q3 (out)
|
||||
1.09 data arrival time
|
||||
|
||||
|
|
@ -2599,6 +2603,7 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 0.00 10.00 ^ reg1/CK (DFF_X1)
|
||||
1 1.16 0.00 0.05 10.05 ^ reg1/Q (DFF_X1)
|
||||
n11 (net)
|
||||
0.00 0.00 10.05 ^ reg3/D (DFF_X1)
|
||||
10.05 data arrival time
|
||||
|
||||
|
|
@ -2615,7 +2620,6 @@ Fanout Cap Slew Delay Time Description
|
|||
4.93 slack (MET)
|
||||
|
||||
|
||||
Warning 168: graph_modify.tcl line 1, unknown field nets.
|
||||
Startpoint: d1 (input port clocked by clk1)
|
||||
Endpoint: q3 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
|
|
@ -2628,14 +2632,19 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 0.00 clock network delay (ideal)
|
||||
1.00 1.00 v input external delay
|
||||
1 0.84 0.10 0.00 1.00 v d1 (in)
|
||||
d1 (net)
|
||||
0.10 0.00 1.00 v buf1/A (BUF_X1)
|
||||
2 2.20 0.02 0.14 1.14 v buf1/Z (BUF_X1)
|
||||
n1 (net)
|
||||
0.02 0.00 1.14 v and1/A1 (AND2_X1)
|
||||
1 1.45 0.02 0.09 1.23 v and1/ZN (AND2_X1)
|
||||
n5 (net)
|
||||
0.02 0.00 1.23 v nand1/A1 (NAND2_X1)
|
||||
3 6.52 0.07 0.09 1.32 ^ nand1/ZN (NAND2_X1)
|
||||
n7 (net)
|
||||
0.07 0.00 1.32 ^ buf4/A (BUF_X4)
|
||||
1 0.00 0.01 0.07 1.38 ^ buf4/Z (BUF_X4)
|
||||
q3 (net)
|
||||
0.01 0.00 1.38 ^ q3 (out)
|
||||
1.38 data arrival time
|
||||
|
||||
|
|
@ -2663,6 +2672,7 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 0.00 10.00 ^ reg1/CK (DFF_X1)
|
||||
1 1.03 0.02 0.23 10.23 v reg1/Q (DFF_X1)
|
||||
n11 (net)
|
||||
0.02 0.00 10.23 v reg3/D (DFF_X1)
|
||||
10.23 data arrival time
|
||||
|
||||
|
|
|
|||
|
|
@ -228,9 +228,9 @@ report_edges -from [get_pins or2/A2] -to [get_pins or2/ZN]
|
|||
# report_checks with fields per corner
|
||||
#---------------------------------------------------------------
|
||||
puts "--- fields per corner ---"
|
||||
report_checks -corner fast -fields {slew cap input_pins nets fanout}
|
||||
report_checks -corner fast -fields {slew cap input_pins net fanout}
|
||||
|
||||
report_checks -corner slow -fields {slew cap input_pins nets fanout}
|
||||
report_checks -corner slow -fields {slew cap input_pins net fanout}
|
||||
|
||||
report_checks -corner fast -format full_clock
|
||||
|
||||
|
|
|
|||
|
|
@ -1784,7 +1784,6 @@ Path Type: max
|
|||
|
||||
|
||||
--- report_checks options ---
|
||||
Warning 168: graph_operations.tcl line 1, unknown field nets.
|
||||
Startpoint: d1 (input port clocked by clk1)
|
||||
Endpoint: q3 (output port clocked by clk1)
|
||||
Path Group: clk1
|
||||
|
|
@ -1796,14 +1795,19 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 0.00 clock network delay (ideal)
|
||||
1.00 1.00 v input external delay
|
||||
1 0.88 0.10 0.00 1.00 v d1 (in)
|
||||
d1 (net)
|
||||
0.10 0.00 1.00 v buf1/A (BUF_X1)
|
||||
2 2.29 0.01 0.06 1.06 v buf1/Z (BUF_X1)
|
||||
n1 (net)
|
||||
0.01 0.00 1.06 v and1/A1 (AND2_X1)
|
||||
1 1.53 0.01 0.03 1.09 v and1/ZN (AND2_X1)
|
||||
n5 (net)
|
||||
0.01 0.00 1.09 v nand1/A1 (NAND2_X1)
|
||||
3 6.80 0.02 0.03 1.11 ^ nand1/ZN (NAND2_X1)
|
||||
n7 (net)
|
||||
0.02 0.00 1.11 ^ buf4/A (BUF_X4)
|
||||
1 0.00 0.00 0.02 1.13 ^ buf4/Z (BUF_X4)
|
||||
q3 (net)
|
||||
0.00 0.00 1.13 ^ q3 (out)
|
||||
1.13 data arrival time
|
||||
|
||||
|
|
@ -1830,6 +1834,7 @@ Fanout Cap Slew Delay Time Description
|
|||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 0.00 10.00 ^ reg1/CK (DFF_X1)
|
||||
1 1.06 0.01 0.08 10.08 v reg1/Q (DFF_X1)
|
||||
n11 (net)
|
||||
0.01 0.00 10.08 v reg3/D (DFF_X1)
|
||||
10.08 data arrival time
|
||||
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ report_check_types -max_delay -min_delay -verbose
|
|||
# report_checks with various options
|
||||
#---------------------------------------------------------------
|
||||
puts "--- report_checks options ---"
|
||||
report_checks -fields {slew cap input_pins nets fanout}
|
||||
report_checks -fields {slew cap input_pins net fanout}
|
||||
|
||||
report_checks -format full_clock
|
||||
|
||||
|
|
|
|||
|
|
@ -24,20 +24,20 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "MinMax.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "Delay.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "ParasiticsClass.hh"
|
||||
#include "StaState.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "TimingArc.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -63,14 +63,14 @@ public:
|
|||
const Pin *drvr_pin,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
const Slew in_slew,
|
||||
Slew in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic);
|
||||
ArcDcalcArg(const Pin *in_pin,
|
||||
const Pin *drvr_pin,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
float in_delay);
|
||||
float input_delay);
|
||||
const Pin *inPin() const { return in_pin_; }
|
||||
const RiseFall *inEdge() const;
|
||||
const Pin *drvrPin() const { return drvr_pin_; }
|
||||
|
|
@ -160,7 +160,6 @@ class ArcDelayCalc : public StaState
|
|||
{
|
||||
public:
|
||||
ArcDelayCalc(StaState *sta);
|
||||
virtual ~ArcDelayCalc() {}
|
||||
virtual ArcDelayCalc *copy() = 0;
|
||||
virtual std::string_view name() const = 0;
|
||||
|
||||
|
|
@ -262,4 +261,4 @@ public:
|
|||
virtual void finishDrvrPin() = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#include "StaState.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "StaState.hh"
|
||||
|
||||
struct DdNode;
|
||||
struct DdManager;
|
||||
|
|
@ -41,7 +41,7 @@ class Bdd : public StaState
|
|||
{
|
||||
public:
|
||||
Bdd(const StaState *sta);
|
||||
~Bdd();
|
||||
~Bdd() override;
|
||||
DdNode *funcBdd(const FuncExpr *expr);
|
||||
DdNode *findNode(const LibertyPort *port);
|
||||
const LibertyPort *nodePort(DdNode *node);
|
||||
|
|
@ -58,4 +58,4 @@ private:
|
|||
BddVarIdxPortMap bdd_var_idx_port_map_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@
|
|||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "Iterator.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "VertexVisitor.hh"
|
||||
#include "Iterator.hh"
|
||||
#include "StaState.hh"
|
||||
#include "VertexVisitor.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -52,10 +52,10 @@ using LevelQueue = std::vector<VertexSeq>;
|
|||
// Vertices are marked as being in the queue by using a flag on
|
||||
// the vertex indexed by bfs_index. A unique flag is only needed
|
||||
// if the BFS in in use when other BFS's are simultaneously in use.
|
||||
class BfsIterator : public StaState, Iterator<Vertex*>
|
||||
class BfsIterator : public StaState,
|
||||
public Iterator<Vertex*>
|
||||
{
|
||||
public:
|
||||
virtual ~BfsIterator();
|
||||
// Make sure that the BFS queue is deep enough for the max logic level.
|
||||
void ensureSize();
|
||||
// Reset to virgin state.
|
||||
|
|
@ -157,7 +157,7 @@ public:
|
|||
BfsFwdIterator(BfsIndex bfs_index,
|
||||
SearchPred *search_pred,
|
||||
StaState *sta);
|
||||
virtual ~BfsFwdIterator();
|
||||
~BfsFwdIterator() override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
|
|
@ -182,7 +182,7 @@ public:
|
|||
BfsBkwdIterator(BfsIndex bfs_index,
|
||||
SearchPred *search_pred,
|
||||
StaState *sta);
|
||||
virtual ~BfsBkwdIterator();
|
||||
~BfsBkwdIterator() override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
|
|
@ -201,4 +201,4 @@ protected:
|
|||
const VertexFn &fn) override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
|
|||
|
|
@ -28,4 +28,4 @@ namespace sta {
|
|||
|
||||
enum class CircuitSim { hspice, ngspice, xyce };
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#include "StaState.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "StaState.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class ClkNetwork : public StaState
|
|||
public:
|
||||
ClkNetwork(Mode *mode,
|
||||
StaState *sta);
|
||||
~ClkNetwork();
|
||||
~ClkNetwork() override;
|
||||
void ensureClkNetwork();
|
||||
void clear();
|
||||
bool isClock(const Pin *pin) const;
|
||||
|
|
@ -73,9 +73,9 @@ private:
|
|||
|
||||
void findClkPins();
|
||||
void findClkPins(bool ideal_only,
|
||||
PinClksMap &clk_pin_map);
|
||||
PinClksMap &pin_clks_map);
|
||||
|
||||
bool clk_pins_valid_;
|
||||
bool clk_pins_valid_{false};
|
||||
// pin -> clks
|
||||
PinClksMap pin_clks_map_;
|
||||
// pin -> ideal clks
|
||||
|
|
@ -84,4 +84,4 @@ private:
|
|||
ClkPinsMap clk_pins_map_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "GraphClass.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "RiseFallMinMax.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "SdcCmdComment.hh"
|
||||
#include "GraphClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -57,8 +57,7 @@ public:
|
|||
const Pin *defaultPin() const;
|
||||
bool addToPins() const { return add_to_pins_; }
|
||||
void setAddToPins(bool add_to_pins);
|
||||
FloatSeq *waveform() { return waveform_; }
|
||||
const FloatSeq *waveform() const { return waveform_; }
|
||||
const FloatSeq &waveform() const { return waveform_; }
|
||||
ClockEdge *edge(const RiseFall *rf) const;
|
||||
int index() const { return index_; }
|
||||
bool isPropagated() const { return is_propagated_; }
|
||||
|
|
@ -82,11 +81,11 @@ public:
|
|||
void removeSlew();
|
||||
const RiseFallMinMax &slews() const { return slews_; }
|
||||
void setSlewLimit(const RiseFallBoth *rf,
|
||||
const PathClkOrData clk_data,
|
||||
PathClkOrData clk_data,
|
||||
const MinMax *min_max,
|
||||
float slew);
|
||||
void slewLimit(const RiseFall *rf,
|
||||
const PathClkOrData clk_data,
|
||||
PathClkOrData clk_data,
|
||||
const MinMax *min_max,
|
||||
// Return values.
|
||||
float &slew,
|
||||
|
|
@ -120,8 +119,8 @@ public:
|
|||
int multiplyBy() const { return multiply_by_; }
|
||||
float dutyCycle() const { return duty_cycle_; }
|
||||
bool invert() const { return invert_; }
|
||||
IntSeq *edges() const { return edges_; }
|
||||
FloatSeq *edgeShifts() const { return edge_shifts_; }
|
||||
const IntSeq &edges() const { return edges_; }
|
||||
const FloatSeq &edgeShifts() const { return edge_shifts_; }
|
||||
const RiseFall *masterClkEdgeTr(const RiseFall *rf) const;
|
||||
bool combinational() const { return combinational_; }
|
||||
bool isDivideByOneCombinational() const;
|
||||
|
|
@ -138,13 +137,13 @@ protected:
|
|||
Clock(std::string_view name,
|
||||
int index,
|
||||
const Network *network);
|
||||
void initClk(PinSet *pins,
|
||||
void initClk(const PinSet &pins,
|
||||
bool add_to_pins,
|
||||
float period,
|
||||
FloatSeq *waveform,
|
||||
const FloatSeq &waveform,
|
||||
std::string_view comment,
|
||||
const Network *network);
|
||||
void initGeneratedClk(PinSet *pins,
|
||||
void initGeneratedClk(const PinSet &pins,
|
||||
bool add_to_pins,
|
||||
Pin *src_pin,
|
||||
Clock *master_clk,
|
||||
|
|
@ -153,12 +152,12 @@ protected:
|
|||
float duty_cycle,
|
||||
bool invert,
|
||||
bool combinational,
|
||||
IntSeq *edges,
|
||||
FloatSeq *edge_shifts,
|
||||
const IntSeq &edges,
|
||||
const FloatSeq &edge_shifts,
|
||||
bool is_propagated,
|
||||
std::string_view comment,
|
||||
const Network *network);
|
||||
void setPins(PinSet *pins,
|
||||
void setPins(const PinSet &pins,
|
||||
const Network *network);
|
||||
void setMasterClk(Clock *master);
|
||||
void makeClkEdges();
|
||||
|
|
@ -170,31 +169,31 @@ protected:
|
|||
|
||||
std::string name_;
|
||||
PinSet pins_;
|
||||
bool add_to_pins_;
|
||||
bool add_to_pins_{false};
|
||||
// Hierarchical pins in pins_ become driver pins through the pin.
|
||||
PinSet leaf_pins_;
|
||||
float period_;
|
||||
FloatSeq *waveform_;
|
||||
bool waveform_valid_;
|
||||
float period_{0.0};
|
||||
FloatSeq waveform_;
|
||||
bool waveform_valid_{false};
|
||||
const int index_;
|
||||
ClockEdge **clk_edges_;
|
||||
bool is_propagated_;
|
||||
std::array<ClockEdge*, RiseFall::index_count> clk_edges_;
|
||||
bool is_propagated_{false};
|
||||
RiseFallMinMax slews_;
|
||||
RiseFallMinMax slew_limits_[path_clk_or_data_count];
|
||||
ClockUncertainties *uncertainties_;
|
||||
bool is_generated_;
|
||||
ClockUncertainties *uncertainties_{nullptr};
|
||||
bool is_generated_{false};
|
||||
// Generated clock variables.
|
||||
Pin *src_pin_;
|
||||
Clock *master_clk_;
|
||||
Pin *src_pin_{nullptr};
|
||||
Clock *master_clk_{nullptr};
|
||||
// True if the master clock is infered rather than specified by command.
|
||||
bool master_clk_infered_;
|
||||
int divide_by_;
|
||||
int multiply_by_;
|
||||
float duty_cycle_;
|
||||
bool invert_;
|
||||
bool combinational_;
|
||||
IntSeq *edges_;
|
||||
FloatSeq *edge_shifts_;
|
||||
bool master_clk_infered_{false};
|
||||
int divide_by_{0};
|
||||
int multiply_by_{0};
|
||||
float duty_cycle_{0};
|
||||
bool invert_{false};
|
||||
bool combinational_{false};
|
||||
IntSeq edges_;
|
||||
FloatSeq edge_shifts_;
|
||||
|
||||
private:
|
||||
friend class Sdc;
|
||||
|
|
@ -205,7 +204,6 @@ class ClockEdge
|
|||
{
|
||||
public:
|
||||
Clock *clock() const { return clock_; }
|
||||
~ClockEdge();
|
||||
const RiseFall *transition() const { return rf_; }
|
||||
float time() const { return time_; }
|
||||
const std::string &name() const { return name_; }
|
||||
|
|
@ -223,7 +221,7 @@ private:
|
|||
Clock *clock_;
|
||||
const RiseFall *rf_;
|
||||
std::string name_;
|
||||
float time_;
|
||||
float time_{0.0};
|
||||
int index_;
|
||||
};
|
||||
|
||||
|
|
@ -291,4 +289,4 @@ int
|
|||
compare(const ClockSet *set1,
|
||||
const ClockSet *set2);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,22 +24,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "SdcClass.hh"
|
||||
#include "RiseFallMinMax.hh"
|
||||
#include "SdcClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
class ClockGatingCheck
|
||||
{
|
||||
public:
|
||||
ClockGatingCheck();
|
||||
RiseFallMinMax *margins() { return &margins_; }
|
||||
void setActiveValue(LogicValue value);
|
||||
LogicValue activeValue() const { return active_value_; }
|
||||
|
||||
private:
|
||||
RiseFallMinMax margins_;
|
||||
LogicValue active_value_;
|
||||
LogicValue active_value_{LogicValue::unknown};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,20 +26,20 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "SdcCmdComment.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "SdcCmdComment.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
class ClockGroups : public SdcCmdComment
|
||||
{
|
||||
public:
|
||||
ClockGroups(const std::string &name,
|
||||
ClockGroups(std::string_view name,
|
||||
bool logically_exclusive,
|
||||
bool physically_exclusive,
|
||||
bool asynchronous,
|
||||
bool allow_paths,
|
||||
std::string comment);
|
||||
std::string_view comment);
|
||||
~ClockGroups();
|
||||
void makeClockGroup(ClockSet *clks);
|
||||
const std::string &name() const { return name_; }
|
||||
|
|
@ -59,4 +59,4 @@ private:
|
|||
ClockGroupSet groups_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
#include "MinMax.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "RiseFallMinMax.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "Transition.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -57,4 +57,4 @@ private:
|
|||
RiseFallMinMax delays_[EarlyLate::index_count];
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
|
||||
#include "MinMax.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "Transition.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "RiseFallMinMax.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "Transition.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -61,4 +61,4 @@ private:
|
|||
RiseFallMinMax delays_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "StringUtil.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
||||
// The classes defined in this file are a contrete implementation of
|
||||
// the library API. They can be used by a reader to construct classes
|
||||
|
|
@ -56,8 +56,8 @@ using ConcretePortMemberIterator = VectorIterator<ConcretePortSeq, ConcretePort*
|
|||
class ConcreteLibrary
|
||||
{
|
||||
public:
|
||||
ConcreteLibrary(std::string name,
|
||||
std::string filename,
|
||||
ConcreteLibrary(std::string_view name,
|
||||
std::string_view filename,
|
||||
bool is_liberty);
|
||||
virtual ~ConcreteLibrary();
|
||||
const std::string &name() const { return name_; }
|
||||
|
|
@ -84,8 +84,8 @@ protected:
|
|||
ObjectId id_;
|
||||
std::string filename_;
|
||||
bool is_liberty_;
|
||||
char bus_brkt_left_;
|
||||
char bus_brkt_right_;
|
||||
char bus_brkt_left_{'['};
|
||||
char bus_brkt_right_{']'};
|
||||
ConcreteCellMap cell_map_;
|
||||
|
||||
private:
|
||||
|
|
@ -127,12 +127,12 @@ public:
|
|||
ConcretePort *makeBundlePort(std::string_view name,
|
||||
ConcretePortSeq *members);
|
||||
// Group previously defined bus bit ports together.
|
||||
void groupBusPorts(const char bus_brkt_left,
|
||||
const char bus_brkt_right,
|
||||
std::function<bool(std::string_view)> port_msb_first);
|
||||
void groupBusPorts(char bus_brkt_left,
|
||||
char bus_brkt_right,
|
||||
const std::function<bool(std::string_view)> &port_msb_first);
|
||||
size_t portCount() const;
|
||||
void setName(std::string_view name);
|
||||
void addPort(ConcretePort *port);
|
||||
virtual void addPort(ConcretePort *port);
|
||||
void addPortBit(ConcretePort *port);
|
||||
|
||||
protected:
|
||||
|
|
@ -149,7 +149,7 @@ protected:
|
|||
int from_index,
|
||||
int to_index);
|
||||
// Bus port bit (internal to makeBusPortBits).
|
||||
ConcretePort *makePort(std::string bit_name,
|
||||
ConcretePort *makePort(std::string_view bit_name,
|
||||
int bit_index);
|
||||
void makeBusPortBit(ConcretePort *bus_port,
|
||||
std::string_view bus_name,
|
||||
|
|
@ -160,14 +160,14 @@ protected:
|
|||
// Filename is optional.
|
||||
std::string filename_;
|
||||
ConcreteLibrary *library_;
|
||||
LibertyCell *liberty_cell_;
|
||||
LibertyCell *liberty_cell_{nullptr};
|
||||
// External application cell.
|
||||
void *ext_cell_;
|
||||
void *ext_cell_{nullptr};
|
||||
// Non-bus and bus ports (but no expanded bus bit ports).
|
||||
ConcretePortSeq ports_;
|
||||
ConcretePortMap port_map_;
|
||||
// Port bit count (expanded buses).
|
||||
int port_bit_count_;
|
||||
int port_bit_count_{0};
|
||||
bool is_leaf_;
|
||||
AttributeMap attribute_map_;
|
||||
|
||||
|
|
@ -242,10 +242,10 @@ protected:
|
|||
ObjectId id_;
|
||||
ConcreteCell *cell_;
|
||||
PortDirection *direction_;
|
||||
LibertyPort *liberty_port_;
|
||||
LibertyPort *liberty_port_{nullptr};
|
||||
// External application port.
|
||||
void *ext_port_;
|
||||
int pin_index_;
|
||||
void *ext_port_{nullptr};
|
||||
int pin_index_{-1};
|
||||
bool is_bundle_;
|
||||
bool is_bus_;
|
||||
int from_index_;
|
||||
|
|
@ -253,7 +253,7 @@ protected:
|
|||
// Expanded bus bit ports (ordered by from_index_ to to_index_)
|
||||
// or bundle member ports.
|
||||
ConcretePortSeq *member_ports_;
|
||||
ConcretePort *bundle_port_;
|
||||
ConcretePort *bundle_port_{nullptr};
|
||||
|
||||
private:
|
||||
friend class ConcreteCell;
|
||||
|
|
@ -271,8 +271,8 @@ private:
|
|||
|
||||
const ConcretePortSeq &ports_;
|
||||
ConcretePortSeq::const_iterator port_iter_;
|
||||
ConcretePortMemberIterator *member_iter_;
|
||||
ConcretePort *next_;
|
||||
ConcretePortMemberIterator *member_iter_{nullptr};
|
||||
ConcretePort *next_{nullptr};
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "StringUtil.hh"
|
||||
#include "Network.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "Network.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ class ConcreteNetwork : public NetworkReader
|
|||
{
|
||||
public:
|
||||
ConcreteNetwork();
|
||||
~ConcreteNetwork();
|
||||
~ConcreteNetwork() override;
|
||||
void clear() override;
|
||||
bool linkNetwork(std::string_view top_cell_name,
|
||||
bool make_black_boxes,
|
||||
|
|
@ -263,6 +263,9 @@ public:
|
|||
using Network::isLeaf;
|
||||
|
||||
protected:
|
||||
void clearImpl();
|
||||
void deleteCellNetworkViewsImpl();
|
||||
void deleteInstanceImpl(Instance *inst);
|
||||
void addLibrary(ConcreteLibrary *library);
|
||||
void setName(std::string_view name);
|
||||
void clearConstantNets();
|
||||
|
|
@ -280,8 +283,8 @@ protected:
|
|||
// Cell lookup search order sequence.
|
||||
ConcreteLibrarySeq library_seq_;
|
||||
ConcreteLibraryMap library_map_;
|
||||
Instance *top_instance_;
|
||||
NetSet constant_nets_[2]; // LogicValue::zero/one
|
||||
Instance *top_instance_{nullptr};
|
||||
NetSet constant_nets_[2]{NetSet(this), NetSet(this)}; // LogicValue::zero/one
|
||||
LinkNetworkFunc link_func_;
|
||||
CellNetworkViewMap cell_network_view_map_;
|
||||
static ObjectId object_id_;
|
||||
|
|
@ -293,7 +296,7 @@ private:
|
|||
class ConcreteInstance
|
||||
{
|
||||
public:
|
||||
std::string_view name() const { return name_; }
|
||||
const std::string &name() const { return name_; }
|
||||
ObjectId id() const { return id_; }
|
||||
Cell *cell() const;
|
||||
ConcreteInstance *parent() const { return parent_; }
|
||||
|
|
@ -332,8 +335,8 @@ protected:
|
|||
ConcreteInstance *parent_;
|
||||
// Array of pins indexed by pin->port->index().
|
||||
ConcretePinSeq pins_;
|
||||
ConcreteInstanceChildMap *children_;
|
||||
ConcreteInstanceNetMap *nets_;
|
||||
ConcreteInstanceChildMap *children_{nullptr};
|
||||
ConcreteInstanceNetMap *nets_{nullptr};
|
||||
AttributeMap attribute_map_;
|
||||
|
||||
private:
|
||||
|
|
@ -344,7 +347,7 @@ private:
|
|||
class ConcretePin
|
||||
{
|
||||
public:
|
||||
std::string_view name() const;
|
||||
const std::string &name() const;
|
||||
ConcreteInstance *instance() const { return instance_; }
|
||||
ConcreteNet *net() const { return net_; }
|
||||
ConcretePort *port() const { return port_; }
|
||||
|
|
@ -354,7 +357,7 @@ public:
|
|||
void setVertexId(VertexId id);
|
||||
|
||||
protected:
|
||||
~ConcretePin() {}
|
||||
~ConcretePin() = default;
|
||||
ConcretePin(ConcreteInstance *instance,
|
||||
ConcretePort *port,
|
||||
ConcreteNet *net);
|
||||
|
|
@ -362,12 +365,12 @@ protected:
|
|||
ConcreteInstance *instance_;
|
||||
ConcretePort *port_;
|
||||
ConcreteNet *net_;
|
||||
ConcreteTerm *term_;
|
||||
ConcreteTerm *term_{nullptr};
|
||||
ObjectId id_;
|
||||
// Doubly linked list of net pins.
|
||||
ConcretePin *net_next_;
|
||||
ConcretePin *net_prev_;
|
||||
VertexId vertex_id_;
|
||||
ConcretePin *net_next_{nullptr};
|
||||
ConcretePin *net_prev_{nullptr};
|
||||
VertexId vertex_id_{vertex_id_null};
|
||||
|
||||
private:
|
||||
friend class ConcreteNetwork;
|
||||
|
|
@ -378,13 +381,13 @@ private:
|
|||
class ConcreteTerm
|
||||
{
|
||||
public:
|
||||
std::string_view name() const;
|
||||
const std::string &name() const;
|
||||
ObjectId id() const { return id_; }
|
||||
ConcreteNet *net() const { return net_; }
|
||||
ConcretePin *pin() const { return pin_; }
|
||||
|
||||
protected:
|
||||
~ConcreteTerm() {}
|
||||
~ConcreteTerm() = default;
|
||||
ConcreteTerm(ConcretePin *pin,
|
||||
ConcreteNet *net);
|
||||
|
||||
|
|
@ -392,7 +395,7 @@ protected:
|
|||
ConcreteNet *net_;
|
||||
ObjectId id_;
|
||||
// Linked list of net terms.
|
||||
ConcreteTerm *net_next_;
|
||||
ConcreteTerm *net_next_{nullptr};
|
||||
|
||||
private:
|
||||
friend class ConcreteNetwork;
|
||||
|
|
@ -403,7 +406,7 @@ private:
|
|||
class ConcreteNet
|
||||
{
|
||||
public:
|
||||
std::string_view name() const { return name_; }
|
||||
const std::string &name() const { return name_; }
|
||||
ObjectId id() const { return id_; }
|
||||
ConcreteInstance *instance() const { return instance_; }
|
||||
void addPin(ConcretePin *pin);
|
||||
|
|
@ -420,16 +423,16 @@ protected:
|
|||
ObjectId id_;
|
||||
ConcreteInstance *instance_;
|
||||
// Pointer to head of linked list of pins.
|
||||
ConcretePin *pins_;
|
||||
ConcretePin *pins_{nullptr};
|
||||
// Pointer to head of linked list of terminals.
|
||||
// These terminals correspond to the pins attached to the instance that
|
||||
// contains this net in the hierarchy level above.
|
||||
ConcreteTerm *terms_;
|
||||
ConcreteNet *merged_into_;
|
||||
ConcreteTerm *terms_{nullptr};
|
||||
ConcreteNet *merged_into_{nullptr};
|
||||
|
||||
friend class ConcreteNetwork;
|
||||
friend class ConcreteNetTermIterator;
|
||||
friend class ConcreteNetPinIterator;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,14 +24,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <ranges>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility> // for std::declval
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include <functional>
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -41,7 +42,8 @@ namespace sta {
|
|||
// 1. Sequence containers (vector<T*>, list<T*>, deque<T*>, …)
|
||||
// ------------------------------------------------------------
|
||||
template <typename Container>
|
||||
std::enable_if_t<std::is_pointer_v<typename Container::value_type>>
|
||||
requires std::is_pointer_v<typename Container::value_type>
|
||||
void
|
||||
deleteContents(Container& c)
|
||||
{
|
||||
for (auto ptr : c)
|
||||
|
|
@ -50,7 +52,8 @@ deleteContents(Container& c)
|
|||
}
|
||||
|
||||
template <typename Container>
|
||||
std::enable_if_t<std::is_pointer_v<typename Container::value_type>>
|
||||
requires std::is_pointer_v<typename Container::value_type>
|
||||
void
|
||||
deleteContents(Container *c)
|
||||
{
|
||||
for (auto ptr : *c)
|
||||
|
|
@ -62,8 +65,8 @@ deleteContents(Container *c)
|
|||
// 2. Maps (map<K, T*>, unordered_map<K, T*>)
|
||||
// ------------------------------------------------------------
|
||||
template <typename Map>
|
||||
std::enable_if_t<std::is_pointer_v<typename Map::mapped_type>
|
||||
>
|
||||
requires std::is_pointer_v<typename Map::mapped_type>
|
||||
void
|
||||
deleteContents(Map& m)
|
||||
{
|
||||
for (auto& kv : m)
|
||||
|
|
@ -72,8 +75,8 @@ deleteContents(Map& m)
|
|||
}
|
||||
|
||||
template <typename Map>
|
||||
std::enable_if_t<std::is_pointer_v<typename Map::mapped_type>
|
||||
>
|
||||
requires std::is_pointer_v<typename Map::mapped_type>
|
||||
void
|
||||
deleteContents(Map *m)
|
||||
{
|
||||
for (auto& kv : *m)
|
||||
|
|
@ -85,10 +88,10 @@ deleteContents(Map *m)
|
|||
// 3. Sets (set<T*>, unordered_set<T*>)
|
||||
// ------------------------------------------------------------
|
||||
template <typename Set>
|
||||
std::enable_if_t<
|
||||
std::is_pointer_v<typename Set::value_type> &&
|
||||
!std::is_same_v<typename Set::value_type, typename Set::mapped_type>
|
||||
>
|
||||
requires (std::is_pointer_v<typename Set::value_type> &&
|
||||
requires { typename Set::mapped_type; } &&
|
||||
!std::is_same_v<typename Set::value_type, typename Set::mapped_type>)
|
||||
void
|
||||
deleteContents(Set& s)
|
||||
{
|
||||
for (auto ptr : s)
|
||||
|
|
@ -118,28 +121,28 @@ struct find_return;
|
|||
template<typename C>
|
||||
struct find_return<C*, true>
|
||||
{
|
||||
using type = typename C::mapped_type;
|
||||
using type = C::mapped_type;
|
||||
};
|
||||
|
||||
// pointer to set
|
||||
template<typename C>
|
||||
struct find_return<C*, false>
|
||||
{
|
||||
using type = typename C::key_type;
|
||||
using type = C::key_type;
|
||||
};
|
||||
|
||||
// map ref
|
||||
template<typename C>
|
||||
struct find_return<C, true>
|
||||
{
|
||||
using type = typename C::mapped_type;
|
||||
using type = C::mapped_type;
|
||||
};
|
||||
|
||||
// set ref
|
||||
template<typename C>
|
||||
struct find_return<C, false>
|
||||
{
|
||||
using type = typename C::key_type;
|
||||
using type = C::key_type;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -148,10 +151,10 @@ struct find_return<C, false>
|
|||
template<typename AssocContainer>
|
||||
auto
|
||||
findKey(const AssocContainer& c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> typename find_return<AssocContainer>::type
|
||||
const typename AssocContainer::key_type& key)
|
||||
-> find_return<AssocContainer>::type
|
||||
{
|
||||
using ReturnType = typename find_return<AssocContainer>::type;
|
||||
using ReturnType = find_return<AssocContainer>::type;
|
||||
|
||||
static_assert(std::is_pointer_v<ReturnType>,
|
||||
"findKey requires pointer types");
|
||||
|
|
@ -172,9 +175,9 @@ template<typename AssocContainer>
|
|||
auto
|
||||
findStringKey(const AssocContainer& c,
|
||||
std::string_view key)
|
||||
-> typename find_return<AssocContainer>::type
|
||||
-> find_return<AssocContainer>::type
|
||||
{
|
||||
using ReturnType = typename find_return<AssocContainer>::type;
|
||||
using ReturnType = find_return<AssocContainer>::type;
|
||||
|
||||
static_assert(std::is_pointer_v<ReturnType>,
|
||||
"findStringKey requires pointer types");
|
||||
|
|
@ -193,8 +196,8 @@ findStringKey(const AssocContainer& c,
|
|||
template<typename AssocContainer>
|
||||
auto
|
||||
findKeyValue(const AssocContainer& c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> const typename find_return<AssocContainer>::type &
|
||||
const typename AssocContainer::key_type& key)
|
||||
-> const find_return<AssocContainer>::type &
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it != c.end()) {
|
||||
|
|
@ -212,7 +215,7 @@ findKeyValue(const AssocContainer& c,
|
|||
template<typename AssocContainer>
|
||||
void
|
||||
findKeyValue(const AssocContainer& c,
|
||||
typename AssocContainer::key_type key,
|
||||
const typename AssocContainer::key_type& key,
|
||||
typename find_return<AssocContainer>::type &value,
|
||||
bool &exists)
|
||||
{
|
||||
|
|
@ -239,7 +242,7 @@ findKeyValue(const AssocContainer& c,
|
|||
template<typename AssocContainer>
|
||||
void
|
||||
findKeyValue(const AssocContainer *c,
|
||||
typename AssocContainer::key_type key,
|
||||
const typename AssocContainer::key_type& key,
|
||||
typename find_return<AssocContainer>::type &value,
|
||||
bool &exists)
|
||||
{
|
||||
|
|
@ -268,8 +271,8 @@ findKeyValue(const AssocContainer *c,
|
|||
template<typename AssocContainer>
|
||||
auto
|
||||
findKeyValuePtr(AssocContainer& c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> typename find_return<AssocContainer>::type*
|
||||
const typename AssocContainer::key_type& key)
|
||||
-> find_return<AssocContainer>::type*
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it == c.end())
|
||||
|
|
@ -288,8 +291,8 @@ findKeyValuePtr(AssocContainer& c,
|
|||
template<typename AssocContainer>
|
||||
auto
|
||||
findKeyValuePtr(const AssocContainer& c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> typename find_return<AssocContainer>::type const*
|
||||
const typename AssocContainer::key_type& key)
|
||||
-> find_return<AssocContainer>::type const*
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it == c.end())
|
||||
|
|
@ -309,8 +312,8 @@ findKeyValuePtr(const AssocContainer& c,
|
|||
template<typename AssocContainer>
|
||||
auto
|
||||
findStringValuePtr(AssocContainer& c,
|
||||
std::string_view key)
|
||||
-> typename find_return<AssocContainer>::type*
|
||||
std::string_view key)
|
||||
-> find_return<AssocContainer>::type*
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it == c.end())
|
||||
|
|
@ -325,8 +328,8 @@ findStringValuePtr(AssocContainer& c,
|
|||
template<typename AssocContainer>
|
||||
auto
|
||||
findStringValuePtr(const AssocContainer& c,
|
||||
std::string_view key)
|
||||
-> typename find_return<AssocContainer>::type const*
|
||||
std::string_view key)
|
||||
-> find_return<AssocContainer>::type const*
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it == c.end())
|
||||
|
|
@ -434,7 +437,7 @@ requires std::predicate<Comp&,
|
|||
std::ranges::range_reference_t<Range>>
|
||||
void
|
||||
sort(Range& r,
|
||||
Comp comp = Comp{})
|
||||
const Comp &comp = Comp{})
|
||||
{
|
||||
std::stable_sort(std::ranges::begin(r), std::ranges::end(r), comp);
|
||||
}
|
||||
|
|
@ -449,9 +452,9 @@ requires std::ranges::random_access_range<Range> &&
|
|||
std::ranges::range_reference_t<Range>>
|
||||
void
|
||||
sort(Range* r,
|
||||
Comp comp = Comp{})
|
||||
const Comp &comp = Comp{})
|
||||
{
|
||||
std::stable_sort(std::ranges::begin(*r), std::ranges::end(*r), comp);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
#include <unordered_set>
|
||||
|
||||
#include "MinMax.hh"
|
||||
#include "TimingRole.hh"
|
||||
#include "StaState.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "StaState.hh"
|
||||
#include "TimingRole.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ private:
|
|||
int src_cycle_[TimingRole::index_max + 1];
|
||||
// Target clock cycle offset.
|
||||
int tgt_cycle_[TimingRole::index_max + 1];
|
||||
bool max_cycles_exceeded_;
|
||||
bool max_cycles_exceeded_{false};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "MinMax.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "NetworkCmp.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "RiseFallMinMax.hh"
|
||||
#include "SdcClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -79,4 +79,4 @@ private:
|
|||
const Network *network_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "Format.hh"
|
||||
#include "Report.hh"
|
||||
|
|
@ -64,9 +64,9 @@ public:
|
|||
protected:
|
||||
Report *report_;
|
||||
std::mutex buffer_lock_;
|
||||
bool debug_on_;
|
||||
bool debug_on_{false};
|
||||
DebugMap debug_map_;
|
||||
int stats_level_;
|
||||
int stats_level_{0};
|
||||
};
|
||||
|
||||
// Inlining a varargs function would eval the args, which can
|
||||
|
|
@ -76,4 +76,4 @@ protected:
|
|||
debug->report(what, fmt __VA_OPT__(,) __VA_ARGS__); \
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "StaConfig.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "StaConfig.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -37,16 +37,16 @@ class StaState;
|
|||
class Delay
|
||||
{
|
||||
public:
|
||||
Delay();
|
||||
Delay(float mean);
|
||||
Delay() noexcept;
|
||||
Delay(float mean) noexcept;
|
||||
Delay(float mean,
|
||||
// std_dev^2
|
||||
float std_dev2);
|
||||
float std_dev2) noexcept;
|
||||
Delay(float mean,
|
||||
float mean_shift,
|
||||
// std_dev^2
|
||||
float std_dev2,
|
||||
float skewness);
|
||||
float skewness) noexcept;
|
||||
void setValues(float mean,
|
||||
float mean_shift,
|
||||
float std_dev2,
|
||||
|
|
@ -62,7 +62,7 @@ public:
|
|||
float skewness() const { return values_[3]; }
|
||||
void setSkewness(float skewness);
|
||||
|
||||
void operator=(float delay);
|
||||
Delay &operator=(float delay);
|
||||
// This allows applications that do not support statistical timing
|
||||
// to treat Delays as floats without explicitly converting with
|
||||
// delayAsFloat.
|
||||
|
|
@ -77,8 +77,8 @@ private:
|
|||
class DelayDbl
|
||||
{
|
||||
public:
|
||||
DelayDbl();
|
||||
DelayDbl(double value);
|
||||
DelayDbl() noexcept;
|
||||
DelayDbl(double mean) noexcept;
|
||||
double mean() const { return values_[0]; }
|
||||
void setMean(double mean);
|
||||
double meanShift() const { return values_[1]; }
|
||||
|
|
@ -91,7 +91,7 @@ public:
|
|||
double std_dev2,
|
||||
double skewnes);
|
||||
|
||||
void operator=(double delay);
|
||||
DelayDbl &operator=(double delay);
|
||||
|
||||
private:
|
||||
std::array<double, 4> values_;
|
||||
|
|
@ -108,7 +108,7 @@ const Delay delay_zero(0.0);
|
|||
class DelayOps
|
||||
{
|
||||
public:
|
||||
virtual ~DelayOps() {}
|
||||
virtual ~DelayOps() = default;
|
||||
virtual float stdDev2(const Delay &delay,
|
||||
const EarlyLate *early_late) const = 0;
|
||||
virtual float asFloat(const Delay &delay,
|
||||
|
|
@ -356,4 +356,4 @@ Delay
|
|||
delayRemove(const Delay &delay1,
|
||||
const Delay &delay2);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -55,4 +55,4 @@ ArcDelayCalc *
|
|||
makeDelayCalc(std::string_view name,
|
||||
StaState *sta);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -87,4 +87,4 @@ public:
|
|||
const StaState *sta) const override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -87,4 +87,4 @@ public:
|
|||
const StaState *sta) const override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -95,4 +95,4 @@ private:
|
|||
double skewness2) const;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "MinMax.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "RiseFallMinMax.hh"
|
||||
#include "SdcClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -111,10 +111,4 @@ private:
|
|||
DeratingFactors factors_[timing_derate_cell_type_count];
|
||||
};
|
||||
|
||||
class DeratingFactorsNet : public DeratingFactors
|
||||
{
|
||||
public:
|
||||
DeratingFactorsNet();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "NetworkClass.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -46,7 +46,6 @@ using TimingArcSetSet = std::set<TimingArcSet*, TimingArcSetLess>;
|
|||
class DisabledPorts
|
||||
{
|
||||
public:
|
||||
DisabledPorts();
|
||||
~DisabledPorts();
|
||||
void setDisabledAll();
|
||||
void removeDisabledAll();
|
||||
|
|
@ -67,10 +66,10 @@ public:
|
|||
[[nodiscard]] bool all() const { return all_; }
|
||||
|
||||
private:
|
||||
bool all_;
|
||||
LibertyPortSet *from_;
|
||||
LibertyPortSet *to_;
|
||||
LibertyPortPairSet *from_to_;
|
||||
bool all_{false};
|
||||
LibertyPortSet *from_{nullptr};
|
||||
LibertyPortSet *to_{nullptr};
|
||||
LibertyPortPairSet *from_to_{nullptr};
|
||||
};
|
||||
|
||||
// set_disable_timing cell [-from] [-to]
|
||||
|
|
@ -89,7 +88,7 @@ public:
|
|||
|
||||
private:
|
||||
LibertyCell *cell_;
|
||||
TimingArcSetSet *arc_sets_;
|
||||
TimingArcSetSet *arc_sets_{nullptr};
|
||||
};
|
||||
|
||||
// set_disable_timing instance [-from] [-to]
|
||||
|
|
@ -111,4 +110,4 @@ sortByPathName(const DisabledInstancePortsMap *inst_map,
|
|||
LibertyPortPairSeq
|
||||
sortByName(const LibertyPortPairSet *set);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -5,23 +5,23 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace sta {
|
||||
|
||||
class DispatchQueue
|
||||
{
|
||||
typedef std::function<void(int thread)> fp_t;
|
||||
using fp_t = std::function<void(int thread)>;
|
||||
|
||||
public:
|
||||
DispatchQueue(size_t thread_cnt);
|
||||
DispatchQueue(size_t thread_count);
|
||||
~DispatchQueue();
|
||||
void setThreadCount(size_t thread_count);
|
||||
size_t getThreadCount() const;
|
||||
|
|
@ -49,4 +49,4 @@ private:
|
|||
bool quit_ = false;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ template <class ENUM>
|
|||
class EnumNameMap
|
||||
{
|
||||
public:
|
||||
EnumNameMap(std::initializer_list<std::pair<const ENUM, std::string>> enum_names);
|
||||
EnumNameMap(std::initializer_list<std::pair<const ENUM,
|
||||
std::string>> enum_names) noexcept;
|
||||
const std::string &find(ENUM key) const;
|
||||
ENUM find(std::string_view name,
|
||||
ENUM unknown_key) const;
|
||||
|
|
@ -49,7 +50,7 @@ private:
|
|||
};
|
||||
|
||||
template <class ENUM>
|
||||
EnumNameMap<ENUM>::EnumNameMap(std::initializer_list<std::pair<const ENUM,std::string>> enum_names) :
|
||||
EnumNameMap<ENUM>::EnumNameMap(std::initializer_list<std::pair<const ENUM,std::string>> enum_names) noexcept :
|
||||
enum_map_(enum_names)
|
||||
{
|
||||
for (const auto& [key, name] : enum_map_)
|
||||
|
|
@ -97,4 +98,4 @@ EnumNameMap<ENUM>::find(std::string_view name,
|
|||
return unknown_key;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -87,4 +87,4 @@ bool
|
|||
equivCellSequentials(const LibertyCell *cell1,
|
||||
const LibertyCell *cell2);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ namespace sta {
|
|||
class Exception : public std::exception
|
||||
{
|
||||
public:
|
||||
Exception();
|
||||
virtual ~Exception() {}
|
||||
const char *what() const noexcept override = 0;
|
||||
};
|
||||
|
||||
|
|
@ -44,7 +42,7 @@ class ExceptionMsg : public Exception
|
|||
{
|
||||
public:
|
||||
ExceptionMsg(const std::string &msg,
|
||||
const bool suppressed);
|
||||
bool suppressed);
|
||||
const char *what() const noexcept override;
|
||||
bool suppressed() const { return suppressed_; }
|
||||
|
||||
|
|
@ -93,4 +91,4 @@ protected:
|
|||
#define criticalError(id, msg) \
|
||||
Report::defaultReport()->fileCritical(id, __FILE__, __LINE__, msg)
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@
|
|||
#include <vector>
|
||||
|
||||
#include "Error.hh"
|
||||
#include "SdcCmdComment.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "SdcCmdComment.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -70,6 +70,7 @@ public:
|
|||
virtual bool isFilter() const { return false; }
|
||||
virtual ExceptionPathType type() const = 0;
|
||||
virtual std::string to_string(const Network *network) const;
|
||||
virtual std::string_view typeString() const = 0;
|
||||
ExceptionFrom *from() const { return from_; }
|
||||
ExceptionThruSeq *thrus() const { return thrus_; }
|
||||
ExceptionTo *to() const { return to_; }
|
||||
|
|
@ -135,7 +136,6 @@ public:
|
|||
virtual bool breakPath() const { return false; }
|
||||
|
||||
protected:
|
||||
virtual const char *typeString() const = 0;
|
||||
std::string fromThruToString(const Network *network) const;
|
||||
void makeStates();
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ protected:
|
|||
const MinMaxAll *min_max_;
|
||||
bool own_pts_;
|
||||
int priority_;
|
||||
size_t id_; // Unique ID assigned by Sdc.
|
||||
size_t id_{0}; // Unique ID assigned by Sdc.
|
||||
ExceptionState *states_;
|
||||
};
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ public:
|
|||
bool own_pts) override;
|
||||
bool isFalse() const override { return true; }
|
||||
ExceptionPathType type() const override { return ExceptionPathType::false_path; }
|
||||
const char *typeString() const override;
|
||||
std::string_view typeString() const override;
|
||||
bool mergeable(ExceptionPath *exception) const override;
|
||||
bool overrides(ExceptionPath *exception) const override;
|
||||
int typePriority() const override;
|
||||
|
|
@ -188,7 +188,7 @@ public:
|
|||
bool own_pts);
|
||||
bool isLoop() const override { return true; }
|
||||
ExceptionPathType type() const override { return ExceptionPathType::loop; }
|
||||
const char *typeString() const override;
|
||||
std::string_view typeString() const override;
|
||||
bool mergeable(ExceptionPath *exception) const override;
|
||||
};
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ public:
|
|||
bool isPathDelay() const override { return true; }
|
||||
ExceptionPathType type() const override { return ExceptionPathType::path_delay; }
|
||||
std::string to_string(const Network *network) const override;
|
||||
const char *typeString() const override;
|
||||
std::string_view typeString() const override;
|
||||
bool mergeable(ExceptionPath *exception) const override;
|
||||
bool overrides(ExceptionPath *exception) const override;
|
||||
float delay() const override { return delay_; }
|
||||
|
|
@ -248,7 +248,7 @@ public:
|
|||
bool matches(const MinMax *min_max,
|
||||
bool exactly) const override;
|
||||
std::string to_string(const Network *network) const override;
|
||||
const char *typeString() const override;
|
||||
std::string_view typeString() const override;
|
||||
bool mergeable(ExceptionPath *exception) const override;
|
||||
bool overrides(ExceptionPath *exception) const override;
|
||||
bool useEndClk() const override { return use_end_clk_; }
|
||||
|
|
@ -279,7 +279,7 @@ public:
|
|||
bool own_pts) override;
|
||||
bool isFilter() const override { return true; }
|
||||
ExceptionPathType type() const override { return ExceptionPathType::filter; }
|
||||
const char *typeString() const override;
|
||||
std::string_view typeString() const override;
|
||||
bool mergeable(ExceptionPath *exception) const override;
|
||||
bool overrides(ExceptionPath *exception) const override;
|
||||
bool resetMatch(ExceptionFrom *from,
|
||||
|
|
@ -301,14 +301,13 @@ public:
|
|||
ExceptionTo *to,
|
||||
bool own_pts,
|
||||
std::string_view comment);
|
||||
~GroupPath() override;
|
||||
ExceptionPath *clone(ExceptionFrom *from,
|
||||
ExceptionThruSeq *thrus,
|
||||
ExceptionTo *to,
|
||||
bool own_pts) override;
|
||||
bool isGroupPath() const override { return true; }
|
||||
ExceptionPathType type() const override { return ExceptionPathType::group_path; }
|
||||
const char *typeString() const override;
|
||||
std::string_view typeString() const override;
|
||||
bool mergeable(ExceptionPath *exception) const override;
|
||||
bool overrides(ExceptionPath *exception) const override;
|
||||
int typePriority() const override;
|
||||
|
|
@ -327,7 +326,7 @@ class ExceptionPt
|
|||
public:
|
||||
ExceptionPt(const RiseFallBoth *rf,
|
||||
bool own_pts);
|
||||
virtual ~ExceptionPt() {};
|
||||
virtual ~ExceptionPt() = default;
|
||||
virtual bool isFrom() const { return false; }
|
||||
virtual bool isThru() const { return false; }
|
||||
virtual bool isTo() const { return false; }
|
||||
|
|
@ -367,7 +366,7 @@ protected:
|
|||
bool own_pts_;
|
||||
// Hash is cached because there may be many objects to speed up
|
||||
// exception merging.
|
||||
size_t hash_;
|
||||
size_t hash_{0};
|
||||
|
||||
// Maximum number of objects for to_string() to show.
|
||||
static const int to_string_max_objects_;
|
||||
|
|
@ -386,7 +385,7 @@ public:
|
|||
const RiseFallBoth *rf,
|
||||
bool own_pts,
|
||||
const Network *network);
|
||||
~ExceptionFromTo();
|
||||
~ExceptionFromTo() override;
|
||||
PinSet *pins() override { return pins_; }
|
||||
bool hasPins() const;
|
||||
ClockSet *clks() override { return clks_; }
|
||||
|
|
@ -512,7 +511,7 @@ public:
|
|||
const RiseFallBoth *rf,
|
||||
bool own_pts,
|
||||
const Network *network);
|
||||
~ExceptionThru();
|
||||
~ExceptionThru() override;
|
||||
ExceptionThru *clone(const Network *network);
|
||||
std::string to_string(const Network *network) const override;
|
||||
bool isThru() const override { return true; }
|
||||
|
|
@ -538,15 +537,6 @@ public:
|
|||
const Network *network) const;
|
||||
int typePriority() const override { return 2; }
|
||||
size_t objectCount() const override;
|
||||
void connectPinAfter(PinSet *drvrs,
|
||||
Network *network) override;
|
||||
void deletePinBefore(const Pin *pin,
|
||||
Network *network) override;
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
|
||||
protected:
|
||||
void findHash(const Network *network);
|
||||
void addPin(const Pin *pin,
|
||||
const Network *network) override;
|
||||
void addEdge(const EdgePins &edge,
|
||||
|
|
@ -556,6 +546,15 @@ protected:
|
|||
void addInstance(const Instance *inst,
|
||||
const Network *network) override;
|
||||
void addClock(Clock *) override {}
|
||||
void connectPinAfter(PinSet *drvrs,
|
||||
Network *network) override;
|
||||
void deletePinBefore(const Pin *pin,
|
||||
Network *network) override;
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
|
||||
protected:
|
||||
void findHash(const Network *network);
|
||||
void deletePin(const Pin *pin,
|
||||
const Network *network);
|
||||
void deleteEdge(const EdgePins &edge);
|
||||
|
|
@ -583,7 +582,7 @@ protected:
|
|||
// Leaf/port pins.
|
||||
PinSet *pins_;
|
||||
// Graph edges that traverse thru hierarchical pins.
|
||||
EdgePinsSet *edges_;
|
||||
EdgePinsSet *edges_{nullptr};
|
||||
NetSet *nets_;
|
||||
InstanceSet *insts_;
|
||||
};
|
||||
|
|
@ -602,9 +601,9 @@ public:
|
|||
|
||||
private:
|
||||
const ExceptionPath *exception_;
|
||||
bool from_done_;
|
||||
bool from_done_{false};
|
||||
ExceptionThruSeq::iterator thru_iter_;
|
||||
bool to_done_;
|
||||
bool to_done_{false};
|
||||
};
|
||||
|
||||
// Visitor for exception point sets expanded into single object paths.
|
||||
|
|
@ -620,7 +619,6 @@ class ExpandedExceptionVisitor
|
|||
public:
|
||||
ExpandedExceptionVisitor(ExceptionPath *exception,
|
||||
const Network *network);
|
||||
virtual ~ExpandedExceptionVisitor() {}
|
||||
void visitExpansions();
|
||||
// From/thrus/to have a single exception point (pin/instance/net/clock).
|
||||
virtual void visit(ExceptionFrom *from,
|
||||
|
|
@ -666,7 +664,7 @@ public:
|
|||
private:
|
||||
ExceptionPath *exception_;
|
||||
ExceptionThru *next_thru_;
|
||||
ExceptionState *next_state_;
|
||||
ExceptionState *next_state_{nullptr};
|
||||
int index_;
|
||||
};
|
||||
|
||||
|
|
@ -678,7 +676,7 @@ exceptionStateCmp(const ExceptionState *state1,
|
|||
class EmptyExpceptionPt : public Exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept;
|
||||
const char *what() const noexcept override;
|
||||
};
|
||||
|
||||
class ExceptionPathLess
|
||||
|
|
@ -698,4 +696,4 @@ checkFromThrusTo(ExceptionFrom *from,
|
|||
ExceptionThruSeq *thrus,
|
||||
ExceptionTo *to);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
// Copyright (c) 2026, 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
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "GraphClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
|
@ -39,68 +41,57 @@ class Report;
|
|||
|
||||
PortSeq
|
||||
filterPorts(std::string_view filter_expression,
|
||||
PortSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
PortSeq *ports,
|
||||
Sta *sta);
|
||||
|
||||
InstanceSeq
|
||||
filterInstances(std::string_view filter_expression,
|
||||
InstanceSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
InstanceSeq *insts,
|
||||
Sta *sta);
|
||||
|
||||
PinSeq
|
||||
filterPins(std::string_view filter_expression,
|
||||
PinSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
PinSeq *pins,
|
||||
Sta *sta);
|
||||
|
||||
NetSeq
|
||||
filterNets(std::string_view filter_expression,
|
||||
NetSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
NetSeq *nets,
|
||||
Sta *sta);
|
||||
|
||||
ClockSeq
|
||||
filterClocks(std::string_view filter_expression,
|
||||
ClockSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
ClockSeq *clks,
|
||||
Sta *sta);
|
||||
|
||||
LibertyCellSeq
|
||||
filterLibCells(std::string_view filter_expression,
|
||||
LibertyCellSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
LibertyCellSeq *cells,
|
||||
Sta *sta);
|
||||
|
||||
LibertyPortSeq
|
||||
filterLibPins(std::string_view filter_expression,
|
||||
LibertyPortSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
LibertyPortSeq *ports,
|
||||
Sta *sta);
|
||||
|
||||
LibertyLibrarySeq
|
||||
filterLibertyLibraries(std::string_view filter_expression,
|
||||
LibertyLibrarySeq *objects,
|
||||
bool bool_props_as_int,
|
||||
LibertyLibrarySeq *libs,
|
||||
Sta *sta);
|
||||
|
||||
EdgeSeq
|
||||
filterTimingArcs(std::string_view filter_expression,
|
||||
EdgeSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
EdgeSeq *edges,
|
||||
Sta *sta);
|
||||
|
||||
PathEndSeq
|
||||
filterPathEnds(std::string_view filter_expression,
|
||||
PathEndSeq *objects,
|
||||
bool bool_props_as_int,
|
||||
PathEndSeq *ends,
|
||||
Sta *sta);
|
||||
|
||||
// For FilterExpr unit tests.
|
||||
StringSeq
|
||||
filterExprToPostfix(std::string_view expr,
|
||||
bool bool_props_as_int,
|
||||
Report *report);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "NetworkClass.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -105,4 +105,4 @@ private:
|
|||
FuncExpr *
|
||||
funcExprNot(FuncExpr *expr);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -48,4 +48,4 @@ fuzzyGreaterEqual(float v1,
|
|||
bool
|
||||
fuzzyInf(float value);
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include "Iterator.hh"
|
||||
#include "ObjectTable.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "Delay.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "VertexId.hh"
|
||||
#include "Iterator.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "ObjectTable.hh"
|
||||
#include "Path.hh"
|
||||
#include "StaState.hh"
|
||||
#include "VertexId.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ public:
|
|||
Graph(StaState *sta,
|
||||
DcalcAPIndex ap_count);
|
||||
void makeGraph();
|
||||
~Graph();
|
||||
~Graph() override;
|
||||
|
||||
// Number of arc delays and slews from sdf or delay calculation.
|
||||
void setDelayCount(DcalcAPIndex ap_count);
|
||||
|
|
@ -102,7 +102,7 @@ public:
|
|||
const Slew &slew);
|
||||
|
||||
// Edge functions.
|
||||
Edge *edge(EdgeId edge_index) const;
|
||||
Edge *edge(EdgeId edge_id) const;
|
||||
EdgeId id(const Edge *edge) const;
|
||||
Edge *makeEdge(Vertex *from,
|
||||
Vertex *to,
|
||||
|
|
@ -211,8 +211,8 @@ protected:
|
|||
void initArcDelays(Edge *edge);
|
||||
void removeDelayAnnotated(Edge *edge);
|
||||
|
||||
VertexTable *vertices_;
|
||||
EdgeTable *edges_;
|
||||
VertexTable *vertices_{nullptr};
|
||||
EdgeTable *edges_{nullptr};
|
||||
// Bidirect pins are split into two vertices:
|
||||
// load/sink (top level output, instance pin input) vertex in pin_vertex_map
|
||||
// driver/source (top level input, instance pin output) vertex
|
||||
|
|
@ -291,8 +291,8 @@ protected:
|
|||
bool is_bidirect_drvr,
|
||||
bool is_reg_clk);
|
||||
void clear();
|
||||
Slew *slews() { return std::bit_cast<Slew*>(slews_); }
|
||||
const Slew *slews() const { return std::bit_cast<const Slew*>(slews_); }
|
||||
Slew *slews() { return reinterpret_cast<Slew*>(slews_); }
|
||||
const Slew *slews() const { return reinterpret_cast<const Slew*>(slews_); }
|
||||
float *slewsFloat() { return slews_; }
|
||||
const float *slewsFloat() const { return slews_; }
|
||||
void setSlews(float *slews);
|
||||
|
|
@ -436,9 +436,9 @@ private:
|
|||
Network *network_;
|
||||
Instance *top_inst_;
|
||||
LeafInstanceIterator *inst_iter_;
|
||||
InstancePinIterator *pin_iter_;
|
||||
Vertex *vertex_;
|
||||
Vertex *bidir_vertex_;
|
||||
InstancePinIterator *pin_iter_{nullptr};
|
||||
Vertex *vertex_{nullptr};
|
||||
Vertex *bidir_vertex_{nullptr};
|
||||
};
|
||||
|
||||
class VertexInEdgeIterator : public VertexEdgeIterator
|
||||
|
|
@ -491,4 +491,4 @@ makeVertexSet(StaState *sta)
|
|||
return VertexSet(VertexIdLess(sta->graphRef()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sta
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue