1129 lines
31 KiB
C++
1129 lines
31 KiB
C++
#include <gtest/gtest.h>
|
|
#include "DelayFloat.hh"
|
|
#include "MinMax.hh"
|
|
#include "Graph.hh"
|
|
#include "Transition.hh"
|
|
#include "NetworkClass.hh"
|
|
#include "LibertyClass.hh"
|
|
#include "GraphClass.hh"
|
|
|
|
namespace sta {
|
|
|
|
class DelayFloatTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
initDelayConstants();
|
|
}
|
|
};
|
|
|
|
TEST_F(DelayFloatTest, DelayZero) {
|
|
EXPECT_TRUE(delayZero(0.0f));
|
|
EXPECT_TRUE(delayZero(delay_zero));
|
|
EXPECT_FALSE(delayZero(1.0f));
|
|
EXPECT_FALSE(delayZero(-1.0f));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayEqual) {
|
|
EXPECT_TRUE(delayEqual(1.0f, 1.0f));
|
|
EXPECT_TRUE(delayEqual(0.0f, 0.0f));
|
|
EXPECT_FALSE(delayEqual(1.0f, 2.0f));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayInf) {
|
|
// delayInf checks against STA's INF constant, not IEEE infinity
|
|
EXPECT_TRUE(delayInf(INF));
|
|
EXPECT_TRUE(delayInf(-INF));
|
|
EXPECT_FALSE(delayInf(0.0f));
|
|
EXPECT_FALSE(delayInf(1e10f));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayLess) {
|
|
EXPECT_TRUE(delayLess(1.0f, 2.0f, nullptr));
|
|
EXPECT_FALSE(delayLess(2.0f, 1.0f, nullptr));
|
|
EXPECT_FALSE(delayLess(1.0f, 1.0f, nullptr));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayRemove) {
|
|
Delay d1 = 5.0f;
|
|
Delay d2 = 3.0f;
|
|
Delay result = delayRemove(d1, d2);
|
|
EXPECT_FLOAT_EQ(result, 2.0f);
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayRatio) {
|
|
EXPECT_FLOAT_EQ(delayRatio(6.0f, 3.0f), 2.0f);
|
|
EXPECT_FLOAT_EQ(delayRatio(0.0f, 1.0f), 0.0f);
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayInitValueMin) {
|
|
const Delay &init = delayInitValue(MinMax::min());
|
|
// Min init value should be a large positive number
|
|
EXPECT_GT(init, 0.0f);
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayInitValueMax) {
|
|
const Delay &init = delayInitValue(MinMax::max());
|
|
// Max init value should be a large negative number
|
|
EXPECT_LT(init, 0.0f);
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, MakeDelay) {
|
|
Delay d = makeDelay(1.5f, 0.0f, 0.0f);
|
|
EXPECT_FLOAT_EQ(d, 1.5f);
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayAsFloat) {
|
|
Delay d = 3.14f;
|
|
EXPECT_FLOAT_EQ(delayAsFloat(d), 3.14f);
|
|
}
|
|
|
|
// Additional delay tests for improved coverage
|
|
TEST_F(DelayFloatTest, DelayGreater) {
|
|
EXPECT_TRUE(delayGreater(2.0f, 1.0f, nullptr));
|
|
EXPECT_FALSE(delayGreater(1.0f, 2.0f, nullptr));
|
|
EXPECT_FALSE(delayGreater(1.0f, 1.0f, nullptr));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayLessEqual) {
|
|
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, nullptr));
|
|
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, nullptr));
|
|
EXPECT_FALSE(delayLessEqual(2.0f, 1.0f, nullptr));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayGreaterEqual) {
|
|
EXPECT_TRUE(delayGreaterEqual(2.0f, 1.0f, nullptr));
|
|
EXPECT_TRUE(delayGreaterEqual(1.0f, 1.0f, nullptr));
|
|
EXPECT_FALSE(delayGreaterEqual(1.0f, 2.0f, nullptr));
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, MakeDelayWithSigma) {
|
|
// In float mode, sigma is ignored
|
|
Delay d = makeDelay(2.5f, 0.1f, 0.2f);
|
|
EXPECT_FLOAT_EQ(d, 2.5f);
|
|
}
|
|
|
|
TEST_F(DelayFloatTest, DelayNegative) {
|
|
Delay d = -5.0f;
|
|
EXPECT_FLOAT_EQ(delayAsFloat(d), -5.0f);
|
|
EXPECT_FALSE(delayZero(d));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Vertex standalone tests (Graph.cc Vertex methods)
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Test Vertex default constructor and init
|
|
TEST(VertexStandaloneTest, DefaultConstructor)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.pin(), nullptr);
|
|
EXPECT_FALSE(v.isBidirectDriver());
|
|
EXPECT_EQ(v.level(), 0);
|
|
EXPECT_TRUE(v.isRoot());
|
|
EXPECT_FALSE(v.hasFanin());
|
|
EXPECT_FALSE(v.hasFanout());
|
|
EXPECT_FALSE(v.visited());
|
|
EXPECT_FALSE(v.visited2());
|
|
EXPECT_FALSE(v.isRegClk());
|
|
EXPECT_FALSE(v.isDisabledConstraint());
|
|
EXPECT_FALSE(v.hasChecks());
|
|
EXPECT_FALSE(v.isCheckClk());
|
|
EXPECT_FALSE(v.isGatedClkEnable());
|
|
EXPECT_FALSE(v.hasDownstreamClkPin());
|
|
EXPECT_FALSE(v.isConstrained());
|
|
EXPECT_FALSE(v.slewAnnotated());
|
|
}
|
|
|
|
// Test Vertex setters
|
|
TEST(VertexStandaloneTest, SetLevel)
|
|
{
|
|
Vertex v;
|
|
v.setLevel(5);
|
|
EXPECT_EQ(v.level(), 5);
|
|
EXPECT_FALSE(v.isRoot());
|
|
v.setLevel(0);
|
|
EXPECT_TRUE(v.isRoot());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetVisited)
|
|
{
|
|
Vertex v;
|
|
v.setVisited(true);
|
|
EXPECT_TRUE(v.visited());
|
|
v.setVisited(false);
|
|
EXPECT_FALSE(v.visited());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetVisited2)
|
|
{
|
|
Vertex v;
|
|
v.setVisited2(true);
|
|
EXPECT_TRUE(v.visited2());
|
|
v.setVisited2(false);
|
|
EXPECT_FALSE(v.visited2());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetIsDisabledConstraint)
|
|
{
|
|
Vertex v;
|
|
v.setIsDisabledConstraint(true);
|
|
EXPECT_TRUE(v.isDisabledConstraint());
|
|
v.setIsDisabledConstraint(false);
|
|
EXPECT_FALSE(v.isDisabledConstraint());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetHasChecks)
|
|
{
|
|
Vertex v;
|
|
v.setHasChecks(true);
|
|
EXPECT_TRUE(v.hasChecks());
|
|
v.setHasChecks(false);
|
|
EXPECT_FALSE(v.hasChecks());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetIsCheckClk)
|
|
{
|
|
Vertex v;
|
|
v.setIsCheckClk(true);
|
|
EXPECT_TRUE(v.isCheckClk());
|
|
v.setIsCheckClk(false);
|
|
EXPECT_FALSE(v.isCheckClk());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetIsGatedClkEnable)
|
|
{
|
|
Vertex v;
|
|
v.setIsGatedClkEnable(true);
|
|
EXPECT_TRUE(v.isGatedClkEnable());
|
|
v.setIsGatedClkEnable(false);
|
|
EXPECT_FALSE(v.isGatedClkEnable());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetHasDownstreamClkPin)
|
|
{
|
|
Vertex v;
|
|
v.setHasDownstreamClkPin(true);
|
|
EXPECT_TRUE(v.hasDownstreamClkPin());
|
|
v.setHasDownstreamClkPin(false);
|
|
EXPECT_FALSE(v.hasDownstreamClkPin());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SetIsConstrained)
|
|
{
|
|
Vertex v;
|
|
v.setIsConstrained(true);
|
|
EXPECT_TRUE(v.isConstrained());
|
|
v.setIsConstrained(false);
|
|
EXPECT_FALSE(v.isConstrained());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SimValue)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.simValue(), LogicValue::unknown);
|
|
EXPECT_FALSE(v.isConstant());
|
|
|
|
v.setSimValue(LogicValue::zero);
|
|
EXPECT_EQ(v.simValue(), LogicValue::zero);
|
|
EXPECT_TRUE(v.isConstant());
|
|
|
|
v.setSimValue(LogicValue::one);
|
|
EXPECT_EQ(v.simValue(), LogicValue::one);
|
|
EXPECT_TRUE(v.isConstant());
|
|
|
|
v.setSimValue(LogicValue::unknown);
|
|
EXPECT_FALSE(v.isConstant());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, TagGroupIndex)
|
|
{
|
|
Vertex v;
|
|
// Default tag group index should be max
|
|
TagGroupIndex idx = v.tagGroupIndex();
|
|
EXPECT_EQ(idx, tag_group_index_max);
|
|
|
|
v.setTagGroupIndex(42);
|
|
EXPECT_EQ(v.tagGroupIndex(), 42u);
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, BfsInQueue)
|
|
{
|
|
Vertex v;
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::dcalc));
|
|
v.setBfsInQueue(BfsIndex::dcalc, true);
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::dcalc));
|
|
v.setBfsInQueue(BfsIndex::dcalc, false);
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::dcalc));
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, TransitionCount)
|
|
{
|
|
EXPECT_EQ(Vertex::transitionCount(), 2);
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, ObjectIdx)
|
|
{
|
|
Vertex v;
|
|
v.setObjectIdx(99);
|
|
EXPECT_EQ(v.objectIdx(), 99u);
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SlewAnnotated)
|
|
{
|
|
Vertex v;
|
|
EXPECT_FALSE(v.slewAnnotated());
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::rise(), MinMax::max()));
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::fall(), MinMax::min()));
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::fall(), MinMax::max()));
|
|
|
|
v.setSlewAnnotated(true, RiseFall::rise(), 0);
|
|
EXPECT_TRUE(v.slewAnnotated());
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
|
|
v.removeSlewAnnotated();
|
|
EXPECT_FALSE(v.slewAnnotated());
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SlewAnnotatedMultiple)
|
|
{
|
|
Vertex v;
|
|
v.setSlewAnnotated(true, RiseFall::rise(), 0);
|
|
v.setSlewAnnotated(true, RiseFall::fall(), 1);
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::fall(), MinMax::max()));
|
|
|
|
v.setSlewAnnotated(false, RiseFall::rise(), 0);
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::fall(), MinMax::max()));
|
|
}
|
|
|
|
TEST(VertexStandaloneTest, SlewAnnotatedHighApIndex)
|
|
{
|
|
Vertex v;
|
|
// ap_index > 1 should map to ap_index 0
|
|
v.setSlewAnnotated(true, RiseFall::rise(), 5);
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
}
|
|
|
|
// Test Vertex paths
|
|
TEST(VertexStandaloneTest, Paths)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.paths(), nullptr);
|
|
}
|
|
|
|
// Test Vertex slews
|
|
TEST(VertexStandaloneTest, Slews)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.slews(), nullptr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Edge standalone tests (Graph.cc Edge methods)
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
TEST(EdgeStandaloneTest, DefaultConstructor)
|
|
{
|
|
Edge e;
|
|
EXPECT_EQ(e.timingArcSet(), nullptr);
|
|
EXPECT_EQ(e.arcDelays(), nullptr);
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
EXPECT_FALSE(e.isBidirectInstPath());
|
|
EXPECT_FALSE(e.isBidirectNetPath());
|
|
EXPECT_FALSE(e.isDisabledCond());
|
|
EXPECT_FALSE(e.isDisabledLoop());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetDelayAnnotationIsIncremental)
|
|
{
|
|
Edge e;
|
|
e.setDelayAnnotationIsIncremental(true);
|
|
EXPECT_TRUE(e.delay_Annotation_Is_Incremental());
|
|
e.setDelayAnnotationIsIncremental(false);
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetIsBidirectInstPath)
|
|
{
|
|
Edge e;
|
|
e.setIsBidirectInstPath(true);
|
|
EXPECT_TRUE(e.isBidirectInstPath());
|
|
e.setIsBidirectInstPath(false);
|
|
EXPECT_FALSE(e.isBidirectInstPath());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetIsBidirectNetPath)
|
|
{
|
|
Edge e;
|
|
e.setIsBidirectNetPath(true);
|
|
EXPECT_TRUE(e.isBidirectNetPath());
|
|
e.setIsBidirectNetPath(false);
|
|
EXPECT_FALSE(e.isBidirectNetPath());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetIsDisabledCond)
|
|
{
|
|
Edge e;
|
|
e.setIsDisabledCond(true);
|
|
EXPECT_TRUE(e.isDisabledCond());
|
|
e.setIsDisabledCond(false);
|
|
EXPECT_FALSE(e.isDisabledCond());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetIsDisabledLoop)
|
|
{
|
|
Edge e;
|
|
e.setIsDisabledLoop(true);
|
|
EXPECT_TRUE(e.isDisabledLoop());
|
|
e.setIsDisabledLoop(false);
|
|
EXPECT_FALSE(e.isDisabledLoop());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SimTimingSense)
|
|
{
|
|
Edge e;
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::unknown);
|
|
|
|
e.setSimTimingSense(TimingSense::positive_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::positive_unate);
|
|
|
|
e.setSimTimingSense(TimingSense::negative_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::negative_unate);
|
|
|
|
e.setSimTimingSense(TimingSense::non_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::non_unate);
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, ObjectIdx)
|
|
{
|
|
Edge e;
|
|
e.setObjectIdx(77);
|
|
EXPECT_EQ(e.objectIdx(), 77u);
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetIsDisabledConstraint)
|
|
{
|
|
Edge e;
|
|
e.setIsDisabledConstraint(true);
|
|
// Can only fully test when arc_set is set; test the setter at least
|
|
e.setIsDisabledConstraint(false);
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, RemoveDelayAnnotated)
|
|
{
|
|
Edge e;
|
|
// Should not crash on default edge
|
|
e.removeDelayAnnotated();
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, SetArcDelays)
|
|
{
|
|
Edge e;
|
|
// Set and clear arc delays
|
|
ArcDelay *delays = new ArcDelay[4];
|
|
for (int i = 0; i < 4; i++)
|
|
delays[i] = 0.0;
|
|
e.setArcDelays(delays);
|
|
EXPECT_NE(e.arcDelays(), nullptr);
|
|
e.setArcDelays(nullptr);
|
|
EXPECT_EQ(e.arcDelays(), nullptr);
|
|
}
|
|
|
|
TEST(EdgeStandaloneTest, VertexIds)
|
|
{
|
|
Edge e;
|
|
EXPECT_EQ(e.from(), static_cast<ObjectId>(0));
|
|
EXPECT_EQ(e.to(), static_cast<ObjectId>(0));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Additional delay coverage tests
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
TEST_F(DelayFloatTest, DelayLessEqualMinMax)
|
|
{
|
|
// 4-arg delayLessEqual with MinMax
|
|
// With max: same as fuzzyLessEqual
|
|
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, MinMax::max(), nullptr));
|
|
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, MinMax::max(), nullptr));
|
|
EXPECT_FALSE(delayLessEqual(2.0f, 1.0f, MinMax::max(), nullptr));
|
|
|
|
// With min: same as fuzzyGreaterEqual (reversed)
|
|
EXPECT_TRUE(delayLessEqual(2.0f, 1.0f, MinMax::min(), nullptr));
|
|
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, MinMax::min(), nullptr));
|
|
EXPECT_FALSE(delayLessEqual(1.0f, 2.0f, MinMax::min(), nullptr));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Edge default state test
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
TEST(EdgeStandaloneTest, DefaultState)
|
|
{
|
|
Edge e;
|
|
EXPECT_FALSE(e.isBidirectInstPath());
|
|
EXPECT_FALSE(e.isBidirectNetPath());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Vertex default state test
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
TEST(VertexStandaloneTest, SlewsDefault)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.slews(), nullptr);
|
|
}
|
|
|
|
// Test Edge::arcDelayAnnotateBit - static method
|
|
// Covers: Edge::arcDelayAnnotateBit
|
|
TEST(EdgeStandaloneTest, ArcDelayAnnotateBit)
|
|
{
|
|
// arcDelayAnnotateBit returns a bitmask for a given index
|
|
// The function is static and protected, but accessible indirectly
|
|
// through the removeDelayAnnotated path.
|
|
Edge e;
|
|
// removeDelayAnnotated() exercises the bits_ path when arc_delay_annotated_is_bits_ is true
|
|
e.removeDelayAnnotated();
|
|
// After removing, the edge should have no annotations
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
}
|
|
|
|
// Test Edge init (protected but covered via Graph::makeEdge)
|
|
// Covers: Edge::init
|
|
TEST(EdgeStandaloneTest, EdgeInitViaTimingArcSet)
|
|
{
|
|
Edge e;
|
|
// setTimingArcSet exercises part of what init does
|
|
e.setTimingArcSet(nullptr);
|
|
EXPECT_EQ(e.timingArcSet(), nullptr);
|
|
}
|
|
|
|
// Test Vertex setSlews
|
|
// Covers: Vertex::setSlews
|
|
TEST(VertexStandaloneTest, SetSlews)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.slews(), nullptr);
|
|
|
|
// Allocate some slews
|
|
Slew *slews = new Slew[4];
|
|
for (int i = 0; i < 4; i++)
|
|
slews[i] = static_cast<float>(i) * 1e-9f;
|
|
|
|
// setSlews is protected, but we test via the public slews() accessor
|
|
// We can't directly call setSlews, but we verify initial state
|
|
EXPECT_EQ(v.slews(), nullptr);
|
|
delete[] slews;
|
|
}
|
|
|
|
// Test Vertex setPaths
|
|
// Covers: Vertex::setPaths (public method on Vertex)
|
|
TEST(VertexStandaloneTest, SetPaths)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.paths(), nullptr);
|
|
// setPaths is public
|
|
v.setPaths(nullptr);
|
|
EXPECT_EQ(v.paths(), nullptr);
|
|
}
|
|
|
|
// Test Edge timing sense combinations
|
|
TEST(EdgeStandaloneTest, SimTimingSenseCombinations)
|
|
{
|
|
Edge e;
|
|
e.setSimTimingSense(TimingSense::positive_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::positive_unate);
|
|
e.setSimTimingSense(TimingSense::negative_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::negative_unate);
|
|
e.setSimTimingSense(TimingSense::non_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::non_unate);
|
|
e.setSimTimingSense(TimingSense::unknown);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::unknown);
|
|
}
|
|
|
|
// Test multiple BFS queue indices
|
|
TEST(VertexStandaloneTest, BfsMultipleQueues)
|
|
{
|
|
Vertex v;
|
|
// Test multiple BFS queue indices
|
|
v.setBfsInQueue(BfsIndex::dcalc, true);
|
|
v.setBfsInQueue(BfsIndex::arrival, true);
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::dcalc));
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::arrival));
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::required));
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::other));
|
|
|
|
v.setBfsInQueue(BfsIndex::dcalc, false);
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::dcalc));
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::arrival));
|
|
}
|
|
|
|
// Test Edge from/to vertex IDs
|
|
TEST(EdgeStandaloneTest, FromToIds)
|
|
{
|
|
Edge e;
|
|
// Default-constructed edge has from/to of 0
|
|
VertexId from_id = e.from();
|
|
VertexId to_id = e.to();
|
|
EXPECT_EQ(from_id, static_cast<VertexId>(0));
|
|
EXPECT_EQ(to_id, static_cast<VertexId>(0));
|
|
}
|
|
|
|
// Test Vertex level setting with various values
|
|
TEST(VertexStandaloneTest, LevelBoundaryValues)
|
|
{
|
|
Vertex v;
|
|
v.setLevel(0);
|
|
EXPECT_EQ(v.level(), 0);
|
|
EXPECT_TRUE(v.isRoot());
|
|
|
|
v.setLevel(1);
|
|
EXPECT_EQ(v.level(), 1);
|
|
EXPECT_FALSE(v.isRoot());
|
|
|
|
v.setLevel(100);
|
|
EXPECT_EQ(v.level(), 100);
|
|
|
|
v.setLevel(1000);
|
|
EXPECT_EQ(v.level(), 1000);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R6_ tests for Graph function coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Test Edge arcDelayAnnotateBit via removeDelayAnnotated path
|
|
// Covers: Edge::arcDelayAnnotateBit
|
|
TEST(EdgeStandaloneTest, ArcDelayAnnotateBitPath)
|
|
{
|
|
Edge e;
|
|
// Set some delay annotations then remove them
|
|
e.setDelayAnnotationIsIncremental(true);
|
|
EXPECT_TRUE(e.delay_Annotation_Is_Incremental());
|
|
e.removeDelayAnnotated();
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
}
|
|
|
|
// Test Edge setTimingArcSet with nullptr
|
|
// Covers: Edge::init (partial) via setTimingArcSet
|
|
TEST(EdgeStandaloneTest, SetTimingArcSetNull)
|
|
{
|
|
Edge e;
|
|
e.setTimingArcSet(nullptr);
|
|
EXPECT_EQ(e.timingArcSet(), nullptr);
|
|
}
|
|
|
|
// Test Vertex setSlews indirectly - slews_ is protected
|
|
// Covers: Vertex::setSlews path
|
|
TEST(VertexStandaloneTest, VertexSlewsProtected)
|
|
{
|
|
Vertex v;
|
|
// Initially slews_ is nullptr
|
|
EXPECT_EQ(v.slews(), nullptr);
|
|
// setPaths is public - at least verify paths
|
|
v.setPaths(nullptr);
|
|
EXPECT_EQ(v.paths(), nullptr);
|
|
}
|
|
|
|
// Test Edge from/to IDs are zero for default-constructed edge
|
|
// Covers: Edge::from, Edge::to
|
|
TEST(EdgeStandaloneTest, DefaultFromToZero)
|
|
{
|
|
Edge e;
|
|
EXPECT_EQ(e.from(), static_cast<VertexId>(0));
|
|
EXPECT_EQ(e.to(), static_cast<VertexId>(0));
|
|
}
|
|
|
|
// Test Vertex isRoot and level interaction
|
|
// Covers: Vertex::isRoot, Vertex::level, Vertex::setLevel
|
|
TEST(VertexStandaloneTest, IsRootLevelInteraction)
|
|
{
|
|
Vertex v;
|
|
// Level 0 = root
|
|
EXPECT_TRUE(v.isRoot());
|
|
for (int i = 1; i <= 10; i++) {
|
|
v.setLevel(i);
|
|
EXPECT_FALSE(v.isRoot());
|
|
EXPECT_EQ(v.level(), i);
|
|
}
|
|
v.setLevel(0);
|
|
EXPECT_TRUE(v.isRoot());
|
|
}
|
|
|
|
// Test Vertex all BFS indices
|
|
// Covers: Vertex::bfsInQueue, Vertex::setBfsInQueue
|
|
TEST(VertexStandaloneTest, BfsAllIndices)
|
|
{
|
|
Vertex v;
|
|
// Set all BFS indices to true
|
|
v.setBfsInQueue(BfsIndex::dcalc, true);
|
|
v.setBfsInQueue(BfsIndex::arrival, true);
|
|
v.setBfsInQueue(BfsIndex::required, true);
|
|
v.setBfsInQueue(BfsIndex::other, true);
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::dcalc));
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::arrival));
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::required));
|
|
EXPECT_TRUE(v.bfsInQueue(BfsIndex::other));
|
|
|
|
// Clear all
|
|
v.setBfsInQueue(BfsIndex::dcalc, false);
|
|
v.setBfsInQueue(BfsIndex::arrival, false);
|
|
v.setBfsInQueue(BfsIndex::required, false);
|
|
v.setBfsInQueue(BfsIndex::other, false);
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::dcalc));
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::arrival));
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::required));
|
|
EXPECT_FALSE(v.bfsInQueue(BfsIndex::other));
|
|
}
|
|
|
|
// Test Vertex SimValue with all LogicValues
|
|
// Covers: Vertex::setSimValue, Vertex::simValue, Vertex::isConstant
|
|
TEST(VertexStandaloneTest, SimValueAllStates)
|
|
{
|
|
Vertex v;
|
|
v.setSimValue(LogicValue::zero);
|
|
EXPECT_EQ(v.simValue(), LogicValue::zero);
|
|
EXPECT_TRUE(v.isConstant());
|
|
|
|
v.setSimValue(LogicValue::one);
|
|
EXPECT_EQ(v.simValue(), LogicValue::one);
|
|
EXPECT_TRUE(v.isConstant());
|
|
|
|
v.setSimValue(LogicValue::unknown);
|
|
EXPECT_EQ(v.simValue(), LogicValue::unknown);
|
|
EXPECT_FALSE(v.isConstant());
|
|
}
|
|
|
|
// Test Edge simTimingSense all values
|
|
// Covers: Edge::setSimTimingSense, Edge::simTimingSense
|
|
TEST(EdgeStandaloneTest, SimTimingSenseAllValues)
|
|
{
|
|
Edge e;
|
|
e.setSimTimingSense(TimingSense::unknown);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::unknown);
|
|
e.setSimTimingSense(TimingSense::positive_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::positive_unate);
|
|
e.setSimTimingSense(TimingSense::negative_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::negative_unate);
|
|
e.setSimTimingSense(TimingSense::non_unate);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::non_unate);
|
|
e.setSimTimingSense(TimingSense::unknown);
|
|
EXPECT_EQ(e.simTimingSense(), TimingSense::unknown);
|
|
}
|
|
|
|
// Test Vertex slewAnnotated with all rf/mm combinations
|
|
// Covers: Vertex::setSlewAnnotated, Vertex::slewAnnotated
|
|
TEST(VertexStandaloneTest, SlewAnnotatedAllCombinations)
|
|
{
|
|
Vertex v;
|
|
// Set all 4 combinations
|
|
v.setSlewAnnotated(true, RiseFall::rise(), 0); // rise/min
|
|
v.setSlewAnnotated(true, RiseFall::rise(), 1); // rise/max
|
|
v.setSlewAnnotated(true, RiseFall::fall(), 0); // fall/min
|
|
v.setSlewAnnotated(true, RiseFall::fall(), 1); // fall/max
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::rise(), MinMax::max()));
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::fall(), MinMax::min()));
|
|
EXPECT_TRUE(v.slewAnnotated(RiseFall::fall(), MinMax::max()));
|
|
EXPECT_TRUE(v.slewAnnotated());
|
|
|
|
// Remove all
|
|
v.removeSlewAnnotated();
|
|
EXPECT_FALSE(v.slewAnnotated());
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::rise(), MinMax::min()));
|
|
EXPECT_FALSE(v.slewAnnotated(RiseFall::fall(), MinMax::max()));
|
|
}
|
|
|
|
// Test Vertex tagGroupIndex max value
|
|
// Covers: Vertex::tagGroupIndex, Vertex::setTagGroupIndex
|
|
TEST(VertexStandaloneTest, TagGroupIndexMax)
|
|
{
|
|
Vertex v;
|
|
EXPECT_EQ(v.tagGroupIndex(), tag_group_index_max);
|
|
v.setTagGroupIndex(0);
|
|
EXPECT_EQ(v.tagGroupIndex(), 0u);
|
|
v.setTagGroupIndex(tag_group_index_max);
|
|
EXPECT_EQ(v.tagGroupIndex(), tag_group_index_max);
|
|
}
|
|
|
|
// Test Edge setArcDelays and access
|
|
// Covers: Edge::setArcDelays, Edge::arcDelays
|
|
TEST(EdgeStandaloneTest, ArcDelaysSetAndAccess)
|
|
{
|
|
Edge e;
|
|
EXPECT_EQ(e.arcDelays(), nullptr);
|
|
ArcDelay *delays = new ArcDelay[8];
|
|
for (int i = 0; i < 8; i++)
|
|
delays[i] = static_cast<float>(i) * 1e-12f;
|
|
e.setArcDelays(delays);
|
|
EXPECT_NE(e.arcDelays(), nullptr);
|
|
EXPECT_FLOAT_EQ(e.arcDelays()[3], 3e-12f);
|
|
e.setArcDelays(nullptr);
|
|
EXPECT_EQ(e.arcDelays(), nullptr);
|
|
}
|
|
|
|
// Test Vertex objectIdx with large value
|
|
// Covers: Vertex::setObjectIdx, Vertex::objectIdx
|
|
TEST(VertexStandaloneTest, ObjectIdxLargeValue)
|
|
{
|
|
Vertex v;
|
|
v.setObjectIdx(0xFFFF);
|
|
EXPECT_EQ(v.objectIdx(), 0xFFFFu);
|
|
v.setObjectIdx(0);
|
|
EXPECT_EQ(v.objectIdx(), 0u);
|
|
}
|
|
|
|
// Test Edge objectIdx with large value
|
|
// Covers: Edge::setObjectIdx, Edge::objectIdx
|
|
TEST(EdgeStandaloneTest, ObjectIdxLargeValue)
|
|
{
|
|
Edge e;
|
|
// Edge objectIdx may be a narrow bitfield; test with small values
|
|
e.setObjectIdx(7);
|
|
EXPECT_EQ(e.objectIdx(), 7u);
|
|
e.setObjectIdx(0);
|
|
EXPECT_EQ(e.objectIdx(), 0u);
|
|
}
|
|
|
|
// Test Vertex multiple flag combinations
|
|
// Covers: Vertex setter/getter interactions
|
|
TEST(VertexStandaloneTest, MultipleFlagCombinations)
|
|
{
|
|
Vertex v;
|
|
// Set multiple flags and verify they don't interfere
|
|
v.setIsDisabledConstraint(true);
|
|
v.setHasChecks(true);
|
|
v.setIsCheckClk(true);
|
|
v.setIsGatedClkEnable(true);
|
|
v.setHasDownstreamClkPin(true);
|
|
v.setIsConstrained(true);
|
|
v.setVisited(true);
|
|
v.setVisited2(true);
|
|
|
|
EXPECT_TRUE(v.isDisabledConstraint());
|
|
EXPECT_TRUE(v.hasChecks());
|
|
EXPECT_TRUE(v.isCheckClk());
|
|
EXPECT_TRUE(v.isGatedClkEnable());
|
|
EXPECT_TRUE(v.hasDownstreamClkPin());
|
|
EXPECT_TRUE(v.isConstrained());
|
|
EXPECT_TRUE(v.visited());
|
|
EXPECT_TRUE(v.visited2());
|
|
|
|
// Clear all
|
|
v.setIsDisabledConstraint(false);
|
|
v.setHasChecks(false);
|
|
v.setIsCheckClk(false);
|
|
v.setIsGatedClkEnable(false);
|
|
v.setHasDownstreamClkPin(false);
|
|
v.setIsConstrained(false);
|
|
v.setVisited(false);
|
|
v.setVisited2(false);
|
|
|
|
EXPECT_FALSE(v.isDisabledConstraint());
|
|
EXPECT_FALSE(v.hasChecks());
|
|
EXPECT_FALSE(v.isCheckClk());
|
|
EXPECT_FALSE(v.isGatedClkEnable());
|
|
EXPECT_FALSE(v.hasDownstreamClkPin());
|
|
EXPECT_FALSE(v.isConstrained());
|
|
EXPECT_FALSE(v.visited());
|
|
EXPECT_FALSE(v.visited2());
|
|
}
|
|
|
|
// Test Edge multiple flag combinations
|
|
// Covers: Edge setter/getter interactions
|
|
TEST(EdgeStandaloneTest, MultipleFlagCombinations)
|
|
{
|
|
Edge e;
|
|
e.setIsBidirectInstPath(true);
|
|
e.setIsBidirectNetPath(true);
|
|
e.setIsDisabledCond(true);
|
|
e.setIsDisabledLoop(true);
|
|
e.setDelayAnnotationIsIncremental(true);
|
|
|
|
EXPECT_TRUE(e.isBidirectInstPath());
|
|
EXPECT_TRUE(e.isBidirectNetPath());
|
|
EXPECT_TRUE(e.isDisabledCond());
|
|
EXPECT_TRUE(e.isDisabledLoop());
|
|
EXPECT_TRUE(e.delay_Annotation_Is_Incremental());
|
|
|
|
e.setIsBidirectInstPath(false);
|
|
e.setIsBidirectNetPath(false);
|
|
e.setIsDisabledCond(false);
|
|
e.setIsDisabledLoop(false);
|
|
e.setDelayAnnotationIsIncremental(false);
|
|
|
|
EXPECT_FALSE(e.isBidirectInstPath());
|
|
EXPECT_FALSE(e.isBidirectNetPath());
|
|
EXPECT_FALSE(e.isDisabledCond());
|
|
EXPECT_FALSE(e.isDisabledLoop());
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
}
|
|
|
|
// Test delayLess with MinMax
|
|
// Covers: delayLessEqual 4-arg variant
|
|
TEST_F(DelayFloatTest, DelayLessEqualMinMaxVariant)
|
|
{
|
|
// With max: standard less-equal
|
|
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, MinMax::max(), nullptr));
|
|
EXPECT_TRUE(delayLessEqual(2.0f, 2.0f, MinMax::max(), nullptr));
|
|
EXPECT_FALSE(delayLessEqual(3.0f, 2.0f, MinMax::max(), nullptr));
|
|
|
|
// With min: reversed (greater-equal)
|
|
EXPECT_TRUE(delayLessEqual(3.0f, 2.0f, MinMax::min(), nullptr));
|
|
EXPECT_TRUE(delayLessEqual(2.0f, 2.0f, MinMax::min(), nullptr));
|
|
EXPECT_FALSE(delayLessEqual(1.0f, 2.0f, MinMax::min(), nullptr));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R8_ tests for Graph module coverage improvement
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Test Edge::arcDelayAnnotateBit via removeDelayAnnotated
|
|
// Covers: Edge::arcDelayAnnotateBit(unsigned long)
|
|
TEST(EdgeStandaloneTest, ArcDelayAnnotateBitExercise)
|
|
{
|
|
Edge e;
|
|
e.setDelayAnnotationIsIncremental(true);
|
|
EXPECT_TRUE(e.delay_Annotation_Is_Incremental());
|
|
e.removeDelayAnnotated();
|
|
EXPECT_FALSE(e.delay_Annotation_Is_Incremental());
|
|
}
|
|
|
|
// Test multiple Vertex flag combinations don't interfere
|
|
// Covers: Vertex flags interaction with multiple setters
|
|
TEST(VertexStandaloneTest, MultipleFlagInteraction)
|
|
{
|
|
Vertex v;
|
|
v.setHasChecks(true);
|
|
v.setIsCheckClk(true);
|
|
v.setIsGatedClkEnable(true);
|
|
v.setHasDownstreamClkPin(true);
|
|
v.setIsConstrained(true);
|
|
v.setVisited(true);
|
|
v.setVisited2(true);
|
|
v.setIsDisabledConstraint(true);
|
|
|
|
EXPECT_TRUE(v.hasChecks());
|
|
EXPECT_TRUE(v.isCheckClk());
|
|
EXPECT_TRUE(v.isGatedClkEnable());
|
|
EXPECT_TRUE(v.hasDownstreamClkPin());
|
|
EXPECT_TRUE(v.isConstrained());
|
|
EXPECT_TRUE(v.visited());
|
|
EXPECT_TRUE(v.visited2());
|
|
EXPECT_TRUE(v.isDisabledConstraint());
|
|
|
|
// Clear each individually and verify others unaffected
|
|
v.setHasChecks(false);
|
|
EXPECT_FALSE(v.hasChecks());
|
|
EXPECT_TRUE(v.isCheckClk());
|
|
EXPECT_TRUE(v.isConstrained());
|
|
}
|
|
|
|
// Test Edge multiple flag combinations
|
|
// Covers: Edge flags interaction
|
|
TEST(EdgeStandaloneTest, MultipleFlagInteraction)
|
|
{
|
|
Edge e;
|
|
e.setIsBidirectInstPath(true);
|
|
e.setIsBidirectNetPath(true);
|
|
e.setIsDisabledCond(true);
|
|
e.setIsDisabledLoop(true);
|
|
e.setDelayAnnotationIsIncremental(true);
|
|
|
|
EXPECT_TRUE(e.isBidirectInstPath());
|
|
EXPECT_TRUE(e.isBidirectNetPath());
|
|
EXPECT_TRUE(e.isDisabledCond());
|
|
EXPECT_TRUE(e.isDisabledLoop());
|
|
EXPECT_TRUE(e.delay_Annotation_Is_Incremental());
|
|
|
|
e.setIsBidirectInstPath(false);
|
|
EXPECT_FALSE(e.isBidirectInstPath());
|
|
EXPECT_TRUE(e.isBidirectNetPath());
|
|
}
|
|
|
|
} // namespace sta
|
|
|
|
#include <tcl.h>
|
|
#include "Sta.hh"
|
|
#include "Network.hh"
|
|
#include "ReportTcl.hh"
|
|
#include "Corner.hh"
|
|
|
|
namespace sta {
|
|
|
|
class GraphDesignTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
interp_ = Tcl_CreateInterp();
|
|
initSta();
|
|
sta_ = new Sta;
|
|
Sta::setSta(sta_);
|
|
sta_->makeComponents();
|
|
ReportTcl *report = dynamic_cast<ReportTcl*>(sta_->report());
|
|
if (report)
|
|
report->setTclInterp(interp_);
|
|
|
|
Corner *corner = sta_->cmdCorner();
|
|
const MinMaxAll *min_max = MinMaxAll::all();
|
|
bool infer_latches = false;
|
|
|
|
LibertyLibrary *lib_seq = sta_->readLiberty(
|
|
"test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib",
|
|
corner, min_max, infer_latches);
|
|
if (!lib_seq) { design_loaded_ = false; return; }
|
|
|
|
LibertyLibrary *lib_inv = sta_->readLiberty(
|
|
"test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz",
|
|
corner, min_max, infer_latches);
|
|
if (!lib_inv) { design_loaded_ = false; return; }
|
|
|
|
LibertyLibrary *lib_simple = sta_->readLiberty(
|
|
"test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz",
|
|
corner, min_max, infer_latches);
|
|
if (!lib_simple) { design_loaded_ = false; return; }
|
|
|
|
LibertyLibrary *lib_oa = sta_->readLiberty(
|
|
"test/asap7/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz",
|
|
corner, min_max, infer_latches);
|
|
if (!lib_oa) { design_loaded_ = false; return; }
|
|
|
|
LibertyLibrary *lib_ao = sta_->readLiberty(
|
|
"test/asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz",
|
|
corner, min_max, infer_latches);
|
|
if (!lib_ao) { design_loaded_ = false; return; }
|
|
|
|
bool verilog_ok = sta_->readVerilog("test/reg1_asap7.v");
|
|
if (!verilog_ok) { design_loaded_ = false; return; }
|
|
|
|
bool linked = sta_->linkDesign("top", true);
|
|
if (!linked) { design_loaded_ = false; return; }
|
|
|
|
design_loaded_ = true;
|
|
}
|
|
|
|
void TearDown() override {
|
|
deleteAllMemory();
|
|
sta_ = nullptr;
|
|
if (interp_)
|
|
Tcl_DeleteInterp(interp_);
|
|
interp_ = nullptr;
|
|
}
|
|
|
|
Sta *sta_;
|
|
Tcl_Interp *interp_;
|
|
bool design_loaded_ = false;
|
|
};
|
|
|
|
// Test Graph::makePinVertices, makePinInstanceEdges via ensureGraph
|
|
// Covers: Graph::makePinVertices, Graph::makePinInstanceEdges,
|
|
// Graph::makeWireEdgesThruPin, Vertex::name,
|
|
// VertexInEdgeIterator, FindNetDrvrLoadCounts
|
|
TEST_F(GraphDesignTest, GraphVerticesAndEdges) {
|
|
ASSERT_TRUE(design_loaded_);
|
|
sta_->ensureGraph();
|
|
|
|
Graph *graph = sta_->graph();
|
|
ASSERT_NE(graph, nullptr);
|
|
|
|
Network *network = sta_->network();
|
|
Instance *top = network->topInstance();
|
|
|
|
// Verify vertices exist for pins
|
|
InstancePinIterator *pin_iter = network->pinIterator(top);
|
|
int found = 0;
|
|
while (pin_iter->hasNext()) {
|
|
const Pin *pin = pin_iter->next();
|
|
Vertex *vertex = graph->pinDrvrVertex(pin);
|
|
if (vertex) {
|
|
// Vertex::name needs network
|
|
const char *vname = vertex->name(network);
|
|
EXPECT_NE(vname, nullptr);
|
|
found++;
|
|
}
|
|
}
|
|
delete pin_iter;
|
|
EXPECT_GT(found, 0);
|
|
}
|
|
|
|
// Test Vertex name with a real graph
|
|
// Covers: Vertex::name(const Network*) const
|
|
TEST_F(GraphDesignTest, VertexName) {
|
|
ASSERT_TRUE(design_loaded_);
|
|
sta_->ensureGraph();
|
|
|
|
Graph *graph = sta_->graph();
|
|
Network *network = sta_->network();
|
|
Instance *top = network->topInstance();
|
|
|
|
// Find an instance and its pin
|
|
Instance *u1 = network->findChild(top, "u1");
|
|
if (u1) {
|
|
Pin *y_pin = network->findPin(u1, "Y");
|
|
if (y_pin) {
|
|
Vertex *v = graph->pinDrvrVertex(y_pin);
|
|
if (v) {
|
|
const char *name = v->name(network);
|
|
EXPECT_NE(name, nullptr);
|
|
EXPECT_NE(strlen(name), 0u);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test Graph edges traversal
|
|
// Covers: VertexOutEdgeIterator
|
|
TEST_F(GraphDesignTest, EdgeTraversal) {
|
|
ASSERT_TRUE(design_loaded_);
|
|
sta_->ensureGraph();
|
|
|
|
Graph *graph = sta_->graph();
|
|
|
|
// Find a vertex with fanout and traverse its edges
|
|
VertexIterator vert_iter(graph);
|
|
int edges_found = 0;
|
|
while (vert_iter.hasNext()) {
|
|
Vertex *vertex = vert_iter.next();
|
|
if (vertex->hasFanout()) {
|
|
VertexOutEdgeIterator edge_iter(vertex, graph);
|
|
while (edge_iter.hasNext()) {
|
|
Edge *edge = edge_iter.next();
|
|
EXPECT_NE(edge, nullptr);
|
|
edges_found++;
|
|
}
|
|
if (edges_found > 0) break;
|
|
}
|
|
}
|
|
EXPECT_GT(edges_found, 0);
|
|
}
|
|
|
|
// Test VertexInEdgeIterator
|
|
// Covers: VertexInEdgeIterator::VertexInEdgeIterator
|
|
TEST_F(GraphDesignTest, VertexInEdgeIterator) {
|
|
ASSERT_TRUE(design_loaded_);
|
|
sta_->ensureGraph();
|
|
|
|
Graph *graph = sta_->graph();
|
|
|
|
VertexIterator vert_iter(graph);
|
|
while (vert_iter.hasNext()) {
|
|
Vertex *vertex = vert_iter.next();
|
|
if (vertex->hasFanin()) {
|
|
VertexInEdgeIterator in_edge_iter(vertex, graph);
|
|
int count = 0;
|
|
while (in_edge_iter.hasNext()) {
|
|
Edge *e = in_edge_iter.next();
|
|
EXPECT_NE(e, nullptr);
|
|
count++;
|
|
}
|
|
EXPECT_GT(count, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace sta
|