mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-05-30 00:24:12 +08:00
Merge branch 'master' into sta_update_upstream_lvf_stuff
This commit is contained in:
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@@ -16,7 +16,16 @@ jobs:
|
||||
|
||||
- name: Set up dependencies
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install -y flex libfl-dev bison tcl-dev tcl-tclreadline libeigen3-dev ninja-build
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
flex \
|
||||
libfl-dev \
|
||||
bison \
|
||||
tcl-dev \
|
||||
tcl-tclreadline \
|
||||
libeigen3-dev \
|
||||
ninja-build \
|
||||
libgtest-dev
|
||||
|
||||
- name: Set up cudd-3.0.0
|
||||
run: |
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -12,6 +12,7 @@ Makefile
|
||||
gmon.out
|
||||
|
||||
cmake-build-debug
|
||||
coverage-output
|
||||
build
|
||||
pvt
|
||||
|
||||
@@ -21,6 +22,7 @@ examples/gcd_tb
|
||||
doc/._Sta.docx
|
||||
|
||||
test/results
|
||||
*/test/results
|
||||
# ngspice turd
|
||||
test/b3v3_1check.log
|
||||
|
||||
|
||||
@@ -652,3 +652,44 @@ add_custom_command(
|
||||
COMMAND ${STA_HOME}/etc/FindMessages.tcl > ${STA_HOME}/doc/messages.txt || true
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
)
|
||||
|
||||
################################################################
|
||||
# Tests
|
||||
################################################################
|
||||
|
||||
option(BUILD_TESTS "Build unit tests" ON)
|
||||
if(BUILD_TESTS)
|
||||
enable_testing()
|
||||
find_package(GTest REQUIRED)
|
||||
include(GoogleTest)
|
||||
|
||||
# Helper: register a list of Tcl tests for a module.
|
||||
# Usage:
|
||||
# sta_module_tests("search" TESTS timing analysis ...)
|
||||
function(sta_module_tests module_name)
|
||||
cmake_parse_arguments(ARG "" "" "TESTS" ${ARGN})
|
||||
foreach(test_name ${ARG_TESTS})
|
||||
add_test(
|
||||
NAME tcl.${module_name}.${test_name}
|
||||
COMMAND bash ${STA_HOME}/test/regression.sh $<TARGET_FILE:sta> ${module_name}_${test_name}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
set_tests_properties(tcl.${module_name}.${test_name} PROPERTIES LABELS "tcl;module_${module_name}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(test)
|
||||
# Per-module tests
|
||||
add_subdirectory(util/test)
|
||||
add_subdirectory(liberty/test)
|
||||
add_subdirectory(graph/test)
|
||||
add_subdirectory(network/test)
|
||||
add_subdirectory(sdc/test)
|
||||
add_subdirectory(sdf/test)
|
||||
add_subdirectory(dcalc/test)
|
||||
add_subdirectory(search/test)
|
||||
add_subdirectory(parasitics/test)
|
||||
add_subdirectory(power/test)
|
||||
add_subdirectory(verilog/test)
|
||||
add_subdirectory(spice/test)
|
||||
endif()
|
||||
|
||||
@@ -53,6 +53,21 @@ RUN source /opt/rh/devtoolset-11/enable && \
|
||||
make -j`nproc` && \
|
||||
make install
|
||||
|
||||
# Download and build GTest
|
||||
RUN <<EOF
|
||||
set -e
|
||||
wget https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz
|
||||
tar -xvf v1.14.0.tar.gz
|
||||
source /opt/rh/devtoolset-11/enable
|
||||
cd googletest-1.14.0
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make -j$(nproc)
|
||||
make install
|
||||
cd ../..
|
||||
rm -rf v1.14.0.tar.gz googletest-1.14.0
|
||||
EOF
|
||||
|
||||
FROM base-dependencies AS builder
|
||||
|
||||
COPY . /OpenSTA
|
||||
|
||||
@@ -18,7 +18,8 @@ RUN apt-get update && \
|
||||
bison \
|
||||
flex \
|
||||
automake \
|
||||
autotools-dev
|
||||
autotools-dev \
|
||||
libgtest-dev
|
||||
|
||||
# Download CUDD
|
||||
RUN wget https://raw.githubusercontent.com/davidkebo/cudd/main/cudd_versions/cudd-3.0.0.tar.gz && \
|
||||
|
||||
1
dcalc/test/CMakeLists.txt
Normal file
1
dcalc/test/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(cpp)
|
||||
16
dcalc/test/cpp/CMakeLists.txt
Normal file
16
dcalc/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestFindRoot TestFindRoot.cc)
|
||||
target_link_libraries(TestFindRoot
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestFindRoot PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestFindRoot
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_dcalc"
|
||||
)
|
||||
672
dcalc/test/cpp/TestFindRoot.cc
Normal file
672
dcalc/test/cpp/TestFindRoot.cc
Normal file
@@ -0,0 +1,672 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include "dcalc/FindRoot.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
class FindRootTest : public ::testing::Test {};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Original 7 tests
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Test finding root of f(x) = x^2 - 4 (root at x=2)
|
||||
TEST_F(FindRootTest, QuadraticPositiveRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
||||
// Test finding root of f(x) = x^2 - 4 (root at x=-2)
|
||||
TEST_F(FindRootTest, QuadraticNegativeRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -3.0, -1.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -2.0, 1e-8);
|
||||
}
|
||||
|
||||
// Test finding root of f(x) = x - 1 (linear, root at x=1)
|
||||
TEST_F(FindRootTest, LinearRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 1.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 2.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-8);
|
||||
}
|
||||
|
||||
// Test finding root of f(x) = sin(x) near pi
|
||||
TEST_F(FindRootTest, SinRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 2.5, 3.8, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, M_PI, 1e-6);
|
||||
}
|
||||
|
||||
// Test finding root of f(x) = e^x - 2 (root at x=ln(2))
|
||||
TEST_F(FindRootTest, ExponentialRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = exp(x) - 2.0;
|
||||
dy = exp(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.0, 1.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, log(2.0), 1e-8);
|
||||
}
|
||||
|
||||
// Test with tight tolerance
|
||||
TEST_F(FindRootTest, TightTolerance) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 2.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 2.0, 1e-14, 200, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, sqrt(2.0), 1e-12);
|
||||
}
|
||||
|
||||
// Test the 4-argument version with pre-computed y values
|
||||
TEST_F(FindRootTest, WithPrecomputedY) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Tolerance edge cases
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Very tight tolerance: 1e-15 (near machine epsilon)
|
||||
TEST_F(FindRootTest, VeryTightTolerance) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 5.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 3.0, 7.0, 1e-15, 500, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-13);
|
||||
}
|
||||
|
||||
// Very loose tolerance: 1e-1
|
||||
TEST_F(FindRootTest, LooseTolerance) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 25.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 3.0, 7.0, 1e-1, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
// With 10% relative tolerance, result should still be in the right ballpark
|
||||
EXPECT_NEAR(root, 5.0, 0.6);
|
||||
}
|
||||
|
||||
// Zero tolerance: convergence check becomes abs(dx) <= 0, which is only
|
||||
// satisfied when dx is exactly 0. Likely hits max_iter and fails.
|
||||
TEST_F(FindRootTest, ZeroTolerance) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 3.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 5.0, 0.0, 100, fail);
|
||||
// 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) {
|
||||
EXPECT_NEAR(root, 3.0, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Iteration limit edge cases
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Only 1 iteration allowed
|
||||
TEST_F(FindRootTest, OneIteration) {
|
||||
ASSERT_NO_THROW(( [&](){
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-10, 1, fail);
|
||||
// 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
|
||||
EXPECT_GE(root, 1.0);
|
||||
EXPECT_LE(root, 3.0);
|
||||
|
||||
}() ));
|
||||
}
|
||||
|
||||
// Two iterations
|
||||
TEST_F(FindRootTest, TwoIterations) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 7.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 5.0, 9.0, 1e-10, 2, fail);
|
||||
// Linear function: Newton should converge very fast
|
||||
// After the initial midpoint (7.0), Newton step should nail it
|
||||
if (!fail) {
|
||||
EXPECT_NEAR(root, 7.0, 1e-6);
|
||||
}
|
||||
}
|
||||
|
||||
// Zero max iterations: the for-loop body never executes, so fail is set to true
|
||||
TEST_F(FindRootTest, ZeroMaxIterations) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 1.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, 0.0, 2.0, 1e-10, 0, fail);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
// Large max_iter (should still converge quickly and not hang)
|
||||
TEST_F(FindRootTest, LargeMaxIter) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 16.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 10.0, 1e-12, 10000, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 4.0, 1e-10);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Special function types
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Cubic: f(x) = x^3 - 8 (root at x=2)
|
||||
TEST_F(FindRootTest, CubicRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
||||
// Quartic: f(x) = x^4 - 16 (root at x=2)
|
||||
TEST_F(FindRootTest, QuarticRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
||||
// Exponential: f(x) = e^x - 10 (root at x=ln(10))
|
||||
TEST_F(FindRootTest, ExponentialRoot2) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = exp(x) - 10.0;
|
||||
dy = exp(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 4.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, log(10.0), 1e-8);
|
||||
}
|
||||
|
||||
// Square root function: f(x) = sqrt(x) - 3, root at x=9
|
||||
// Derivative: 1/(2*sqrt(x))
|
||||
TEST_F(FindRootTest, SqrtFunctionRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 9.0, 1e-6);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Near-zero roots
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = x - 1e-10 (root very close to zero)
|
||||
// Note: convergence check is abs(dx) <= x_tol * abs(root).
|
||||
// When root is near zero, the relative tolerance is very tight.
|
||||
// This may require many iterations or not converge.
|
||||
TEST_F(FindRootTest, NearZeroRootLinear) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 1e-10;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1.0, 1.0, 1e-6, 200, fail);
|
||||
// Newton on a linear function converges in 1-2 steps regardless of root location
|
||||
if (!fail) {
|
||||
EXPECT_NEAR(root, 1e-10, 1e-6);
|
||||
}
|
||||
}
|
||||
|
||||
// f(x) = x (root exactly at zero)
|
||||
// Convergence test: abs(dx) <= x_tol * abs(root) = x_tol * 0 = 0
|
||||
// Will likely hit max_iter because relative tolerance at root=0 requires dx=0 exactly
|
||||
TEST_F(FindRootTest, RootExactlyAtZero) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1.0, 1.0, 1e-10, 200, fail);
|
||||
// Even if fail is true, root should be very close to 0
|
||||
EXPECT_NEAR(root, 0.0, 1e-6);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Negative domain
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Root in deeply negative domain: f(x) = x + 100, root at x=-100
|
||||
TEST_F(FindRootTest, NegativeDomainRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x + 100.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -200.0, 0.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -100.0, 1e-6);
|
||||
}
|
||||
|
||||
// Both bracket endpoints negative: f(x) = x^2 - 1, root at x=-1
|
||||
TEST_F(FindRootTest, NegativeBracketRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 1.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -2.0, -0.5, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -1.0, 1e-8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Trigonometric functions
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// sin(x) root at x=0 (bracket [-1, 1])
|
||||
TEST_F(FindRootTest, SinRootAtZero) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1.0, 1.0, 1e-10, 100, fail);
|
||||
// Root at 0 has the relative-tolerance issue, but Newton converges fast for sin
|
||||
EXPECT_NEAR(root, 0.0, 1e-4);
|
||||
}
|
||||
|
||||
// sin(x) root at x=2*pi (bracket [5.5, 7.0])
|
||||
TEST_F(FindRootTest, SinRootAt2Pi) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = sin(x);
|
||||
dy = cos(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 5.5, 7.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0 * M_PI, 1e-6);
|
||||
}
|
||||
|
||||
// cos(x) root at x=pi/2
|
||||
TEST_F(FindRootTest, CosRootAtPiOver2) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = cos(x);
|
||||
dy = -sin(x);
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, M_PI / 2.0, 1e-6);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Multiple roots nearby
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = (x-1)(x-2) = x^2 - 3x + 2, roots at x=1 and x=2
|
||||
// Bracket [0.5, 1.5] should find x=1
|
||||
TEST_F(FindRootTest, MultipleRootsFindFirst) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-8);
|
||||
}
|
||||
|
||||
// Same function, bracket [1.5, 2.5] should find x=2
|
||||
TEST_F(FindRootTest, MultipleRootsFindSecond) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Discontinuous derivative (sharp corner)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = |x| - 1 with piecewise derivative.
|
||||
// Root at x=1 (bracket [0.5, 2.0] avoids the corner at 0)
|
||||
TEST_F(FindRootTest, AbsValueRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-8);
|
||||
}
|
||||
|
||||
// f(x) = |x| - 1, root at x=-1
|
||||
TEST_F(FindRootTest, AbsValueNegativeRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -1.0, 1e-8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Very flat function (slow convergence)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = (x - 3)^5 has a repeated root at x=3 where the derivative is also
|
||||
// zero. Newton-Raphson divides by dy which becomes 0, producing NaN.
|
||||
// The algorithm is expected to fail on this degenerate case.
|
||||
TEST_F(FindRootTest, FlatFifthOrderRootFails) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
double d = x - 3.0;
|
||||
double d2 = d * d;
|
||||
double d4 = d2 * d2;
|
||||
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);
|
||||
// The algorithm is expected to fail because dy -> 0 at the root
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
// A function that is very flat near the root but still has nonzero derivative
|
||||
// at the root: f(x) = sinh(x - 3) which is ~0 near x=3 but never has dy=0.
|
||||
// sinh is flat near 0 (sinh(e) ~ e for small e) but derivative cosh(e) >= 1.
|
||||
TEST_F(FindRootTest, FlatSinhRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-6);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Very steep function (fast convergence)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = 1000*(x - 5), root at x=5. Very steep gradient.
|
||||
TEST_F(FindRootTest, SteepLinearRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = 1000.0 * (x - 5.0);
|
||||
dy = 1000.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 3.0, 7.0, 1e-12, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 5.0, 1e-10);
|
||||
}
|
||||
|
||||
// f(x) = 1e6 * (x - 2), very steep
|
||||
TEST_F(FindRootTest, VerySteepLinearRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = 1e6 * (x - 2.0);
|
||||
dy = 1e6;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 3.0, 1e-14, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-12);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Large bracket
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = x - 42, bracket [-1000, 1000]
|
||||
TEST_F(FindRootTest, LargeBracket) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 42.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -1000.0, 1000.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 42.0, 1e-6);
|
||||
}
|
||||
|
||||
// Quadratic with large bracket: f(x) = x^2 - 100, root at 10
|
||||
TEST_F(FindRootTest, LargeBracketQuadratic) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 100.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.0, 1000.0, 1e-10, 200, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 10.0, 1e-6);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Small bracket
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = x - 1.0, bracket [0.999999, 1.000001] (very tight bracket around root)
|
||||
TEST_F(FindRootTest, SmallBracket) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x - 1.0;
|
||||
dy = 1.0;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.999999, 1.000001, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 1.0, 1e-6);
|
||||
}
|
||||
|
||||
// Quadratic with very small bracket around root=2
|
||||
TEST_F(FindRootTest, SmallBracketQuadratic) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 1.9999, 2.0001, 1e-12, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Both overloads tested together
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Compare 2-arg and 4-arg overloads produce same result
|
||||
TEST_F(FindRootTest, OverloadsProduceSameResult) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x * x - 27.0;
|
||||
dy = 3.0 * x * x;
|
||||
};
|
||||
|
||||
bool fail_2arg = false;
|
||||
double root_2arg = findRoot(func, 2.0, 4.0, 1e-12, 100, fail_2arg);
|
||||
|
||||
// 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);
|
||||
|
||||
EXPECT_FALSE(fail_2arg);
|
||||
EXPECT_FALSE(fail_4arg);
|
||||
EXPECT_NEAR(root_2arg, 3.0, 1e-10);
|
||||
EXPECT_NEAR(root_4arg, 3.0, 1e-10);
|
||||
EXPECT_NEAR(root_2arg, root_4arg, 1e-14);
|
||||
}
|
||||
|
||||
// 4-arg overload: x1 endpoint is exact root (y1 == 0)
|
||||
TEST_F(FindRootTest, FourArgX1IsRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_DOUBLE_EQ(root, 5.0);
|
||||
}
|
||||
|
||||
// 4-arg overload: x2 endpoint is exact root (y2 == 0)
|
||||
TEST_F(FindRootTest, FourArgX2IsRoot) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_DOUBLE_EQ(root, 5.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Same-sign y values (should fail)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Both endpoints positive: should fail
|
||||
TEST_F(FindRootTest, BothEndpointsPositiveFails) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
// Both endpoints negative: should fail
|
||||
TEST_F(FindRootTest, BothEndpointsNegativeFails) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = -x * x - 1.0; // Always negative
|
||||
dy = -2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
findRoot(func, -3.0, 3.0, 1e-10, 100, fail);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
// 4-arg version: same-sign y values
|
||||
TEST_F(FindRootTest, FourArgSameSignFails) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_TRUE(fail);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Symmetry test
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// f(x) = x^2 - 4: bracket [0, 3] finds +2, bracket [-3, 0] finds -2
|
||||
TEST_F(FindRootTest, SymmetryPositiveBracket) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, 0.5, 3.0, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 2.0, 1e-8);
|
||||
}
|
||||
|
||||
TEST_F(FindRootTest, SymmetryNegativeBracket) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
y = x * x - 4.0;
|
||||
dy = 2.0 * x;
|
||||
};
|
||||
bool fail = false;
|
||||
double root = findRoot(func, -3.0, -0.5, 1e-10, 100, fail);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, -2.0, 1e-8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Swapped bracket order (x1 > x2)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// The algorithm should work regardless of bracket order
|
||||
TEST_F(FindRootTest, SwappedBracketOrder) {
|
||||
FindRootFunc func = [](double x, double &y, double &dy) {
|
||||
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);
|
||||
EXPECT_FALSE(fail);
|
||||
EXPECT_NEAR(root, 3.0, 1e-8);
|
||||
}
|
||||
|
||||
} // namespace sta
|
||||
1
dcalc/test/regression
Symbolic link
1
dcalc/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
dcalc/test/save_ok
Symbolic link
1
dcalc/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
127
etc/Build.sh
Executable file
127
etc/Build.sh
Executable file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright (c) 2025, The OpenROAD Authors
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DIR="$(dirname $(readlink -f $0))"
|
||||
cd "$DIR/../"
|
||||
|
||||
# default values, can be overwritten by cmdline args
|
||||
buildDir="build"
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
numThreads=$(nproc --all)
|
||||
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"
|
||||
EOF
|
||||
numThreads=2
|
||||
fi
|
||||
cmakeOptions=""
|
||||
cleanBefore=no
|
||||
compiler=gcc
|
||||
|
||||
_help() {
|
||||
cat <<EOF
|
||||
usage: $0 [OPTIONS]
|
||||
|
||||
Build OpenSTA from source.
|
||||
|
||||
OPTIONS:
|
||||
-cmake='-<key>=<value> ...' User defined cmake options
|
||||
Note: use single quote after
|
||||
-cmake= and double quotes if
|
||||
<key> has multiple <values>
|
||||
e.g.: -cmake='-DFLAGS="-a -b"'
|
||||
-compiler=COMPILER_NAME Compiler name: gcc or clang
|
||||
Default: gcc
|
||||
-dir=PATH Path to store build files.
|
||||
Default: ./build
|
||||
-coverage Enable cmake coverage options
|
||||
-clean Remove build dir before compile
|
||||
-threads=NUM_THREADS Number of threads to use during
|
||||
compile. Default: \`nproc\` on linux
|
||||
or \`sysctl -n hw.ncpu\` on macOS
|
||||
-O0 Disable optimizations for accurate
|
||||
coverage measurement
|
||||
-help Shows this message
|
||||
|
||||
EOF
|
||||
exit "${1:-1}"
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "${1}" in
|
||||
-h|-help)
|
||||
_help 0
|
||||
;;
|
||||
-coverage )
|
||||
cmakeOptions+=" -DCMAKE_BUILD_TYPE=Debug"
|
||||
cmakeOptions+=" -DCMAKE_CXX_FLAGS='--coverage'"
|
||||
cmakeOptions+=" -DCMAKE_EXE_LINKER_FLAGS='--coverage'"
|
||||
;;
|
||||
-O0 )
|
||||
cmakeOptions+=" -DCMAKE_CXX_FLAGS_DEBUG='-g -O0'"
|
||||
;;
|
||||
-cmake=*)
|
||||
cmakeOptions+=" ${1#*=}"
|
||||
;;
|
||||
-clean )
|
||||
cleanBefore=yes
|
||||
;;
|
||||
-compiler=*)
|
||||
compiler="${1#*=}"
|
||||
;;
|
||||
-dir=* )
|
||||
buildDir="${1#*=}"
|
||||
;;
|
||||
-threads=* )
|
||||
numThreads="${1#*=}"
|
||||
;;
|
||||
-compiler | -cmake | -dir | -threads )
|
||||
echo "${1} requires an argument" >&2
|
||||
_help
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: ${1}" >&2
|
||||
_help
|
||||
;;
|
||||
esac
|
||||
shift 1
|
||||
done
|
||||
|
||||
case "${compiler}" in
|
||||
"gcc" )
|
||||
export CC="$(command -v gcc)"
|
||||
export CXX="$(command -v g++)"
|
||||
;;
|
||||
"clang" )
|
||||
export CC="$(command -v clang)"
|
||||
export CXX="$(command -v clang++)"
|
||||
;;
|
||||
*)
|
||||
echo "Compiler $compiler not supported. Use gcc or clang." >&2
|
||||
_help 1
|
||||
esac
|
||||
|
||||
if [[ -z "${CC}" || -z "${CXX}" ]]; then
|
||||
echo "Compiler $compiler not installed." >&2
|
||||
_help 1
|
||||
fi
|
||||
|
||||
if [[ "${cleanBefore}" == "yes" ]]; then
|
||||
rm -rf "${buildDir}"
|
||||
fi
|
||||
|
||||
mkdir -p "${buildDir}"
|
||||
|
||||
echo "[INFO] Compiler: ${compiler} (${CC})"
|
||||
echo "[INFO] Build dir: ${buildDir}"
|
||||
echo "[INFO] Using ${numThreads} threads."
|
||||
|
||||
eval cmake "${cmakeOptions}" -B "${buildDir}" .
|
||||
eval time cmake --build "${buildDir}" -j "${numThreads}"
|
||||
120
etc/CodeCoverage.sh
Executable file
120
etc/CodeCoverage.sh
Executable file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright (c) 2025, The OpenROAD Authors
|
||||
|
||||
# Generate an lcov/genhtml code coverage report for OpenSTA.
|
||||
# Requires a coverage build: ./etc/Build.sh -coverage
|
||||
#
|
||||
# Usage:
|
||||
# ./etc/CodeCoverage.sh Run all tests, generate report
|
||||
# ./etc/CodeCoverage.sh -tcl-only Run only Tcl tests (skip C++ unit tests)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname $(readlink -f $0))/../"
|
||||
|
||||
buildDir="build"
|
||||
reportDir="coverage-output"
|
||||
tclOnly=no
|
||||
|
||||
_help() {
|
||||
cat <<EOF
|
||||
usage: $0 [OPTIONS]
|
||||
|
||||
Generate an lcov/genhtml code coverage report for OpenSTA.
|
||||
Requires a coverage build first: ./etc/Build.sh -coverage
|
||||
|
||||
OPTIONS:
|
||||
-tcl-only Run only Tcl tests (skip C++ unit tests)
|
||||
-dir=PATH Build directory. Default: ./build
|
||||
-help Shows this message
|
||||
|
||||
OUTPUT:
|
||||
coverage-output/ HTML coverage report
|
||||
coverage-output/index.html Main report page
|
||||
|
||||
EOF
|
||||
exit "${1:-1}"
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "${1}" in
|
||||
-h|-help)
|
||||
_help 0
|
||||
;;
|
||||
-tcl-only)
|
||||
tclOnly=yes
|
||||
;;
|
||||
-dir=*)
|
||||
buildDir="${1#*=}"
|
||||
;;
|
||||
-dir )
|
||||
echo "${1} requires an argument" >&2
|
||||
_help
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: ${1}" >&2
|
||||
_help
|
||||
;;
|
||||
esac
|
||||
shift 1
|
||||
done
|
||||
|
||||
if [[ ! -d "${buildDir}" ]]; then
|
||||
echo "Build directory '${buildDir}' not found." >&2
|
||||
echo "Run ./etc/Build.sh -coverage first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Common lcov flags to suppress all known warnings:
|
||||
# mismatch - GCC/GoogleTest macro function range mismatches
|
||||
# gcov - unexecuted blocks on non-branch lines (GCC optimizer artifacts)
|
||||
# source - source file newer than .gcno notes file (stale build artifacts)
|
||||
# Double-specification (X,X) suppresses the warning output entirely.
|
||||
LCOV_IGNORE="--ignore-errors mismatch,mismatch,gcov,gcov,source,source,unused,unused,negative,negative"
|
||||
|
||||
# Clear stale coverage data before test execution.
|
||||
# Old .gcda files from previous runs can cause gcov checksum mismatch noise.
|
||||
find "${buildDir}" -name '*.gcda' -delete
|
||||
|
||||
# Step 1: Run tests
|
||||
if [[ "${tclOnly}" == "yes" ]]; then
|
||||
echo "[INFO] Running Tcl tests only..."
|
||||
ctest --test-dir "${buildDir}" -L tcl -j $(nproc) --output-on-failure || true
|
||||
else
|
||||
echo "[INFO] Running all tests..."
|
||||
ctest --test-dir "${buildDir}" -j $(nproc) --output-on-failure || true
|
||||
fi
|
||||
|
||||
# Step 2: Capture coverage
|
||||
echo "[INFO] Capturing coverage data..."
|
||||
lcov --capture \
|
||||
-d "${buildDir}" \
|
||||
-o "${buildDir}/coverage.info" \
|
||||
--quiet \
|
||||
${LCOV_IGNORE}
|
||||
|
||||
# Step 3: Filter system/build/test dirs
|
||||
lcov --remove "${buildDir}/coverage.info" \
|
||||
'/usr/*' \
|
||||
'*/build/*' \
|
||||
'*/test/*' \
|
||||
-o "${buildDir}/filtered.info" \
|
||||
--quiet \
|
||||
${LCOV_IGNORE}
|
||||
|
||||
# Step 4: Generate HTML report
|
||||
GENHTML_IGNORE="--ignore-errors unmapped,unmapped,inconsistent,inconsistent,corrupt,corrupt,negative,negative,empty,empty,format,format,mismatch,mismatch,source,source"
|
||||
|
||||
mkdir -p "${reportDir}"
|
||||
genhtml "${buildDir}/filtered.info" \
|
||||
--output-directory "${reportDir}" \
|
||||
--quiet \
|
||||
${GENHTML_IGNORE} || true
|
||||
|
||||
echo ""
|
||||
echo "=== Coverage report generated ==="
|
||||
echo "Open $(pwd)/${reportDir}/index.html in a browser to view."
|
||||
echo ""
|
||||
lcov --summary "${buildDir}/filtered.info" ${LCOV_IGNORE} 2>&1 || true
|
||||
6
graph/test/CMakeLists.txt
Normal file
6
graph/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("graph"
|
||||
TESTS
|
||||
make_verify
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
graph/test/cpp/CMakeLists.txt
Normal file
16
graph/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestGraph TestGraph.cc)
|
||||
target_link_libraries(TestGraph
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestGraph PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestGraph
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_graph"
|
||||
)
|
||||
2026
graph/test/cpp/TestGraph.cc
Normal file
2026
graph/test/cpp/TestGraph.cc
Normal file
File diff suppressed because it is too large
Load Diff
1
graph/test/graph_make_verify.ok
Normal file
1
graph/test/graph_make_verify.ok
Normal file
@@ -0,0 +1 @@
|
||||
No paths found.
|
||||
10
graph/test/graph_make_verify.tcl
Normal file
10
graph/test/graph_make_verify.tcl
Normal file
@@ -0,0 +1,10 @@
|
||||
# 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]
|
||||
8
graph/test/graph_test1.v
Normal file
8
graph/test/graph_test1.v
Normal file
@@ -0,0 +1,8 @@
|
||||
module graph_test1 (clk, d, q);
|
||||
input clk, d;
|
||||
output q;
|
||||
wire n1;
|
||||
|
||||
DFF_X1 reg1 (.D(d), .CK(clk), .Q(n1));
|
||||
DFF_X1 reg2 (.D(n1), .CK(clk), .Q(q));
|
||||
endmodule
|
||||
14
graph/test/graph_test2.v
Normal file
14
graph/test/graph_test2.v
Normal file
@@ -0,0 +1,14 @@
|
||||
module graph_test2 (clk, d1, d2, en, q1, q2);
|
||||
input clk, d1, d2, en;
|
||||
output q1, q2;
|
||||
wire n1, n2, n3, n4, n5, n6;
|
||||
|
||||
BUF_X1 buf1 (.A(d1), .Z(n1));
|
||||
BUF_X2 buf2 (.A(d2), .Z(n2));
|
||||
INV_X1 inv1 (.A(n1), .ZN(n3));
|
||||
AND2_X1 and1 (.A1(n3), .A2(en), .ZN(n4));
|
||||
OR2_X1 or1 (.A1(n2), .A2(n4), .ZN(n5));
|
||||
BUF_X1 buf3 (.A(n5), .Z(n6));
|
||||
DFF_X1 reg1 (.D(n4), .CK(clk), .Q(q1));
|
||||
DFF_X1 reg2 (.D(n6), .CK(clk), .Q(q2));
|
||||
endmodule
|
||||
34
graph/test/graph_test3.v
Normal file
34
graph/test/graph_test3.v
Normal file
@@ -0,0 +1,34 @@
|
||||
// Larger design for graph operations testing: more cell types, fan-in/fan-out,
|
||||
// multiple clock domains, and reconvergent paths.
|
||||
module graph_test3 (clk1, clk2, rst, d1, d2, d3, d4, q1, q2, q3);
|
||||
input clk1, clk2, rst, d1, d2, d3, d4;
|
||||
output q1, q2, q3;
|
||||
wire n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12;
|
||||
|
||||
// Input stage: buffers and inverters
|
||||
BUF_X1 buf1 (.A(d1), .Z(n1));
|
||||
BUF_X2 buf2 (.A(d2), .Z(n2));
|
||||
INV_X1 inv1 (.A(d3), .ZN(n3));
|
||||
INV_X2 inv2 (.A(d4), .ZN(n4));
|
||||
|
||||
// Middle stage: logic gates
|
||||
AND2_X1 and1 (.A1(n1), .A2(n2), .ZN(n5));
|
||||
OR2_X1 or1 (.A1(n3), .A2(n4), .ZN(n6));
|
||||
NAND2_X1 nand1 (.A1(n5), .A2(n6), .ZN(n7));
|
||||
NOR2_X1 nor1 (.A1(n1), .A2(n3), .ZN(n8));
|
||||
|
||||
// Reconvergent fan-out
|
||||
AND2_X2 and2 (.A1(n7), .A2(n8), .ZN(n9));
|
||||
OR2_X2 or2 (.A1(n7), .A2(n8), .ZN(n10));
|
||||
|
||||
// Clock domain 1 registers
|
||||
DFF_X1 reg1 (.D(n9), .CK(clk1), .Q(n11));
|
||||
DFF_X1 reg2 (.D(n10), .CK(clk1), .Q(q1));
|
||||
|
||||
// Clock domain 2 register (cross-domain)
|
||||
DFF_X1 reg3 (.D(n11), .CK(clk2), .Q(n12));
|
||||
BUF_X1 buf3 (.A(n12), .Z(q2));
|
||||
|
||||
// Combinational output
|
||||
BUF_X4 buf4 (.A(n7), .Z(q3));
|
||||
endmodule
|
||||
1
graph/test/regression
Symbolic link
1
graph/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
graph/test/save_ok
Symbolic link
1
graph/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
@@ -2762,7 +2762,7 @@ LibertyPort::clkTreeDelay(float in_slew,
|
||||
|| (arc_set->role() == TimingRole::clockTreePathMax()
|
||||
&& min_max == MinMax::max())) {
|
||||
const TimingArc *arc = arc_set->arcTo(to_rf);
|
||||
if (arc->fromEdge()->asRiseFall() == from_rf) {
|
||||
if (arc && arc->fromEdge()->asRiseFall() == from_rf) {
|
||||
const GateTableModel *gate_model = dynamic_cast<GateTableModel*>(arc->model());
|
||||
if (gate_model)
|
||||
return gate_model->delayModel()->findValue(in_slew, 0.0, 0.0);
|
||||
|
||||
6
liberty/test/CMakeLists.txt
Normal file
6
liberty/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("liberty"
|
||||
TESTS
|
||||
read_nangate
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
liberty/test/cpp/CMakeLists.txt
Normal file
16
liberty/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestLibertyClasses TestLibertyClasses.cc)
|
||||
target_link_libraries(TestLibertyClasses
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestLibertyClasses PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestLibertyClasses
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_liberty"
|
||||
)
|
||||
3844
liberty/test/cpp/TestLibertyClasses.cc
Normal file
3844
liberty/test/cpp/TestLibertyClasses.cc
Normal file
File diff suppressed because it is too large
Load Diff
761
liberty/test/liberty_read_nangate.ok
Normal file
761
liberty/test/liberty_read_nangate.ok
Normal file
@@ -0,0 +1,761 @@
|
||||
Cell INV_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 1.55-1.70
|
||||
ZN output function=!A
|
||||
|
||||
Timing arcs
|
||||
A -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell BUF_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 0.88-0.97
|
||||
Z output function=A
|
||||
|
||||
Timing arcs
|
||||
A -> Z
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
Cell NAND2_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A1 input 1.53-1.60
|
||||
A2 input 1.50-1.66
|
||||
ZN output function=!(A1*A2)
|
||||
|
||||
Timing arcs
|
||||
A1 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
A2 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell NOR2_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A1 input 1.41-1.71
|
||||
A2 input 1.56-1.65
|
||||
ZN output function=!(A1+A2)
|
||||
|
||||
Timing arcs
|
||||
A1 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
A2 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell AND2_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A1 input 0.87-0.92
|
||||
A2 input 0.89-0.97
|
||||
ZN output function=A1*A2
|
||||
|
||||
Timing arcs
|
||||
A1 -> ZN
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
A2 -> ZN
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
Cell OR2_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A1 input 0.79-0.95
|
||||
A2 input 0.90-0.94
|
||||
ZN output function=A1+A2
|
||||
|
||||
Timing arcs
|
||||
A1 -> ZN
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
A2 -> ZN
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
Cell MUX2_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 0.91-0.95
|
||||
B input 0.90-0.94
|
||||
S input 1.81-1.92
|
||||
Z output function=(S*B)+(A*!S)
|
||||
|
||||
Timing arcs
|
||||
A -> Z
|
||||
combinational
|
||||
when !B*!S
|
||||
^ -> ^
|
||||
v -> v
|
||||
A -> Z
|
||||
combinational
|
||||
when B*!S
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> Z
|
||||
combinational
|
||||
when !A*S
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> Z
|
||||
combinational
|
||||
when A*S
|
||||
^ -> ^
|
||||
v -> v
|
||||
S -> Z
|
||||
combinational
|
||||
when !A*B
|
||||
^ -> ^
|
||||
v -> v
|
||||
S -> Z
|
||||
combinational
|
||||
when A*!B
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell DFF_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
D input 1.06-1.14
|
||||
CK input 0.86-0.95
|
||||
Q output function=IQ
|
||||
QN output function=IQN
|
||||
IQ internal
|
||||
IQN internal
|
||||
|
||||
Timing arcs
|
||||
CK -> D
|
||||
hold
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> D
|
||||
setup
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> CK
|
||||
width
|
||||
^ -> v
|
||||
v -> ^
|
||||
CK -> Q
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> QN
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
Cell DFFR_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
D input 1.05-1.13
|
||||
RN input 1.74-1.78
|
||||
CK input 0.88-0.98
|
||||
Q output function=IQ
|
||||
QN output function=IQN
|
||||
IQ internal
|
||||
IQN internal
|
||||
|
||||
Timing arcs
|
||||
CK -> D
|
||||
hold
|
||||
when RN
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> D
|
||||
setup
|
||||
when RN
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> RN
|
||||
recovery
|
||||
^ -> ^
|
||||
CK -> RN
|
||||
removal
|
||||
^ -> ^
|
||||
RN -> RN
|
||||
width
|
||||
v -> ^
|
||||
CK -> CK
|
||||
width
|
||||
when RN
|
||||
^ -> v
|
||||
v -> ^
|
||||
CK -> Q
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when !CK*!D
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when !CK*D
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when CK*!D
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when CK*D
|
||||
v -> v
|
||||
CK -> QN
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when !CK*!D
|
||||
v -> ^
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when !CK*D
|
||||
v -> ^
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when CK*!D
|
||||
v -> ^
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when CK*D
|
||||
v -> ^
|
||||
Cell DFFS_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
D input 1.09-1.16
|
||||
SN input 1.33-1.36
|
||||
CK input 0.88-0.97
|
||||
Q output function=IQ
|
||||
QN output function=IQN
|
||||
IQ internal
|
||||
IQN internal
|
||||
|
||||
Timing arcs
|
||||
CK -> D
|
||||
hold
|
||||
when SN
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> D
|
||||
setup
|
||||
when SN
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> SN
|
||||
recovery
|
||||
^ -> ^
|
||||
CK -> SN
|
||||
removal
|
||||
^ -> ^
|
||||
SN -> SN
|
||||
width
|
||||
v -> ^
|
||||
CK -> CK
|
||||
width
|
||||
when SN
|
||||
^ -> v
|
||||
v -> ^
|
||||
CK -> Q
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when !CK*!D
|
||||
v -> ^
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when !CK*D
|
||||
v -> ^
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when CK*!D
|
||||
v -> ^
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when CK*D
|
||||
v -> ^
|
||||
CK -> QN
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when !CK*!D
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when !CK*D
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when CK*!D
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when CK*D
|
||||
v -> v
|
||||
Cell DFFRS_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
D input 1.08-1.15
|
||||
RN input 1.38-1.41
|
||||
SN input 2.10-2.21
|
||||
CK input 0.87-0.96
|
||||
Q output function=IQ
|
||||
QN output function=IQN
|
||||
IQ internal
|
||||
IQN internal
|
||||
|
||||
Timing arcs
|
||||
CK -> D
|
||||
hold
|
||||
when RN*SN
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> D
|
||||
setup
|
||||
when RN*SN
|
||||
^ -> ^
|
||||
^ -> v
|
||||
CK -> RN
|
||||
recovery
|
||||
when SN
|
||||
^ -> ^
|
||||
CK -> RN
|
||||
removal
|
||||
when SN
|
||||
^ -> ^
|
||||
RN -> RN
|
||||
width
|
||||
when SN
|
||||
v -> ^
|
||||
CK -> SN
|
||||
recovery
|
||||
when RN
|
||||
^ -> ^
|
||||
CK -> SN
|
||||
removal
|
||||
when RN
|
||||
^ -> ^
|
||||
SN -> SN
|
||||
width
|
||||
when RN
|
||||
v -> ^
|
||||
CK -> CK
|
||||
width
|
||||
when RN*SN
|
||||
^ -> v
|
||||
v -> ^
|
||||
CK -> Q
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (!CK*!D)*!SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (!CK*!D)*SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (!CK*D)*!SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (!CK*D)*SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (CK*!D)*!SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (CK*!D)*SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (CK*D)*!SN
|
||||
v -> v
|
||||
RN -> Q
|
||||
Reg Set/Clr
|
||||
when (CK*D)*SN
|
||||
v -> v
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when (!CK*!D)*RN
|
||||
v -> ^
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when (!CK*D)*RN
|
||||
v -> ^
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when (CK*!D)*RN
|
||||
v -> ^
|
||||
SN -> Q
|
||||
Reg Set/Clr
|
||||
when (CK*D)*RN
|
||||
v -> ^
|
||||
CK -> QN
|
||||
Reg Clk to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when (!CK*!D)*SN
|
||||
v -> ^
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when (!CK*D)*SN
|
||||
v -> ^
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when (CK*!D)*SN
|
||||
v -> ^
|
||||
RN -> QN
|
||||
Reg Set/Clr
|
||||
when (CK*D)*SN
|
||||
v -> ^
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (!CK*!D)*!RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (!CK*!D)*RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (!CK*D)*!RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (!CK*D)*RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (CK*!D)*!RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (CK*!D)*RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (CK*D)*!RN
|
||||
v -> v
|
||||
SN -> QN
|
||||
Reg Set/Clr
|
||||
when (CK*D)*RN
|
||||
v -> v
|
||||
Cell TLAT_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
D input 1.07-1.14
|
||||
G input 0.92-1.02
|
||||
OE input 1.42-1.50
|
||||
Q tristate enable=OE function=IQ 0.79-0.79
|
||||
IQ internal
|
||||
IQN internal
|
||||
|
||||
Timing arcs
|
||||
G -> D
|
||||
hold
|
||||
v -> ^
|
||||
v -> v
|
||||
G -> D
|
||||
setup
|
||||
v -> ^
|
||||
v -> v
|
||||
G -> G
|
||||
width
|
||||
^ -> v
|
||||
D -> Q
|
||||
Latch D to Q
|
||||
^ -> ^
|
||||
v -> v
|
||||
G -> Q
|
||||
Latch En to Q
|
||||
^ -> ^
|
||||
^ -> v
|
||||
OE -> Q
|
||||
tristate disable
|
||||
v -> 0Z
|
||||
v -> 1Z
|
||||
OE -> Q
|
||||
tristate enable
|
||||
^ -> Z1
|
||||
^ -> Z0
|
||||
Cell AOI21_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 1.54-1.63
|
||||
B1 input 1.45-1.65
|
||||
B2 input 1.41-1.68
|
||||
ZN output function=!(A+(B1*B2))
|
||||
|
||||
Timing arcs
|
||||
A -> ZN
|
||||
combinational
|
||||
when !B1*!B2
|
||||
^ -> v
|
||||
v -> ^
|
||||
A -> ZN
|
||||
combinational
|
||||
when !B1*B2
|
||||
^ -> v
|
||||
v -> ^
|
||||
A -> ZN
|
||||
combinational
|
||||
when B1*!B2
|
||||
^ -> v
|
||||
v -> ^
|
||||
B1 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
B2 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell OAI21_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 1.52-1.67
|
||||
B1 input 1.46-1.66
|
||||
B2 input 1.56-1.57
|
||||
ZN output function=!(A*(B1+B2))
|
||||
|
||||
Timing arcs
|
||||
A -> ZN
|
||||
combinational
|
||||
when !B1*B2
|
||||
^ -> v
|
||||
v -> ^
|
||||
A -> ZN
|
||||
combinational
|
||||
when B1*!B2
|
||||
^ -> v
|
||||
v -> ^
|
||||
A -> ZN
|
||||
combinational
|
||||
when B1*B2
|
||||
^ -> v
|
||||
v -> ^
|
||||
B1 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
B2 -> ZN
|
||||
combinational
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell HA_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 3.06-3.19
|
||||
B input 3.34-3.45
|
||||
CO output function=A*B
|
||||
S output function=A^B
|
||||
|
||||
Timing arcs
|
||||
A -> CO
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> CO
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
A -> S
|
||||
combinational
|
||||
when !B
|
||||
^ -> ^
|
||||
v -> v
|
||||
A -> S
|
||||
combinational
|
||||
when B
|
||||
^ -> v
|
||||
v -> ^
|
||||
B -> S
|
||||
combinational
|
||||
when !A
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> S
|
||||
combinational
|
||||
when A
|
||||
^ -> v
|
||||
v -> ^
|
||||
Cell FA_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 3.61-3.75
|
||||
B input 3.40-3.47
|
||||
CI input 2.66-2.76
|
||||
CO output function=(A*B)+(CI*(A+B))
|
||||
S output function=CI^(A^B)
|
||||
|
||||
Timing arcs
|
||||
A -> CO
|
||||
combinational
|
||||
when !B*CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
A -> CO
|
||||
combinational
|
||||
when B*!CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> CO
|
||||
combinational
|
||||
when !A*CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> CO
|
||||
combinational
|
||||
when A*!CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
CI -> CO
|
||||
combinational
|
||||
when !A*B
|
||||
^ -> ^
|
||||
v -> v
|
||||
CI -> CO
|
||||
combinational
|
||||
when A*!B
|
||||
^ -> ^
|
||||
v -> v
|
||||
A -> S
|
||||
combinational
|
||||
when !B*!CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
A -> S
|
||||
combinational
|
||||
when !B*CI
|
||||
^ -> v
|
||||
v -> ^
|
||||
A -> S
|
||||
combinational
|
||||
when B*!CI
|
||||
^ -> v
|
||||
v -> ^
|
||||
A -> S
|
||||
combinational
|
||||
when B*CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> S
|
||||
combinational
|
||||
when !A*!CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
B -> S
|
||||
combinational
|
||||
when !A*CI
|
||||
^ -> v
|
||||
v -> ^
|
||||
B -> S
|
||||
combinational
|
||||
when A*!CI
|
||||
^ -> v
|
||||
v -> ^
|
||||
B -> S
|
||||
combinational
|
||||
when A*CI
|
||||
^ -> ^
|
||||
v -> v
|
||||
CI -> S
|
||||
combinational
|
||||
when !A*!B
|
||||
^ -> ^
|
||||
v -> v
|
||||
CI -> S
|
||||
combinational
|
||||
when !A*B
|
||||
^ -> v
|
||||
v -> ^
|
||||
CI -> S
|
||||
combinational
|
||||
when A*!B
|
||||
^ -> v
|
||||
v -> ^
|
||||
CI -> S
|
||||
combinational
|
||||
when A*B
|
||||
^ -> ^
|
||||
v -> v
|
||||
Cell CLKBUF_X1
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 0.70-0.78
|
||||
Z output function=A
|
||||
|
||||
Timing arcs
|
||||
A -> Z
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
Cell CLKBUF_X2
|
||||
Library NangateOpenCellLibrary
|
||||
File ../../test/nangate45/Nangate45_typ.lib
|
||||
VDD power
|
||||
VSS ground
|
||||
A input 1.24-1.41
|
||||
Z output function=A
|
||||
|
||||
Timing arcs
|
||||
A -> Z
|
||||
combinational
|
||||
^ -> ^
|
||||
v -> v
|
||||
276
liberty/test/liberty_read_nangate.tcl
Normal file
276
liberty/test/liberty_read_nangate.tcl
Normal file
@@ -0,0 +1,276 @@
|
||||
# Test Nangate45 library reading and cell/pin queries for code coverage
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
|
||||
############################################################
|
||||
# Library queries
|
||||
############################################################
|
||||
|
||||
set lib [get_libs NangateOpenCellLibrary]
|
||||
if { $lib == "" } {
|
||||
puts "FAIL: library not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Inverter cells
|
||||
############################################################
|
||||
|
||||
set inv1 [get_lib_cells NangateOpenCellLibrary/INV_X1]
|
||||
if { $inv1 == "" } {
|
||||
puts "FAIL: INV_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/INV_X1
|
||||
|
||||
set inv_pins [get_lib_pins NangateOpenCellLibrary/INV_X1/*]
|
||||
if { [llength $inv_pins] != 2 } {
|
||||
error "expected 2 pins on INV_X1, found [llength $inv_pins]"
|
||||
}
|
||||
|
||||
# Other inverter sizes
|
||||
foreach sz {X2 X4 X8 X16 X32} {
|
||||
set cell [get_lib_cells NangateOpenCellLibrary/INV_$sz]
|
||||
if { $cell == "" } {
|
||||
puts "FAIL: INV_$sz not found"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Buffer cells
|
||||
############################################################
|
||||
|
||||
set buf1 [get_lib_cells NangateOpenCellLibrary/BUF_X1]
|
||||
if { $buf1 == "" } {
|
||||
puts "FAIL: BUF_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/BUF_X1
|
||||
|
||||
set buf_pins [get_lib_pins NangateOpenCellLibrary/BUF_X1/*]
|
||||
if { [llength $buf_pins] != 2 } {
|
||||
error "expected 2 pins on BUF_X1, found [llength $buf_pins]"
|
||||
}
|
||||
|
||||
foreach sz {X2 X4 X8 X16 X32} {
|
||||
set cell [get_lib_cells NangateOpenCellLibrary/BUF_$sz]
|
||||
if { $cell == "" } {
|
||||
puts "FAIL: BUF_$sz not found"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# NAND cells
|
||||
############################################################
|
||||
|
||||
set nand2 [get_lib_cells NangateOpenCellLibrary/NAND2_X1]
|
||||
if { $nand2 == "" } {
|
||||
puts "FAIL: NAND2_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/NAND2_X1
|
||||
|
||||
set nand_pins [get_lib_pins NangateOpenCellLibrary/NAND2_X1/*]
|
||||
if { [llength $nand_pins] != 3 } {
|
||||
error "expected 3 pins on NAND2_X1, found [llength $nand_pins]"
|
||||
}
|
||||
|
||||
foreach cell_name {NAND2_X2 NAND2_X4 NAND3_X1 NAND3_X2 NAND4_X1} {
|
||||
set cell [get_lib_cells NangateOpenCellLibrary/$cell_name]
|
||||
if { $cell == "" } {
|
||||
puts "FAIL: $cell_name not found"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# NOR cells
|
||||
############################################################
|
||||
|
||||
set nor2 [get_lib_cells NangateOpenCellLibrary/NOR2_X1]
|
||||
if { $nor2 == "" } {
|
||||
puts "FAIL: NOR2_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/NOR2_X1
|
||||
|
||||
foreach cell_name {NOR2_X2 NOR2_X4 NOR3_X1 NOR4_X1} {
|
||||
set cell [get_lib_cells NangateOpenCellLibrary/$cell_name]
|
||||
if { $cell == "" } {
|
||||
puts "FAIL: $cell_name not found"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# AND cells
|
||||
############################################################
|
||||
|
||||
set and2 [get_lib_cells NangateOpenCellLibrary/AND2_X1]
|
||||
if { $and2 == "" } {
|
||||
puts "FAIL: AND2_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/AND2_X1
|
||||
|
||||
foreach cell_name {AND2_X2 AND2_X4 AND3_X1 AND4_X1} {
|
||||
set cell [get_lib_cells NangateOpenCellLibrary/$cell_name]
|
||||
if { $cell == "" } {
|
||||
puts "FAIL: $cell_name not found"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# OR cells
|
||||
############################################################
|
||||
|
||||
set or2 [get_lib_cells NangateOpenCellLibrary/OR2_X1]
|
||||
if { $or2 == "" } {
|
||||
puts "FAIL: OR2_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/OR2_X1
|
||||
|
||||
foreach cell_name {OR2_X2 OR2_X4 OR3_X1 OR4_X1} {
|
||||
set cell [get_lib_cells NangateOpenCellLibrary/$cell_name]
|
||||
if { $cell == "" } {
|
||||
puts "FAIL: $cell_name not found"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# MUX cells
|
||||
############################################################
|
||||
|
||||
set mux [get_lib_cells NangateOpenCellLibrary/MUX2_X1]
|
||||
if { $mux == "" } {
|
||||
puts "FAIL: MUX2_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/MUX2_X1
|
||||
|
||||
############################################################
|
||||
# DFF cells
|
||||
############################################################
|
||||
|
||||
set dff [get_lib_cells NangateOpenCellLibrary/DFF_X1]
|
||||
if { $dff == "" } {
|
||||
puts "FAIL: DFF_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/DFF_X1
|
||||
|
||||
set dff_pins [get_lib_pins NangateOpenCellLibrary/DFF_X1/*]
|
||||
|
||||
# DFF with reset
|
||||
set dffr [get_lib_cells NangateOpenCellLibrary/DFFR_X1]
|
||||
if { $dffr == "" } {
|
||||
puts "FAIL: DFFR_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/DFFR_X1
|
||||
|
||||
# DFF with set
|
||||
set dffs [get_lib_cells NangateOpenCellLibrary/DFFS_X1]
|
||||
if { $dffs == "" } {
|
||||
puts "FAIL: DFFS_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/DFFS_X1
|
||||
|
||||
# DFF with reset and set
|
||||
set dffrs [get_lib_cells NangateOpenCellLibrary/DFFRS_X1]
|
||||
if { $dffrs == "" } {
|
||||
puts "FAIL: DFFRS_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/DFFRS_X1
|
||||
|
||||
############################################################
|
||||
# Latch (TLAT)
|
||||
############################################################
|
||||
|
||||
set tlat [get_lib_cells NangateOpenCellLibrary/TLAT_X1]
|
||||
if { $tlat == "" } {
|
||||
puts "FAIL: TLAT_X1 not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/TLAT_X1
|
||||
|
||||
############################################################
|
||||
# Complex cells: AOI, OAI, HA, FA
|
||||
############################################################
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/AOI21_X1
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/OAI21_X1
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/HA_X1
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/FA_X1
|
||||
|
||||
############################################################
|
||||
# get_lib_cells with pattern matching
|
||||
############################################################
|
||||
|
||||
set all_inv [get_lib_cells NangateOpenCellLibrary/INV_*]
|
||||
if { [llength $all_inv] < 6 } {
|
||||
error "expected multiple INV_* cells, found [llength $all_inv]"
|
||||
}
|
||||
|
||||
set all_buf [get_lib_cells NangateOpenCellLibrary/BUF_*]
|
||||
if { [llength $all_buf] < 6 } {
|
||||
error "expected multiple BUF_* cells, found [llength $all_buf]"
|
||||
}
|
||||
|
||||
set all_dff [get_lib_cells NangateOpenCellLibrary/DFF*]
|
||||
if { [llength $all_dff] < 4 } {
|
||||
error "expected multiple DFF* cells, found [llength $all_dff]"
|
||||
}
|
||||
|
||||
set all_cells [get_lib_cells NangateOpenCellLibrary/*]
|
||||
if { [llength $all_cells] < 100 } {
|
||||
error "expected full Nangate library cell list, found [llength $all_cells]"
|
||||
}
|
||||
|
||||
############################################################
|
||||
# get_lib_pins with patterns
|
||||
############################################################
|
||||
|
||||
set all_inv_pins [get_lib_pins NangateOpenCellLibrary/INV_X1/*]
|
||||
if { [llength $all_inv_pins] != 2 } {
|
||||
error "expected 2 INV_X1 pins from wildcard, found [llength $all_inv_pins]"
|
||||
}
|
||||
|
||||
set all_dff_pins [get_lib_pins NangateOpenCellLibrary/DFF_X1/*]
|
||||
if { [llength $all_dff_pins] < 4 } {
|
||||
error "expected DFF_X1 pins to include D/CK/Q(+variants), found [llength $all_dff_pins]"
|
||||
}
|
||||
|
||||
set nand_a1 [get_lib_pins NangateOpenCellLibrary/NAND2_X1/A1]
|
||||
if { [llength $nand_a1] != 1 } {
|
||||
error "expected single NAND2_X1/A1 pin match"
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Clock buffer
|
||||
############################################################
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/CLKBUF_X1
|
||||
|
||||
report_lib_cell NangateOpenCellLibrary/CLKBUF_X2
|
||||
1
liberty/test/regression
Symbolic link
1
liberty/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
liberty/test/save_ok
Symbolic link
1
liberty/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
6
network/test/CMakeLists.txt
Normal file
6
network/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("network"
|
||||
TESTS
|
||||
query
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
network/test/cpp/CMakeLists.txt
Normal file
16
network/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestNetwork TestNetwork.cc)
|
||||
target_link_libraries(TestNetwork
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestNetwork PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestNetwork
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_network"
|
||||
)
|
||||
2754
network/test/cpp/TestNetwork.cc
Normal file
2754
network/test/cpp/TestNetwork.cc
Normal file
File diff suppressed because it is too large
Load Diff
3
network/test/network_query.ok
Normal file
3
network/test/network_query.ok
Normal file
@@ -0,0 +1,3 @@
|
||||
Cells: 3
|
||||
Nets: 6
|
||||
Ports: 4
|
||||
35
network/test/network_query.tcl
Normal file
35
network/test/network_query.tcl
Normal file
@@ -0,0 +1,35 @@
|
||||
# Read design and query network objects
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
read_verilog network_test1.v
|
||||
link_design network_test1
|
||||
|
||||
# Query cells
|
||||
set cells [get_cells *]
|
||||
puts "Cells: [llength $cells]"
|
||||
if { [llength $cells] != 3 } {
|
||||
puts "FAIL: expected 3 cells"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Query nets
|
||||
set nets [get_nets *]
|
||||
puts "Nets: [llength $nets]"
|
||||
if { [llength $nets] == 0 } {
|
||||
puts "FAIL: no nets found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Query pins
|
||||
set pins [get_pins buf1/*]
|
||||
if { [llength $pins] == 0 } {
|
||||
puts "FAIL: no pins found on buf1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Query ports
|
||||
set ports [get_ports *]
|
||||
puts "Ports: [llength $ports]"
|
||||
if { [llength $ports] != 4 } {
|
||||
puts "FAIL: expected 4 ports"
|
||||
exit 1
|
||||
}
|
||||
9
network/test/network_test1.v
Normal file
9
network/test/network_test1.v
Normal file
@@ -0,0 +1,9 @@
|
||||
module network_test1 (clk, in1, in2, out1);
|
||||
input clk, in1, in2;
|
||||
output out1;
|
||||
wire n1, n2;
|
||||
|
||||
BUF_X1 buf1 (.A(in1), .Z(n1));
|
||||
AND2_X1 and1 (.A1(n1), .A2(in2), .ZN(n2));
|
||||
DFF_X1 reg1 (.D(n2), .CK(clk), .Q(out1));
|
||||
endmodule
|
||||
1
network/test/regression
Symbolic link
1
network/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
network/test/save_ok
Symbolic link
1
network/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
6
parasitics/test/CMakeLists.txt
Normal file
6
parasitics/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("parasitics"
|
||||
TESTS
|
||||
spef
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
parasitics/test/cpp/CMakeLists.txt
Normal file
16
parasitics/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestParasitics TestParasitics.cc)
|
||||
target_link_libraries(TestParasitics
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestParasitics PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestParasitics
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_parasitics"
|
||||
)
|
||||
2598
parasitics/test/cpp/TestParasitics.cc
Normal file
2598
parasitics/test/cpp/TestParasitics.cc
Normal file
File diff suppressed because it is too large
Load Diff
15
parasitics/test/parasitics_spef.ok
Normal file
15
parasitics/test/parasitics_spef.ok
Normal file
@@ -0,0 +1,15 @@
|
||||
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.
|
||||
r1q total_cap=1.3922564510505161e-14 pin_cap=5.225650124681606e-16 wire_cap=1.3399999392157882e-14
|
||||
r2q total_cap=1.3977042281540768e-14 pin_cap=5.770419894103802e-16 wire_cap=1.3400000239190829e-14
|
||||
u1z total_cap=1.3965708133673559e-14 pin_cap=5.65708000361848e-16 wire_cap=1.3400000239190829e-14
|
||||
u2z total_cap=1.4021215896773027e-14 pin_cap=6.212170340107377e-16 wire_cap=1.3399998545124935e-14
|
||||
No paths found.
|
||||
29
parasitics/test/parasitics_spef.tcl
Normal file
29
parasitics/test/parasitics_spef.tcl
Normal file
@@ -0,0 +1,29 @@
|
||||
# Test SPEF read and parasitics reporting
|
||||
# reg1_asap7 uses ASAP7 cells
|
||||
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
|
||||
|
||||
create_clock -name clk1 -period 10 [get_ports clk1]
|
||||
|
||||
# Read SPEF
|
||||
read_spef ../../test/reg1_asap7.spef
|
||||
|
||||
set corner [sta::cmd_scene]
|
||||
foreach net_name {r1q r2q u1z u2z} {
|
||||
set net [get_nets $net_name]
|
||||
set total_cap [$net capacitance $corner "max"]
|
||||
set pin_cap [$net pin_capacitance $corner "max"]
|
||||
set wire_cap [$net wire_capacitance $corner "max"]
|
||||
puts "$net_name total_cap=$total_cap pin_cap=$pin_cap wire_cap=$wire_cap"
|
||||
if {$total_cap <= 0.0} {
|
||||
error "expected positive capacitance on net $net_name after SPEF read"
|
||||
}
|
||||
}
|
||||
|
||||
report_checks -fields {slew cap input_pins fanout}
|
||||
1
parasitics/test/regression
Symbolic link
1
parasitics/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
parasitics/test/save_ok
Symbolic link
1
parasitics/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
6
power/test/CMakeLists.txt
Normal file
6
power/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("power"
|
||||
TESTS
|
||||
report
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
power/test/cpp/CMakeLists.txt
Normal file
16
power/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestPower TestPower.cc)
|
||||
target_link_libraries(TestPower
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestPower PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestPower
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_power"
|
||||
)
|
||||
1497
power/test/cpp/TestPower.cc
Normal file
1497
power/test/cpp/TestPower.cc
Normal file
File diff suppressed because it is too large
Load Diff
0
power/test/power_report.ok
Normal file
0
power/test/power_report.ok
Normal file
27
power/test/power_report.tcl
Normal file
27
power/test/power_report.tcl
Normal file
@@ -0,0 +1,27 @@
|
||||
# Test power reporting
|
||||
read_liberty ../../test/sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib
|
||||
read_verilog power_test1.v
|
||||
link_design power_test1
|
||||
|
||||
create_clock -name clk -period 10 [get_ports clk]
|
||||
set_input_delay -clock clk 0 [get_ports in1]
|
||||
set_output_delay -clock clk 0 [get_ports out1]
|
||||
set_input_transition 0.1 [get_ports in1]
|
||||
|
||||
set_power_activity -global -activity 0.5 -duty 0.5
|
||||
|
||||
# Report power with explicit checks on returned content.
|
||||
with_output_to_variable pwr_default { report_power }
|
||||
if {![regexp {Total} $pwr_default]} {
|
||||
error "report_power output missing Total section"
|
||||
}
|
||||
|
||||
with_output_to_variable pwr_inst { report_power -instances [get_cells reg1] }
|
||||
if {![regexp {reg1} $pwr_inst]} {
|
||||
error "instance power report missing reg1 entry"
|
||||
}
|
||||
|
||||
with_output_to_variable pwr_json { report_power -format json }
|
||||
if {![regexp {"Total"} $pwr_json]} {
|
||||
error "json power report missing Total field"
|
||||
}
|
||||
8
power/test/power_test1.v
Normal file
8
power/test/power_test1.v
Normal file
@@ -0,0 +1,8 @@
|
||||
module power_test1 (clk, in1, out1);
|
||||
input clk, in1;
|
||||
output out1;
|
||||
wire n1;
|
||||
|
||||
sky130_fd_sc_hd__buf_1 buf1 (.A(in1), .X(n1));
|
||||
sky130_fd_sc_hd__dfxtp_1 reg1 (.D(n1), .CLK(clk), .Q(out1));
|
||||
endmodule
|
||||
1
power/test/regression
Symbolic link
1
power/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
power/test/save_ok
Symbolic link
1
power/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
6
sdc/test/CMakeLists.txt
Normal file
6
sdc/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("sdc"
|
||||
TESTS
|
||||
clocks
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
sdc/test/cpp/CMakeLists.txt
Normal file
16
sdc/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestSdcClasses TestSdcClasses.cc)
|
||||
target_link_libraries(TestSdcClasses
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestSdcClasses PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestSdcClasses
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_sdc"
|
||||
)
|
||||
4911
sdc/test/cpp/TestSdcClasses.cc
Normal file
4911
sdc/test/cpp/TestSdcClasses.cc
Normal file
File diff suppressed because it is too large
Load Diff
1
sdc/test/regression
Symbolic link
1
sdc/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
sdc/test/save_ok
Symbolic link
1
sdc/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
22
sdc/test/sdc_clocks.ok
Normal file
22
sdc/test/sdc_clocks.ok
Normal file
@@ -0,0 +1,22 @@
|
||||
Clock Period Waveform
|
||||
----------------------------------------------------
|
||||
clk1 10.00 0.00 5.00
|
||||
clk2 20.00 0.00 10.00
|
||||
vclk 5.00 0.00 2.50
|
||||
clk1_fast 5.00 0.00 2.50
|
||||
Warning 1061: generated clock gen_clk_div2 pin clk1 is in the fanout of multiple clocks.
|
||||
Clock Period Waveform
|
||||
----------------------------------------------------
|
||||
clk1 10.00 0.00 5.00
|
||||
clk2 20.00 0.00 10.00
|
||||
vclk 5.00 0.00 2.50
|
||||
clk1_fast 5.00 0.00 2.50
|
||||
gen_clk_div2 10.00 0.00 5.00 (generated)
|
||||
gen_clk_mul3 6.67 0.00 3.33 (generated)
|
||||
Warning 415: sdc_clocks.tcl line 1, set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock.
|
||||
No paths found.
|
||||
Clock Period Waveform
|
||||
----------------------------------------------------
|
||||
clk1 10.00 0.00 5.00
|
||||
clk2 20.00 0.00 10.00
|
||||
clk1_fast 5.00 0.00 2.50
|
||||
142
sdc/test/sdc_clocks.tcl
Normal file
142
sdc/test/sdc_clocks.tcl
Normal file
@@ -0,0 +1,142 @@
|
||||
# Test comprehensive clock SDC commands for code coverage
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
read_verilog sdc_test2.v
|
||||
link_design sdc_test2
|
||||
|
||||
############################################################
|
||||
# create_clock with various options
|
||||
############################################################
|
||||
|
||||
# Basic clock
|
||||
create_clock -name clk1 -period 10 [get_ports clk1]
|
||||
|
||||
# Clock with waveform
|
||||
create_clock -name clk2 -period 20 -waveform {0 10} [get_ports clk2]
|
||||
|
||||
# Virtual clock (no port)
|
||||
create_clock -name vclk -period 5
|
||||
|
||||
# Clock with -add on same port (additional clock definition)
|
||||
create_clock -name clk1_fast -period 5 -add [get_ports clk1]
|
||||
|
||||
# Report clock properties
|
||||
report_clock_properties
|
||||
|
||||
############################################################
|
||||
# create_generated_clock
|
||||
############################################################
|
||||
|
||||
create_generated_clock -name gen_clk_div2 -source [get_ports clk1] -divide_by 2 [get_pins reg1/Q]
|
||||
|
||||
create_generated_clock -name gen_clk_mul3 -source [get_ports clk2] -multiply_by 3 [get_pins reg3/Q]
|
||||
|
||||
report_clock_properties
|
||||
|
||||
############################################################
|
||||
# set_clock_latency
|
||||
############################################################
|
||||
|
||||
# Source latency with rise/fall min/max
|
||||
set_clock_latency -source 0.5 [get_clocks clk1]
|
||||
|
||||
set_clock_latency -source -rise -max 0.6 [get_clocks clk1]
|
||||
|
||||
set_clock_latency -source -fall -min 0.3 [get_clocks clk1]
|
||||
|
||||
# Network latency
|
||||
set_clock_latency 0.2 [get_clocks clk2]
|
||||
|
||||
set_clock_latency -rise -max 0.4 [get_clocks clk2]
|
||||
|
||||
set_clock_latency -fall -min 0.1 [get_clocks clk2]
|
||||
|
||||
############################################################
|
||||
# set_clock_uncertainty
|
||||
############################################################
|
||||
|
||||
# Simple clock uncertainty
|
||||
set_clock_uncertainty -setup 0.2 [get_clocks clk1]
|
||||
|
||||
set_clock_uncertainty -hold 0.1 [get_clocks clk1]
|
||||
|
||||
# Inter-clock uncertainty
|
||||
set_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -setup 0.3
|
||||
|
||||
set_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -hold 0.15
|
||||
|
||||
############################################################
|
||||
# set_clock_transition
|
||||
############################################################
|
||||
|
||||
set_clock_transition -rise -max 0.15 [get_clocks clk1]
|
||||
|
||||
set_clock_transition -fall -min 0.08 [get_clocks clk1]
|
||||
|
||||
set_clock_transition 0.1 [get_clocks clk2]
|
||||
|
||||
############################################################
|
||||
# set_propagated_clock
|
||||
############################################################
|
||||
|
||||
set_propagated_clock [get_clocks clk1]
|
||||
|
||||
############################################################
|
||||
# set_clock_groups
|
||||
############################################################
|
||||
|
||||
set_clock_groups -logically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
|
||||
# Remove and re-add as physically exclusive
|
||||
unset_clock_groups -logically_exclusive -all
|
||||
|
||||
set_clock_groups -physically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
|
||||
unset_clock_groups -physically_exclusive -all
|
||||
|
||||
set_clock_groups -asynchronous -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
|
||||
unset_clock_groups -asynchronous -all
|
||||
|
||||
############################################################
|
||||
# set_clock_sense
|
||||
############################################################
|
||||
|
||||
set_clock_sense -positive -clocks [get_clocks clk1] [get_pins buf1/Z]
|
||||
|
||||
############################################################
|
||||
# report_checks to verify constraint effects
|
||||
############################################################
|
||||
|
||||
report_checks -from [get_ports in1] -to [get_ports out1]
|
||||
|
||||
############################################################
|
||||
# Unset/cleanup operations
|
||||
############################################################
|
||||
|
||||
unset_propagated_clock [get_clocks clk1]
|
||||
|
||||
unset_clock_latency [get_clocks clk1]
|
||||
|
||||
unset_clock_latency [get_clocks clk2]
|
||||
|
||||
unset_clock_latency -source [get_clocks clk1]
|
||||
|
||||
unset_clock_transition [get_clocks clk1]
|
||||
|
||||
unset_clock_uncertainty -setup [get_clocks clk1]
|
||||
|
||||
unset_clock_uncertainty -hold [get_clocks clk1]
|
||||
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -setup
|
||||
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -hold
|
||||
|
||||
# Delete generated clocks
|
||||
delete_generated_clock [get_clocks gen_clk_div2]
|
||||
|
||||
delete_generated_clock [get_clocks gen_clk_mul3]
|
||||
|
||||
# Delete regular clocks
|
||||
delete_clock [get_clocks vclk]
|
||||
|
||||
report_clock_properties
|
||||
16
sdc/test/sdc_test2.v
Normal file
16
sdc/test/sdc_test2.v
Normal file
@@ -0,0 +1,16 @@
|
||||
module sdc_test2 (clk1, clk2, in1, in2, in3, out1, out2);
|
||||
input clk1, clk2, in1, in2, in3;
|
||||
output out1, out2;
|
||||
wire n1, n2, n3, n4, n5, n6, n7;
|
||||
|
||||
BUF_X1 buf1 (.A(in1), .Z(n1));
|
||||
INV_X1 inv1 (.A(in2), .ZN(n2));
|
||||
AND2_X1 and1 (.A1(n1), .A2(n2), .ZN(n3));
|
||||
OR2_X1 or1 (.A1(n1), .A2(in3), .ZN(n4));
|
||||
NAND2_X1 nand1 (.A1(n3), .A2(n4), .ZN(n5));
|
||||
NOR2_X1 nor1 (.A1(n3), .A2(n4), .ZN(n6));
|
||||
|
||||
DFF_X1 reg1 (.D(n5), .CK(clk1), .Q(n7));
|
||||
DFF_X1 reg2 (.D(n6), .CK(clk1), .Q(out1));
|
||||
DFF_X1 reg3 (.D(n7), .CK(clk2), .Q(out2));
|
||||
endmodule
|
||||
6
sdf/test/CMakeLists.txt
Normal file
6
sdf/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("sdf"
|
||||
TESTS
|
||||
annotation
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
sdf/test/cpp/CMakeLists.txt
Normal file
16
sdf/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestSdf TestSdf.cc)
|
||||
target_link_libraries(TestSdf
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestSdf PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestSdf
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_sdf"
|
||||
)
|
||||
1699
sdf/test/cpp/TestSdf.cc
Normal file
1699
sdf/test/cpp/TestSdf.cc
Normal file
File diff suppressed because it is too large
Load Diff
1
sdf/test/regression
Symbolic link
1
sdf/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
sdf/test/save_ok
Symbolic link
1
sdf/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
255
sdf/test/sdf_annotation.ok
Normal file
255
sdf/test/sdf_annotation.ok
Normal file
@@ -0,0 +1,255 @@
|
||||
--- read_sdf ---
|
||||
--- report_annotated_delay (all) ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell arcs 3 2 1
|
||||
internal net arcs 1 0 1
|
||||
net arcs from primary inputs 2 0 2
|
||||
net arcs to primary outputs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
7 2 5
|
||||
--- report_annotated_delay -cell ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell arcs 3 2 1
|
||||
----------------------------------------------------------------
|
||||
3 2 1
|
||||
--- report_annotated_delay -net ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
internal net arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
--- report_annotated_delay -from_in_ports ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
net arcs from primary inputs 2 0 2
|
||||
----------------------------------------------------------------
|
||||
2 0 2
|
||||
--- report_annotated_delay -to_out_ports ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
net arcs to primary outputs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
--- report_annotated_delay -cell -report_annotated ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell arcs 3 2 1
|
||||
----------------------------------------------------------------
|
||||
3 2 1
|
||||
|
||||
Annotated Arcs
|
||||
delay buf1/A -> buf1/Z
|
||||
delay reg1/CK -> reg1/Q
|
||||
--- report_annotated_delay -cell -report_unannotated ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell arcs 3 2 1
|
||||
----------------------------------------------------------------
|
||||
3 2 1
|
||||
|
||||
Unannotated Arcs
|
||||
delay reg1/CK -> reg1/QN
|
||||
--- report_annotated_delay -constant_arcs ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell arcs 3 2 1
|
||||
constant arcs 0 0
|
||||
internal net arcs 1 0 1
|
||||
constant arcs 0 0
|
||||
net arcs from primary inputs 2 0 2
|
||||
constant arcs 0 0
|
||||
net arcs to primary outputs 1 0 1
|
||||
constant arcs 0 0
|
||||
----------------------------------------------------------------
|
||||
7 2 5
|
||||
--- report_annotated_delay -max_lines 5 ---
|
||||
Not
|
||||
Delay type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell arcs 3 2 1
|
||||
internal net arcs 1 0 1
|
||||
net arcs from primary inputs 2 0 2
|
||||
net arcs to primary outputs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
7 2 5
|
||||
--- report_annotated_check (all) ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell setup arcs 1 0 1
|
||||
cell hold arcs 1 0 1
|
||||
cell width arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
3 0 3
|
||||
--- report_annotated_check -setup ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell setup arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
--- report_annotated_check -hold ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell hold arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
--- report_annotated_check -recovery ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
0 0 0
|
||||
--- report_annotated_check -removal ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
0 0 0
|
||||
--- report_annotated_check -width ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell width arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
--- report_annotated_check -period ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
0 0 0
|
||||
--- report_annotated_check -setup -report_annotated ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell setup arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
|
||||
Annotated Arcs
|
||||
--- report_annotated_check -setup -report_unannotated ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell setup arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
1 0 1
|
||||
|
||||
Unannotated Arcs
|
||||
setup reg1/CK -> reg1/D
|
||||
--- report_annotated_check -constant_arcs ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell setup arcs 1 0 1
|
||||
constant arcs 0 0
|
||||
cell hold arcs 1 0 1
|
||||
constant arcs 0 0
|
||||
cell width arcs 1 0 1
|
||||
constant arcs 0 0
|
||||
----------------------------------------------------------------
|
||||
3 0 3
|
||||
--- report_annotated_check -max_lines 5 ---
|
||||
Not
|
||||
Check type Total Annotated Annotated
|
||||
----------------------------------------------------------------
|
||||
cell setup arcs 1 0 1
|
||||
cell hold arcs 1 0 1
|
||||
cell width arcs 1 0 1
|
||||
----------------------------------------------------------------
|
||||
3 0 3
|
||||
--- report_checks (shows annotated delays) ---
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: q (output port 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 ^ reg1/CK (DFF_X1)
|
||||
0.40 0.40 ^ reg1/Q (DFF_X1)
|
||||
0.00 0.40 ^ q (out)
|
||||
0.40 data arrival time
|
||||
|
||||
10.00 10.00 clock clk (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
0.00 10.00 output external delay
|
||||
10.00 data required time
|
||||
---------------------------------------------------------
|
||||
10.00 data required time
|
||||
-0.40 data arrival time
|
||||
---------------------------------------------------------
|
||||
9.60 slack (MET)
|
||||
|
||||
|
||||
--- report_checks -format full_clock ---
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: q (output port 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 ^ reg1/CK (DFF_X1)
|
||||
0.40 0.40 ^ reg1/Q (DFF_X1)
|
||||
0.00 0.40 ^ q (out)
|
||||
0.40 data arrival time
|
||||
|
||||
10.00 10.00 clock clk (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
0.00 10.00 output external delay
|
||||
10.00 data required time
|
||||
---------------------------------------------------------
|
||||
10.00 data required time
|
||||
-0.40 data arrival time
|
||||
---------------------------------------------------------
|
||||
9.60 slack (MET)
|
||||
|
||||
|
||||
--- report_checks -path_delay min ---
|
||||
Startpoint: d (input port clocked by clk)
|
||||
Endpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: min
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 ^ input external delay
|
||||
0.00 0.00 ^ d (in)
|
||||
0.10 0.10 ^ buf1/Z (BUF_X1)
|
||||
0.00 0.10 ^ reg1/D (DFF_X1)
|
||||
0.10 data arrival time
|
||||
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 clock reconvergence pessimism
|
||||
0.00 ^ reg1/CK (DFF_X1)
|
||||
0.00 0.00 library hold time
|
||||
0.00 data required time
|
||||
---------------------------------------------------------
|
||||
0.00 data required time
|
||||
-0.10 data arrival time
|
||||
---------------------------------------------------------
|
||||
0.10 slack (MET)
|
||||
|
||||
|
||||
80
sdf/test/sdf_annotation.tcl
Normal file
80
sdf/test/sdf_annotation.tcl
Normal file
@@ -0,0 +1,80 @@
|
||||
# Test SDF annotation and reporting commands
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
read_verilog sdf_test1.v
|
||||
link_design sdf_test1
|
||||
|
||||
create_clock -name clk -period 10 [get_ports clk]
|
||||
set_input_delay -clock clk 0 [get_ports d]
|
||||
set_output_delay -clock clk 0 [get_ports q]
|
||||
|
||||
puts "--- read_sdf ---"
|
||||
read_sdf sdf_test1.sdf
|
||||
|
||||
puts "--- report_annotated_delay (all) ---"
|
||||
report_annotated_delay
|
||||
|
||||
puts "--- report_annotated_delay -cell ---"
|
||||
report_annotated_delay -cell
|
||||
|
||||
puts "--- report_annotated_delay -net ---"
|
||||
report_annotated_delay -net
|
||||
|
||||
puts "--- report_annotated_delay -from_in_ports ---"
|
||||
report_annotated_delay -from_in_ports
|
||||
|
||||
puts "--- report_annotated_delay -to_out_ports ---"
|
||||
report_annotated_delay -to_out_ports
|
||||
|
||||
puts "--- report_annotated_delay -cell -report_annotated ---"
|
||||
report_annotated_delay -cell -report_annotated
|
||||
|
||||
puts "--- report_annotated_delay -cell -report_unannotated ---"
|
||||
report_annotated_delay -cell -report_unannotated
|
||||
|
||||
puts "--- report_annotated_delay -constant_arcs ---"
|
||||
report_annotated_delay -constant_arcs
|
||||
|
||||
puts "--- report_annotated_delay -max_lines 5 ---"
|
||||
report_annotated_delay -max_lines 5
|
||||
|
||||
puts "--- report_annotated_check (all) ---"
|
||||
report_annotated_check
|
||||
|
||||
puts "--- report_annotated_check -setup ---"
|
||||
report_annotated_check -setup
|
||||
|
||||
puts "--- report_annotated_check -hold ---"
|
||||
report_annotated_check -hold
|
||||
|
||||
puts "--- report_annotated_check -recovery ---"
|
||||
report_annotated_check -recovery
|
||||
|
||||
puts "--- report_annotated_check -removal ---"
|
||||
report_annotated_check -removal
|
||||
|
||||
puts "--- report_annotated_check -width ---"
|
||||
report_annotated_check -width
|
||||
|
||||
puts "--- report_annotated_check -period ---"
|
||||
report_annotated_check -period
|
||||
|
||||
puts "--- report_annotated_check -setup -report_annotated ---"
|
||||
report_annotated_check -setup -report_annotated
|
||||
|
||||
puts "--- report_annotated_check -setup -report_unannotated ---"
|
||||
report_annotated_check -setup -report_unannotated
|
||||
|
||||
puts "--- report_annotated_check -constant_arcs ---"
|
||||
report_annotated_check -constant_arcs
|
||||
|
||||
puts "--- report_annotated_check -max_lines 5 ---"
|
||||
report_annotated_check -max_lines 5
|
||||
|
||||
puts "--- report_checks (shows annotated delays) ---"
|
||||
report_checks
|
||||
|
||||
puts "--- report_checks -format full_clock ---"
|
||||
report_checks -format full_clock
|
||||
|
||||
puts "--- report_checks -path_delay min ---"
|
||||
report_checks -path_delay min
|
||||
23
sdf/test/sdf_test1.sdf
Normal file
23
sdf/test/sdf_test1.sdf
Normal file
@@ -0,0 +1,23 @@
|
||||
(DELAYFILE
|
||||
(SDFVERSION "3.0")
|
||||
(DESIGN "sdf_test1")
|
||||
(TIMESCALE 1ns)
|
||||
(CELL
|
||||
(CELLTYPE "BUF_X1")
|
||||
(INSTANCE buf1)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH A Z (0.1:0.2:0.3) (0.1:0.2:0.3))
|
||||
)
|
||||
)
|
||||
)
|
||||
(CELL
|
||||
(CELLTYPE "DFF_X1")
|
||||
(INSTANCE reg1)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH CK Q (0.2:0.3:0.4) (0.2:0.3:0.4))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
8
sdf/test/sdf_test1.v
Normal file
8
sdf/test/sdf_test1.v
Normal file
@@ -0,0 +1,8 @@
|
||||
module sdf_test1 (clk, d, q);
|
||||
input clk, d;
|
||||
output q;
|
||||
wire n1;
|
||||
|
||||
BUF_X1 buf1 (.A(d), .Z(n1));
|
||||
DFF_X1 reg1 (.D(n1), .CK(clk), .Q(q));
|
||||
endmodule
|
||||
6
search/test/CMakeLists.txt
Normal file
6
search/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("search"
|
||||
TESTS
|
||||
timing
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
16
search/test/cpp/CMakeLists.txt
Normal file
16
search/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_executable(TestSearchClasses TestSearchClasses.cc)
|
||||
target_link_libraries(TestSearchClasses
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestSearchClasses PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestSearchClasses
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_search"
|
||||
)
|
||||
1824
search/test/cpp/TestSearchClasses.cc
Normal file
1824
search/test/cpp/TestSearchClasses.cc
Normal file
File diff suppressed because it is too large
Load Diff
1
search/test/regression
Symbolic link
1
search/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
search/test/save_ok
Symbolic link
1
search/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
10
search/test/search_test1.v
Normal file
10
search/test/search_test1.v
Normal file
@@ -0,0 +1,10 @@
|
||||
module search_test1 (clk, in1, in2, out1);
|
||||
input clk, in1, in2;
|
||||
output out1;
|
||||
wire n1, n2, n3;
|
||||
|
||||
AND2_X1 and1 (.A1(in1), .A2(in2), .ZN(n1));
|
||||
BUF_X1 buf1 (.A(n1), .Z(n2));
|
||||
DFF_X1 reg1 (.D(n2), .CK(clk), .Q(n3));
|
||||
BUF_X1 buf2 (.A(n3), .Z(out1));
|
||||
endmodule
|
||||
57
search/test/search_timing.ok
Normal file
57
search/test/search_timing.ok
Normal file
@@ -0,0 +1,57 @@
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: out1 (output port 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 ^ reg1/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg1/Q (DFF_X1)
|
||||
0.02 0.10 ^ buf2/Z (BUF_X1)
|
||||
0.00 0.10 ^ out1 (out)
|
||||
0.10 data arrival time
|
||||
|
||||
10.00 10.00 clock clk (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
-2.00 8.00 output external delay
|
||||
8.00 data required time
|
||||
---------------------------------------------------------
|
||||
8.00 data required time
|
||||
-0.10 data arrival time
|
||||
---------------------------------------------------------
|
||||
7.90 slack (MET)
|
||||
|
||||
|
||||
Startpoint: in1 (input port clocked by clk)
|
||||
Endpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Path Group: clk
|
||||
Path Type: min
|
||||
|
||||
Delay Time Description
|
||||
---------------------------------------------------------
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
1.00 1.00 ^ input external delay
|
||||
0.00 1.00 ^ in1 (in)
|
||||
0.02 1.02 ^ and1/ZN (AND2_X1)
|
||||
0.02 1.04 ^ buf1/Z (BUF_X1)
|
||||
0.00 1.04 ^ reg1/D (DFF_X1)
|
||||
1.04 data arrival time
|
||||
|
||||
0.00 0.00 clock clk (rise edge)
|
||||
0.00 0.00 clock network delay (ideal)
|
||||
0.00 0.00 clock reconvergence pessimism
|
||||
0.00 ^ reg1/CK (DFF_X1)
|
||||
0.00 0.00 library hold time
|
||||
0.00 data required time
|
||||
---------------------------------------------------------
|
||||
0.00 data required time
|
||||
-1.04 data arrival time
|
||||
---------------------------------------------------------
|
||||
1.04 slack (MET)
|
||||
|
||||
|
||||
Worst slack: 7.899713772019368e-9
|
||||
23
search/test/search_timing.tcl
Normal file
23
search/test/search_timing.tcl
Normal file
@@ -0,0 +1,23 @@
|
||||
# Full timing analysis flow test
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
read_verilog search_test1.v
|
||||
link_design search_test1
|
||||
|
||||
create_clock -name clk -period 10 [get_ports clk]
|
||||
set_input_delay -clock clk 1.0 [get_ports in1]
|
||||
set_input_delay -clock clk 1.0 [get_ports in2]
|
||||
set_output_delay -clock clk 2.0 [get_ports out1]
|
||||
|
||||
# Setup analysis
|
||||
report_checks -path_delay max
|
||||
|
||||
# Hold analysis
|
||||
report_checks -path_delay min
|
||||
|
||||
# Check worst slack
|
||||
set slack [sta::worst_slack_cmd "max"]
|
||||
puts "Worst slack: $slack"
|
||||
if { $slack == "" } {
|
||||
puts "FAIL: no slack found"
|
||||
exit 1
|
||||
}
|
||||
6
spice/test/CMakeLists.txt
Normal file
6
spice/test/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
sta_module_tests("spice"
|
||||
TESTS
|
||||
write
|
||||
)
|
||||
|
||||
add_subdirectory(cpp)
|
||||
17
spice/test/cpp/CMakeLists.txt
Normal file
17
spice/test/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
add_executable(TestSpice TestSpice.cc)
|
||||
target_link_libraries(TestSpice
|
||||
OpenSTA
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
${TCL_LIBRARY}
|
||||
)
|
||||
target_include_directories(TestSpice PRIVATE
|
||||
${STA_HOME}/include/sta
|
||||
${STA_HOME}
|
||||
${STA_HOME}/spice
|
||||
${CMAKE_BINARY_DIR}/include/sta
|
||||
)
|
||||
gtest_discover_tests(TestSpice
|
||||
WORKING_DIRECTORY ${STA_HOME}
|
||||
PROPERTIES LABELS "cpp\;module_spice"
|
||||
)
|
||||
1867
spice/test/cpp/TestSpice.cc
Normal file
1867
spice/test/cpp/TestSpice.cc
Normal file
File diff suppressed because it is too large
Load Diff
1
spice/test/regression
Symbolic link
1
spice/test/regression
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/regression
|
||||
1
spice/test/save_ok
Symbolic link
1
spice/test/save_ok
Symbolic link
@@ -0,0 +1 @@
|
||||
../../test/shared/save_ok
|
||||
8
spice/test/spice_test1.v
Normal file
8
spice/test/spice_test1.v
Normal file
@@ -0,0 +1,8 @@
|
||||
module spice_test1 (clk, in1, out1);
|
||||
input clk, in1;
|
||||
output out1;
|
||||
wire n1;
|
||||
|
||||
BUF_X1 buf1 (.A(in1), .Z(n1));
|
||||
DFF_X1 reg1 (.D(n1), .CK(clk), .Q(out1));
|
||||
endmodule
|
||||
27
spice/test/spice_write.ok
Normal file
27
spice/test/spice_write.ok
Normal file
@@ -0,0 +1,27 @@
|
||||
Startpoint: reg1 (rising edge-triggered flip-flop clocked by clk)
|
||||
Endpoint: out1 (output port 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 ^ reg1/CK (DFF_X1)
|
||||
0.08 0.08 ^ reg1/Q (DFF_X1)
|
||||
0.00 0.08 ^ out1 (out)
|
||||
0.08 data arrival time
|
||||
|
||||
10.00 10.00 clock clk (rise edge)
|
||||
0.00 10.00 clock network delay (ideal)
|
||||
0.00 10.00 clock reconvergence pessimism
|
||||
0.00 10.00 output external delay
|
||||
10.00 data required time
|
||||
---------------------------------------------------------
|
||||
10.00 data required time
|
||||
-0.08 data arrival time
|
||||
---------------------------------------------------------
|
||||
9.92 slack (MET)
|
||||
|
||||
|
||||
No differences found.
|
||||
59
spice/test/spice_write.spok
Normal file
59
spice/test/spice_write.spok
Normal file
@@ -0,0 +1,59 @@
|
||||
* Path from reg1/Q ^ to out1 ^
|
||||
.include "/workspace/sta/OpenSTA/spice/test/results/spice_out/mock_model.sp"
|
||||
.include "path_1.subckt"
|
||||
.tran 1e-13 3.1e-08
|
||||
|
||||
.print tran v(clk) v(reg1/CK) v(reg1/Q) v(out1)
|
||||
|
||||
**************
|
||||
* Input source
|
||||
**************
|
||||
|
||||
v1 clk 0 pwl(
|
||||
+0.000e+00 0.000e+00
|
||||
+9.985e-10 0.000e+00
|
||||
+1.001e-09 1.100e+00
|
||||
+5.999e-09 1.100e+00
|
||||
+6.001e-09 0.000e+00
|
||||
+1.100e-08 0.000e+00
|
||||
+1.100e-08 1.100e+00
|
||||
+1.600e-08 1.100e+00
|
||||
+1.600e-08 0.000e+00
|
||||
+2.100e-08 0.000e+00
|
||||
+2.100e-08 1.100e+00
|
||||
+2.600e-08 1.100e+00
|
||||
+2.600e-08 0.000e+00
|
||||
+3.100e-08 0.000e+00
|
||||
+)
|
||||
|
||||
*****************
|
||||
* Stage instances
|
||||
*****************
|
||||
|
||||
xstage1 clk reg1/CK stage1
|
||||
xstage2 reg1/CK reg1/Q out1 stage2
|
||||
|
||||
***************
|
||||
* Stage subckts
|
||||
***************
|
||||
|
||||
.subckt stage1 clk reg1/CK
|
||||
* Net clk
|
||||
* Net has no parasitics.
|
||||
R1 clk reg1/CK 1.000e-04
|
||||
.ends
|
||||
|
||||
.subckt stage2 reg1/CK reg1/Q out1
|
||||
* Gate reg1 CK -> Q
|
||||
xreg1 reg1/D reg1/CK reg1/Q reg1/VDD reg1/VSS DFF_X1
|
||||
v1 reg1/D 0 1.100
|
||||
v2 reg1/VDD 0 1.100
|
||||
v3 reg1/VSS 0 0.000
|
||||
|
||||
* Load pins
|
||||
* Net out1
|
||||
* Net has no parasitics.
|
||||
R1 reg1/Q out1 1.000e-04
|
||||
.ends
|
||||
|
||||
.end
|
||||
50
spice/test/spice_write.tcl
Normal file
50
spice/test/spice_write.tcl
Normal file
@@ -0,0 +1,50 @@
|
||||
# Test spice-related functionality
|
||||
source ../../test/helpers.tcl
|
||||
set test_name spice_write
|
||||
|
||||
read_liberty ../../test/nangate45/Nangate45_typ.lib
|
||||
read_verilog spice_test1.v
|
||||
link_design spice_test1
|
||||
|
||||
create_clock -name clk -period 10 [get_ports clk]
|
||||
set_input_delay -clock clk 0 [get_ports in1]
|
||||
set_output_delay -clock clk 0 [get_ports out1]
|
||||
|
||||
# Run timing analysis (needed before write_path_spice)
|
||||
report_checks
|
||||
|
||||
# Create mock SPICE model and subckt files for write_path_spice
|
||||
set spice_dir [make_result_file spice_out]
|
||||
file mkdir $spice_dir
|
||||
|
||||
set model_file [file join $spice_dir mock_model.sp]
|
||||
set model_fh [open $model_file w]
|
||||
puts $model_fh "* Mock SPICE model file"
|
||||
puts $model_fh ".model nmos nmos level=1"
|
||||
puts $model_fh ".model pmos pmos level=1"
|
||||
close $model_fh
|
||||
|
||||
set subckt_file [file join $spice_dir mock_subckt.sp]
|
||||
set subckt_fh [open $subckt_file w]
|
||||
puts $subckt_fh "* Mock SPICE subckt file"
|
||||
puts $subckt_fh ".subckt BUF_X1 A Z VDD VSS"
|
||||
puts $subckt_fh "M1 Z A VDD VDD pmos W=1u L=100n"
|
||||
puts $subckt_fh "M2 Z A VSS VSS nmos W=1u L=100n"
|
||||
puts $subckt_fh ".ends"
|
||||
puts $subckt_fh ""
|
||||
puts $subckt_fh ".subckt DFF_X1 D CK Q VDD VSS"
|
||||
puts $subckt_fh "M1 Q D VDD VDD pmos W=1u L=100n"
|
||||
puts $subckt_fh "M2 Q D VSS VSS nmos W=1u L=100n"
|
||||
puts $subckt_fh ".ends"
|
||||
close $subckt_fh
|
||||
|
||||
# write_path_spice - exercises the Tcl command parsing and
|
||||
# C++ WritePathSpice code paths.
|
||||
write_path_spice \
|
||||
-path_args {-sort_by_slack} \
|
||||
-spice_directory $spice_dir \
|
||||
-lib_subckt_file $subckt_file \
|
||||
-model_file $model_file \
|
||||
-power VDD \
|
||||
-ground VSS
|
||||
diff_files $test_name.spok [file join $spice_dir path_1.sp] "mock_model.sp"
|
||||
38
test/CMakeLists.txt
Normal file
38
test/CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
# Register existing upstream Tcl tests for ctest coverage
|
||||
set(STA_EXE $<TARGET_FILE:sta>)
|
||||
set(TEST_DIR ${STA_HOME}/test)
|
||||
set(EXAMPLES_DIR ${STA_HOME}/examples)
|
||||
|
||||
function(sta_tcl_test test_name)
|
||||
add_test(
|
||||
NAME tcl.${test_name}
|
||||
COMMAND ${STA_EXE} -no_init -no_splash -exit ${TEST_DIR}/${test_name}.tcl
|
||||
WORKING_DIRECTORY ${TEST_DIR}
|
||||
)
|
||||
set_tests_properties(tcl.${test_name} PROPERTIES LABELS "tcl")
|
||||
endfunction()
|
||||
|
||||
function(sta_example_test test_name)
|
||||
add_test(
|
||||
NAME tcl.example.${test_name}
|
||||
COMMAND ${STA_EXE} -no_init -no_splash -exit ${EXAMPLES_DIR}/${test_name}.tcl
|
||||
WORKING_DIRECTORY ${EXAMPLES_DIR}
|
||||
)
|
||||
set_tests_properties(tcl.example.${test_name} PROPERTIES LABELS "tcl;example")
|
||||
endfunction()
|
||||
|
||||
# Auto-detect public tests: register all *.ok files that have a matching *.tcl
|
||||
file(GLOB ok_files "${TEST_DIR}/*.ok")
|
||||
foreach(ok_file ${ok_files})
|
||||
get_filename_component(test_name ${ok_file} NAME_WE)
|
||||
if(EXISTS "${TEST_DIR}/${test_name}.tcl")
|
||||
sta_tcl_test(${test_name})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Auto-detect example tests: register all *.tcl files in examples/
|
||||
file(GLOB example_tcl_files "${EXAMPLES_DIR}/*.tcl")
|
||||
foreach(tcl_file ${example_tcl_files})
|
||||
get_filename_component(test_name ${tcl_file} NAME_WE)
|
||||
sta_example_test(${test_name})
|
||||
endforeach()
|
||||
BIN
test/asap7/asap7sc7p5t_AO_LVT_FF_nldm_211120.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_AO_LVT_FF_nldm_211120.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_AO_RVT_SS_nldm_211120.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_AO_RVT_SS_nldm_211120.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_AO_SLVT_FF_nldm_211120.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_AO_SLVT_FF_nldm_211120.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_LVT_FF_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_LVT_FF_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_LVT_TT_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_LVT_TT_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_RVT_SS_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_RVT_SS_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_RVT_TT_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_RVT_TT_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_SLVT_FF_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_SLVT_FF_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_INVBUF_SLVT_TT_nldm_220122.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_INVBUF_SLVT_TT_nldm_220122.lib.gz
Normal file
Binary file not shown.
BIN
test/asap7/asap7sc7p5t_OA_LVT_FF_nldm_211120.lib.gz
Normal file
BIN
test/asap7/asap7sc7p5t_OA_LVT_FF_nldm_211120.lib.gz
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user