Merge remote-tracking branch 'origin/secure-bump-opensta-0321' into secure-sta-test-by-opus
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
This commit is contained in:
commit
9547beead3
|
|
@ -1,5 +1,7 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include "DelayFloat.hh"
|
||||
#include "Delay.hh"
|
||||
#include "DelayScalar.hh"
|
||||
#include "StaState.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Transition.hh"
|
||||
|
|
@ -9,38 +11,55 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
// Minimal StaState subclass that provides a DelayOps for unit tests.
|
||||
class TestStaState : public StaState
|
||||
{
|
||||
public:
|
||||
TestStaState() { delay_ops_ = new DelayOpsScalar(); }
|
||||
~TestStaState() override { delete delay_ops_; delay_ops_ = nullptr; }
|
||||
};
|
||||
|
||||
class DelayFloatTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
initDelayConstants();
|
||||
sta_state_ = new TestStaState();
|
||||
}
|
||||
void TearDown() override {
|
||||
delete sta_state_;
|
||||
sta_state_ = nullptr;
|
||||
}
|
||||
// Convenience accessor for delay comparison functions.
|
||||
const StaState *sta() const { return sta_state_; }
|
||||
|
||||
TestStaState *sta_state_;
|
||||
};
|
||||
|
||||
TEST_F(DelayFloatTest, DelayZero) {
|
||||
EXPECT_TRUE(delayZero(0.0f));
|
||||
EXPECT_TRUE(delayZero(delay_zero));
|
||||
EXPECT_FALSE(delayZero(1.0f));
|
||||
EXPECT_FALSE(delayZero(-1.0f));
|
||||
EXPECT_TRUE(delayZero(Delay(0.0f), sta()));
|
||||
EXPECT_TRUE(delayZero(delay_zero, sta()));
|
||||
EXPECT_FALSE(delayZero(Delay(1.0f), sta()));
|
||||
EXPECT_FALSE(delayZero(Delay(-1.0f), sta()));
|
||||
}
|
||||
|
||||
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));
|
||||
EXPECT_TRUE(delayEqual(Delay(1.0f), Delay(1.0f), sta()));
|
||||
EXPECT_TRUE(delayEqual(Delay(0.0f), Delay(0.0f), sta()));
|
||||
EXPECT_FALSE(delayEqual(Delay(1.0f), Delay(2.0f), sta()));
|
||||
}
|
||||
|
||||
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));
|
||||
EXPECT_TRUE(delayInf(Delay(INF), sta()));
|
||||
EXPECT_TRUE(delayInf(Delay(-INF), sta()));
|
||||
EXPECT_FALSE(delayInf(Delay(0.0f), sta()));
|
||||
EXPECT_FALSE(delayInf(Delay(1e10f), sta()));
|
||||
}
|
||||
|
||||
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));
|
||||
EXPECT_TRUE(delayLess(Delay(1.0f), Delay(2.0f), sta()));
|
||||
EXPECT_FALSE(delayLess(Delay(2.0f), Delay(1.0f), sta()));
|
||||
EXPECT_FALSE(delayLess(Delay(1.0f), Delay(1.0f), sta()));
|
||||
}
|
||||
|
||||
TEST_F(DelayFloatTest, DelayRemove) {
|
||||
|
|
@ -50,11 +69,6 @@ TEST_F(DelayFloatTest, DelayRemove) {
|
|||
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
|
||||
|
|
@ -68,8 +82,8 @@ TEST_F(DelayFloatTest, DelayInitValueMax) {
|
|||
}
|
||||
|
||||
TEST_F(DelayFloatTest, MakeDelay) {
|
||||
Delay d = makeDelay(1.5f, 0.0f, 0.0f);
|
||||
EXPECT_FLOAT_EQ(d, 1.5f);
|
||||
Delay d = makeDelay(1.5f, 0.0f);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(d), 1.5f);
|
||||
}
|
||||
|
||||
TEST_F(DelayFloatTest, DelayAsFloat) {
|
||||
|
|
@ -79,33 +93,33 @@ TEST_F(DelayFloatTest, DelayAsFloat) {
|
|||
|
||||
// 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));
|
||||
EXPECT_TRUE(delayGreater(Delay(2.0f), Delay(1.0f), sta()));
|
||||
EXPECT_FALSE(delayGreater(Delay(1.0f), Delay(2.0f), sta()));
|
||||
EXPECT_FALSE(delayGreater(Delay(1.0f), Delay(1.0f), sta()));
|
||||
}
|
||||
|
||||
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));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), sta()));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), sta()));
|
||||
EXPECT_FALSE(delayLessEqual(Delay(2.0f), Delay(1.0f), sta()));
|
||||
}
|
||||
|
||||
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));
|
||||
EXPECT_TRUE(delayGreaterEqual(Delay(2.0f), Delay(1.0f), sta()));
|
||||
EXPECT_TRUE(delayGreaterEqual(Delay(1.0f), Delay(1.0f), sta()));
|
||||
EXPECT_FALSE(delayGreaterEqual(Delay(1.0f), Delay(2.0f), sta()));
|
||||
}
|
||||
|
||||
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);
|
||||
// makeDelay(mean, std_dev) - sigma stored in Delay class
|
||||
Delay d = makeDelay(2.5f, 0.1f);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(d), 2.5f);
|
||||
}
|
||||
|
||||
TEST_F(DelayFloatTest, DelayNegative) {
|
||||
Delay d = -5.0f;
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(d), -5.0f);
|
||||
EXPECT_FALSE(delayZero(d));
|
||||
EXPECT_FALSE(delayZero(d, sta()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -274,11 +288,12 @@ TEST(VertexStandaloneTest, Paths)
|
|||
EXPECT_EQ(v.paths(), nullptr);
|
||||
}
|
||||
|
||||
// Test Vertex slews
|
||||
TEST(VertexStandaloneTest, Slews)
|
||||
// Test Vertex pin default
|
||||
TEST(VertexStandaloneTest, PinDefault)
|
||||
{
|
||||
Vertex v;
|
||||
EXPECT_EQ(v.slews(), nullptr);
|
||||
// slews() is protected; verify public pin() accessor instead
|
||||
EXPECT_EQ(v.pin(), nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -360,10 +375,10 @@ TEST(EdgeStandaloneTest, RemoveDelayAnnotated)
|
|||
TEST(EdgeStandaloneTest, SetArcDelays)
|
||||
{
|
||||
Edge e;
|
||||
// Set and clear arc delays
|
||||
ArcDelay *delays = new ArcDelay[4];
|
||||
// Set and clear arc delays (setArcDelays takes float*)
|
||||
float *delays = new float[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
delays[i] = 0.0;
|
||||
delays[i] = 0.0f;
|
||||
e.setArcDelays(delays);
|
||||
EXPECT_NE(e.arcDelays(), nullptr);
|
||||
e.setArcDelays(nullptr);
|
||||
|
|
@ -385,14 +400,14 @@ 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));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::max(), sta()));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), MinMax::max(), sta()));
|
||||
EXPECT_FALSE(delayLessEqual(Delay(2.0f), Delay(1.0f), MinMax::max(), sta()));
|
||||
|
||||
// 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));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(1.0f), MinMax::min(), sta()));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), MinMax::min(), sta()));
|
||||
EXPECT_FALSE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::min(), sta()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -413,7 +428,8 @@ TEST(EdgeStandaloneTest, DefaultState)
|
|||
TEST(VertexStandaloneTest, SlewsDefault)
|
||||
{
|
||||
Vertex v;
|
||||
EXPECT_EQ(v.slews(), nullptr);
|
||||
// slews() is protected; verify public paths() accessor instead
|
||||
EXPECT_EQ(v.paths(), nullptr);
|
||||
}
|
||||
|
||||
// Test Edge::arcDelayAnnotateBit - static method
|
||||
|
|
@ -440,22 +456,14 @@ TEST(EdgeStandaloneTest, EdgeInitViaTimingArcSet)
|
|||
EXPECT_EQ(e.timingArcSet(), nullptr);
|
||||
}
|
||||
|
||||
// Test Vertex setSlews
|
||||
// Covers: Vertex::setSlews
|
||||
// Test Vertex initial state via public accessors
|
||||
// Covers: Vertex default state
|
||||
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;
|
||||
// slews() and setSlews() are protected; verify public accessors instead
|
||||
EXPECT_EQ(v.pin(), nullptr);
|
||||
EXPECT_EQ(v.paths(), nullptr);
|
||||
}
|
||||
|
||||
// Test Vertex setPaths
|
||||
|
|
@ -541,14 +549,12 @@ TEST(EdgeStandaloneTest, SetTimingArcSetNull)
|
|||
EXPECT_EQ(e.timingArcSet(), nullptr);
|
||||
}
|
||||
|
||||
// Test Vertex setSlews indirectly - slews_ is protected
|
||||
// Covers: Vertex::setSlews path
|
||||
// Test Vertex public accessors for initial state
|
||||
// Covers: Vertex::paths, Vertex::setPaths
|
||||
TEST(VertexStandaloneTest, VertexSlewsProtected)
|
||||
{
|
||||
Vertex v;
|
||||
// Initially slews_ is nullptr
|
||||
EXPECT_EQ(v.slews(), nullptr);
|
||||
// setPaths is public - at least verify paths
|
||||
// slews() is protected; verify public setPaths/paths instead
|
||||
v.setPaths(nullptr);
|
||||
EXPECT_EQ(v.paths(), nullptr);
|
||||
}
|
||||
|
|
@ -673,7 +679,8 @@ TEST(EdgeStandaloneTest, ArcDelaysSetAndAccess)
|
|||
{
|
||||
Edge e;
|
||||
EXPECT_EQ(e.arcDelays(), nullptr);
|
||||
ArcDelay *delays = new ArcDelay[8];
|
||||
// setArcDelays takes float*
|
||||
float *delays = new float[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
delays[i] = static_cast<float>(i) * 1e-12f;
|
||||
e.setArcDelays(delays);
|
||||
|
|
@ -773,14 +780,14 @@ TEST(EdgeStandaloneTest, MultipleFlagCombinations)
|
|||
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));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::max(), sta()));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(2.0f), MinMax::max(), sta()));
|
||||
EXPECT_FALSE(delayLessEqual(Delay(3.0f), Delay(2.0f), MinMax::max(), sta()));
|
||||
|
||||
// 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));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(3.0f), Delay(2.0f), MinMax::min(), sta()));
|
||||
EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(2.0f), MinMax::min(), sta()));
|
||||
EXPECT_FALSE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::min(), sta()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ TEST_F(UnitTest, UserToSta) {
|
|||
|
||||
TEST_F(UnitTest, AsString) {
|
||||
Unit unit(1e-9f, "s", 3);
|
||||
const char *str = unit.asString(1e-9f);
|
||||
EXPECT_NE(str, nullptr);
|
||||
std::string str = unit.asString(1e-9f);
|
||||
EXPECT_FALSE(str.empty());
|
||||
// Should produce something like "1.000"
|
||||
}
|
||||
|
||||
|
|
@ -1268,8 +1268,8 @@ TEST(InternalPowerTest, DirectConstruction) {
|
|||
InternalPower pwr(nullptr, nullptr, nullptr, when_expr, models);
|
||||
EXPECT_EQ(pwr.when(), when_expr.get());
|
||||
EXPECT_EQ(pwr.relatedPgPin(), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::rise()).model(), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1450,26 +1450,27 @@ TEST_F(LinearModelTest, GateLinearModelConstruct) {
|
|||
|
||||
TEST_F(LinearModelTest, GateLinearModelGateDelay) {
|
||||
GateLinearModel model(cell_, 1.0f, 2.0f);
|
||||
ArcDelay gate_delay;
|
||||
Slew drvr_slew;
|
||||
float gate_delay;
|
||||
float drvr_slew;
|
||||
// delay = intrinsic + resistance * load_cap = 1.0 + 2.0 * 3.0 = 7.0
|
||||
model.gateDelay(nullptr, 0.0f, 3.0f, false, gate_delay, drvr_slew);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(gate_delay), 7.0f);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(drvr_slew), 0.0f);
|
||||
model.gateDelay(nullptr, 0.0f, 3.0f, gate_delay, drvr_slew);
|
||||
EXPECT_FLOAT_EQ(gate_delay, 7.0f);
|
||||
EXPECT_FLOAT_EQ(drvr_slew, 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(LinearModelTest, GateLinearModelZeroLoad) {
|
||||
GateLinearModel model(cell_, 2.5f, 1.0f);
|
||||
ArcDelay gate_delay;
|
||||
Slew drvr_slew;
|
||||
float gate_delay;
|
||||
float drvr_slew;
|
||||
// delay = 2.5 + 1.0 * 0.0 = 2.5
|
||||
model.gateDelay(nullptr, 0.0f, 0.0f, false, gate_delay, drvr_slew);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(gate_delay), 2.5f);
|
||||
model.gateDelay(nullptr, 0.0f, 0.0f, gate_delay, drvr_slew);
|
||||
EXPECT_FLOAT_EQ(gate_delay, 2.5f);
|
||||
}
|
||||
|
||||
TEST_F(LinearModelTest, GateLinearModelReportGateDelay) {
|
||||
GateLinearModel model(cell_, 1.0f, 2.0f);
|
||||
std::string report = model.reportGateDelay(nullptr, 0.0f, 0.5f, false, 3);
|
||||
std::string report = model.reportGateDelay(nullptr, 0.0f, 0.5f,
|
||||
nullptr, PocvMode::scalar, 3);
|
||||
EXPECT_FALSE(report.empty());
|
||||
// Report should contain "Delay ="
|
||||
EXPECT_NE(report.find("Delay"), std::string::npos);
|
||||
|
|
@ -1477,23 +1478,27 @@ TEST_F(LinearModelTest, GateLinearModelReportGateDelay) {
|
|||
|
||||
TEST_F(LinearModelTest, CheckLinearModelConstruct) {
|
||||
CheckLinearModel model(cell_, 3.0f);
|
||||
ArcDelay delay = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f, false);
|
||||
ArcDelay delay = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f,
|
||||
nullptr, PocvMode::scalar);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(delay), 3.0f);
|
||||
}
|
||||
|
||||
TEST_F(LinearModelTest, CheckLinearModelCheckDelay) {
|
||||
CheckLinearModel model(cell_, 5.5f);
|
||||
// checkDelay always returns intrinsic_ regardless of other params
|
||||
ArcDelay delay1 = model.checkDelay(nullptr, 1.0f, 2.0f, 3.0f, true);
|
||||
ArcDelay delay1 = model.checkDelay(nullptr, 1.0f, 2.0f, 3.0f,
|
||||
nullptr, PocvMode::scalar);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(delay1), 5.5f);
|
||||
ArcDelay delay2 = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f, false);
|
||||
ArcDelay delay2 = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f,
|
||||
nullptr, PocvMode::scalar);
|
||||
EXPECT_FLOAT_EQ(delayAsFloat(delay2), 5.5f);
|
||||
}
|
||||
|
||||
TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) {
|
||||
CheckLinearModel model(cell_, 2.0f);
|
||||
std::string report = model.reportCheckDelay(nullptr, 0.0f, nullptr,
|
||||
0.0f, 0.0f, false, 3);
|
||||
0.0f, 0.0f,
|
||||
nullptr, PocvMode::scalar, 3);
|
||||
EXPECT_FALSE(report.empty());
|
||||
EXPECT_NE(report.find("Check"), std::string::npos);
|
||||
}
|
||||
|
|
@ -1505,24 +1510,24 @@ TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) {
|
|||
TEST(InternalPowerTest, ModelAccess) {
|
||||
InternalPowerModels models{};
|
||||
InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models);
|
||||
// Initially models should be nullptr
|
||||
EXPECT_EQ(pwr.model(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr);
|
||||
// Initially models should have null inner TableModel
|
||||
EXPECT_EQ(pwr.model(RiseFall::rise()).model(), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
|
||||
}
|
||||
|
||||
TEST(InternalPowerTest, WithModel) {
|
||||
// Create a minimal model: Table -> TableModel -> InternalPowerModel
|
||||
TablePtr tbl = std::make_shared<Table>(1.0f);
|
||||
TableModel *table_model = new TableModel(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
auto power_model = std::make_shared<InternalPowerModel>(table_model);
|
||||
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
InternalPowerModel power_model(table_model);
|
||||
|
||||
InternalPowerModels models{};
|
||||
models[RiseFall::riseIndex()] = power_model;
|
||||
InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models);
|
||||
EXPECT_EQ(pwr.model(RiseFall::rise()), power_model.get());
|
||||
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr);
|
||||
EXPECT_NE(pwr.model(RiseFall::rise()).model(), nullptr);
|
||||
EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3473,9 +3478,9 @@ TEST(LibertyUtilTest, PortLibertyToStaWithBrackets) {
|
|||
|
||||
TEST(InternalPowerModelTest, PowerLookupOrder0) {
|
||||
TablePtr tbl = std::make_shared<Table>(5.0f);
|
||||
TableModel *table_model = new TableModel(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
InternalPowerModel model(table_model);
|
||||
LibertyLibrary lib("test_lib", "test.lib");
|
||||
TestCell cell(&lib, "INV", "test.lib");
|
||||
|
|
@ -3485,9 +3490,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder0) {
|
|||
|
||||
TEST(InternalPowerModelTest, ReportPowerOrder0) {
|
||||
TablePtr tbl = std::make_shared<Table>(3.0f);
|
||||
TableModel *table_model = new TableModel(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
InternalPowerModel model(table_model);
|
||||
LibertyLibrary lib("test_lib", "test.lib");
|
||||
TestCell cell(&lib, "INV", "test.lib");
|
||||
|
|
@ -3505,9 +3510,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder1) {
|
|||
values.push_back(1.0f);
|
||||
values.push_back(3.0f);
|
||||
TablePtr tbl = std::make_shared<Table>(std::move(values), axis);
|
||||
TableModel *table_model = new TableModel(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
InternalPowerModel model(table_model);
|
||||
LibertyLibrary lib("test_lib", "test.lib");
|
||||
TestCell cell(&lib, "INV", "test.lib");
|
||||
|
|
@ -3529,9 +3534,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder2) {
|
|||
FloatSeq row1; row1.push_back(3.0f); row1.push_back(4.0f);
|
||||
values.push_back(std::move(row0)); values.push_back(std::move(row1));
|
||||
TablePtr tbl = std::make_shared<Table>(std::move(values), axis1, axis2);
|
||||
TableModel *table_model = new TableModel(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
|
||||
ScaleFactorType::internal_power,
|
||||
RiseFall::rise());
|
||||
InternalPowerModel model(table_model);
|
||||
LibertyLibrary lib("test_lib", "test.lib");
|
||||
TestCell cell(&lib, "INV", "test.lib");
|
||||
|
|
|
|||
|
|
@ -61,20 +61,20 @@ TEST_F(VerilogNamespaceTest, PortBusName) {
|
|||
// Test Verilog-to-STA conversion
|
||||
TEST_F(VerilogNamespaceTest, ModuleVerilogToSta) {
|
||||
std::string verilog_name = "top_module";
|
||||
std::string result = moduleVerilogToSta(&verilog_name);
|
||||
std::string result = moduleVerilogToSta(verilog_name);
|
||||
EXPECT_EQ(result, "top_module");
|
||||
}
|
||||
|
||||
TEST_F(VerilogNamespaceTest, InstanceVerilogToSta) {
|
||||
std::string verilog_name = "u1";
|
||||
std::string result = instanceVerilogToSta(&verilog_name);
|
||||
std::string result = instanceVerilogToSta(verilog_name);
|
||||
EXPECT_EQ(result, "u1");
|
||||
}
|
||||
|
||||
// Test escaped name round-trip
|
||||
TEST_F(VerilogNamespaceTest, EscapedNameRoundTrip) {
|
||||
std::string verilog_name = "\\esc_name ";
|
||||
std::string sta = instanceVerilogToSta(&verilog_name);
|
||||
std::string sta = instanceVerilogToSta(verilog_name);
|
||||
EXPECT_FALSE(sta.empty());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -886,7 +886,7 @@ TEST_F(VariablesTest, SetUseDefaultArrivalClock) {
|
|||
|
||||
TEST_F(VariablesTest, SetPocvEnabled) {
|
||||
Variables vars;
|
||||
vars.setPocvEnabled(true);
|
||||
vars.setPocvMode(PocvMode::normal);
|
||||
EXPECT_TRUE(vars.pocvEnabled());
|
||||
}
|
||||
|
||||
|
|
@ -2170,7 +2170,7 @@ TEST_F(SdcInitTest, GroupPathClone) {
|
|||
ExceptionPath *cloned = gp.clone(nullptr, nullptr, nullptr, true);
|
||||
EXPECT_NE(cloned, nullptr);
|
||||
EXPECT_TRUE(cloned->isGroupPath());
|
||||
EXPECT_STREQ(cloned->name(), "grp");
|
||||
EXPECT_EQ(cloned->name(), "grp");
|
||||
delete cloned;
|
||||
}
|
||||
|
||||
|
|
@ -2184,22 +2184,22 @@ TEST_F(SdcInitTest, FilterPathClone) {
|
|||
|
||||
TEST_F(SdcInitTest, FalsePathAsString) {
|
||||
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||||
const char *str = fp.asString(sta_->cmdNetwork());
|
||||
EXPECT_NE(str, nullptr);
|
||||
std::string str = fp.to_string(sta_->cmdNetwork());
|
||||
EXPECT_FALSE(str.empty());
|
||||
}
|
||||
|
||||
TEST_F(SdcInitTest, PathDelayAsString) {
|
||||
PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||||
1.0e-9f, true, nullptr);
|
||||
const char *str = pd.asString(sta_->cmdNetwork());
|
||||
EXPECT_NE(str, nullptr);
|
||||
std::string str = pd.to_string(sta_->cmdNetwork());
|
||||
EXPECT_FALSE(str.empty());
|
||||
}
|
||||
|
||||
TEST_F(SdcInitTest, MultiCyclePathAsString) {
|
||||
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||||
true, 2, true, nullptr);
|
||||
const char *str = mcp.asString(sta_->cmdNetwork());
|
||||
EXPECT_NE(str, nullptr);
|
||||
std::string str = mcp.to_string(sta_->cmdNetwork());
|
||||
EXPECT_FALSE(str.empty());
|
||||
}
|
||||
|
||||
// ExceptionPath type predicates
|
||||
|
|
@ -2320,7 +2320,7 @@ TEST_F(SdcInitTest, ExceptionPathDefaultHandlers) {
|
|||
EXPECT_FALSE(fp.useEndClk());
|
||||
EXPECT_EQ(fp.pathMultiplier(), 0);
|
||||
EXPECT_FLOAT_EQ(fp.delay(), 0.0f);
|
||||
EXPECT_EQ(fp.name(), nullptr);
|
||||
EXPECT_TRUE(fp.name().empty());
|
||||
EXPECT_FALSE(fp.isDefault());
|
||||
EXPECT_FALSE(fp.ignoreClkLatency());
|
||||
EXPECT_FALSE(fp.breakPath());
|
||||
|
|
@ -2641,8 +2641,8 @@ TEST_F(SdcInitTest, ClockEdgeDetails) {
|
|||
EXPECT_EQ(fall->transition(), RiseFall::fall());
|
||||
EXPECT_EQ(rise->opposite(), fall);
|
||||
EXPECT_EQ(fall->opposite(), rise);
|
||||
EXPECT_NE(rise->name(), nullptr);
|
||||
EXPECT_NE(fall->name(), nullptr);
|
||||
EXPECT_FALSE(rise->name().empty());
|
||||
EXPECT_FALSE(fall->name().empty());
|
||||
EXPECT_GE(rise->index(), 0);
|
||||
EXPECT_GE(fall->index(), 0);
|
||||
EXPECT_NE(rise->index(), fall->index());
|
||||
|
|
@ -2878,8 +2878,8 @@ TEST_F(SdcInitTest, SdcMakePathDelay) {
|
|||
TEST_F(SdcInitTest, SdcRemoveClockGroupsOther) {
|
||||
ASSERT_NO_THROW(( [&](){
|
||||
Sdc *sdc = sta_->cmdSdc();
|
||||
sdc->removeClockGroupsPhysicallyExclusive(nullptr);
|
||||
sdc->removeClockGroupsAsynchronous(nullptr);
|
||||
sdc->removeClockGroupsPhysicallyExclusive();
|
||||
sdc->removeClockGroupsAsynchronous();
|
||||
|
||||
}() ));
|
||||
}
|
||||
|
|
@ -3813,7 +3813,7 @@ TEST_F(SdcInitTest, VariablesSetUseDefaultArrivalClock) {
|
|||
|
||||
TEST_F(SdcInitTest, VariablesSetPocvEnabled) {
|
||||
Variables vars;
|
||||
vars.setPocvEnabled(true);
|
||||
vars.setPocvMode(PocvMode::normal);
|
||||
EXPECT_TRUE(vars.pocvEnabled());
|
||||
}
|
||||
|
||||
|
|
@ -4565,7 +4565,7 @@ TEST_F(SdcExceptionPathTest, GroupPathIsGroupPath) {
|
|||
GroupPath gp("grp", false, nullptr, nullptr, nullptr, true, nullptr);
|
||||
EXPECT_TRUE(gp.isGroupPath());
|
||||
EXPECT_FALSE(gp.isFalse());
|
||||
EXPECT_STREQ(gp.name(), "grp");
|
||||
EXPECT_EQ(gp.name(), "grp");
|
||||
EXPECT_FALSE(gp.isDefault());
|
||||
EXPECT_EQ(gp.type(), ExceptionPathType::group_path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,18 +84,18 @@ set_propagated_clock [get_clocks clk1]
|
|||
# set_clock_groups
|
||||
############################################################
|
||||
|
||||
set_clock_groups -logically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
set_clock_groups -name le_grp -logically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
|
||||
# Remove and re-add as physically exclusive
|
||||
unset_clock_groups -logically_exclusive -all
|
||||
unset_clock_groups -logically_exclusive -name le_grp
|
||||
|
||||
set_clock_groups -physically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
set_clock_groups -name pe_grp -physically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
|
||||
unset_clock_groups -physically_exclusive -all
|
||||
unset_clock_groups -physically_exclusive -name pe_grp
|
||||
|
||||
set_clock_groups -asynchronous -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
set_clock_groups -name async_grp -asynchronous -group [get_clocks clk1] -group [get_clocks clk2]
|
||||
|
||||
unset_clock_groups -asynchronous -all
|
||||
unset_clock_groups -asynchronous -name async_grp
|
||||
|
||||
############################################################
|
||||
# set_clock_sense
|
||||
|
|
|
|||
|
|
@ -1233,14 +1233,14 @@ TEST_F(ExceptionPathTest, GroupPathBasic) {
|
|||
EXPECT_FALSE(gp.isFalse());
|
||||
EXPECT_FALSE(gp.isPathDelay());
|
||||
EXPECT_EQ(gp.type(), ExceptionPathType::group_path);
|
||||
EXPECT_STREQ(gp.name(), "group1");
|
||||
EXPECT_EQ(gp.name(), "group1");
|
||||
EXPECT_FALSE(gp.isDefault());
|
||||
}
|
||||
|
||||
TEST_F(ExceptionPathTest, GroupPathDefault) {
|
||||
GroupPath gp("default_group", true, nullptr, nullptr, nullptr, true, nullptr);
|
||||
EXPECT_TRUE(gp.isDefault());
|
||||
EXPECT_STREQ(gp.name(), "default_group");
|
||||
EXPECT_EQ(gp.name(), "default_group");
|
||||
}
|
||||
|
||||
TEST_F(ExceptionPathTest, GroupPathTypePriority) {
|
||||
|
|
@ -1258,7 +1258,7 @@ TEST_F(ExceptionPathTest, GroupPathClone) {
|
|||
GroupPath gp("gp_clone", true, nullptr, nullptr, nullptr, true, "comment");
|
||||
ExceptionPath *clone = gp.clone(nullptr, nullptr, nullptr, true);
|
||||
EXPECT_TRUE(clone->isGroupPath());
|
||||
EXPECT_STREQ(clone->name(), "gp_clone");
|
||||
EXPECT_EQ(clone->name(), "gp_clone");
|
||||
EXPECT_TRUE(clone->isDefault());
|
||||
delete clone;
|
||||
}
|
||||
|
|
@ -1377,7 +1377,7 @@ TEST_F(ExceptionPathTest, DefaultValues) {
|
|||
EXPECT_FALSE(fp.useEndClk());
|
||||
EXPECT_EQ(fp.pathMultiplier(), 0);
|
||||
EXPECT_FLOAT_EQ(fp.delay(), 0.0f);
|
||||
EXPECT_EQ(fp.name(), nullptr);
|
||||
EXPECT_EQ(fp.name(), "");
|
||||
EXPECT_FALSE(fp.isDefault());
|
||||
EXPECT_FALSE(fp.ignoreClkLatency());
|
||||
EXPECT_FALSE(fp.breakPath());
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ TEST_F(SpiceSmokeTest, TransitionNames) {
|
|||
EXPECT_EQ(Transition::fall()->to_string(), "v");
|
||||
}
|
||||
|
||||
// Tests for streamPrint (free function in WriteSpice.cc)
|
||||
// Tests for print (Format.hh - formerly print)
|
||||
class StreamPrintTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
|
|
@ -63,7 +63,7 @@ protected:
|
|||
TEST_F(StreamPrintTest, BasicString) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "hello world\n");
|
||||
sta::print(out, "hello world\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -75,7 +75,7 @@ TEST_F(StreamPrintTest, BasicString) {
|
|||
TEST_F(StreamPrintTest, FormattedOutput) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "v%d %s 0 %.3f\n", 1, "node1", 1.800);
|
||||
sta::print(out, "v{} {} 0 {:.3f}\n", 1, "node1", 1.800);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -87,7 +87,7 @@ TEST_F(StreamPrintTest, FormattedOutput) {
|
|||
TEST_F(StreamPrintTest, ScientificNotation) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "C%d %s 0 %.3e\n", 1, "net1", 1.5e-12);
|
||||
sta::print(out, "C{} {} 0 {:.3e}\n", 1, "net1", 1.5e-12);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -99,9 +99,9 @@ TEST_F(StreamPrintTest, ScientificNotation) {
|
|||
TEST_F(StreamPrintTest, MultipleWrites) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "* Header\n");
|
||||
streamPrint(out, ".tran %.3g %.3g\n", 1e-13, 1e-9);
|
||||
streamPrint(out, ".end\n");
|
||||
sta::print(out, "* Header\n");
|
||||
sta::print(out, ".tran {:.3g} {:.3g}\n", 1e-13, 1e-9);
|
||||
sta::print(out, ".end\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -182,11 +182,11 @@ TEST_F(XyceCsvTest, FileNotReadableThrows) {
|
|||
);
|
||||
}
|
||||
|
||||
// Additional streamPrint tests for format coverage
|
||||
// Additional print tests for format coverage
|
||||
TEST_F(StreamPrintTest, EmptyString) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "%s", "");
|
||||
sta::print(out, "{}", "");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -200,7 +200,7 @@ TEST_F(StreamPrintTest, LongString) {
|
|||
ASSERT_TRUE(out.is_open());
|
||||
// Build a long subcircuit line
|
||||
std::string long_name(200, 'x');
|
||||
streamPrint(out, ".subckt %s\n", long_name.c_str());
|
||||
sta::print(out, ".subckt {}\n", long_name.c_str());
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -213,7 +213,7 @@ TEST_F(StreamPrintTest, LongString) {
|
|||
TEST_F(StreamPrintTest, SpiceResistor) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "R%d %s %s %.4e\n", 1, "n1", "n2", 1.0e3);
|
||||
sta::print(out, "R{} {} {} {:.4e}\n", 1, "n1", "n2", 1.0e3);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -227,7 +227,7 @@ TEST_F(StreamPrintTest, SpiceResistor) {
|
|||
TEST_F(StreamPrintTest, SpiceComment) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "* %s\n", "This is a SPICE comment");
|
||||
sta::print(out, "* {}\n", "This is a SPICE comment");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -240,7 +240,7 @@ TEST_F(StreamPrintTest, SpiceComment) {
|
|||
TEST_F(StreamPrintTest, SpiceSubcktInstantiation) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "x%s %s %s %s %s %s\n",
|
||||
sta::print(out, "x{} {} {} {} {} {}\n",
|
||||
"inst1", "vdd", "vss", "in", "out", "INV");
|
||||
out.close();
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ TEST_F(StreamPrintTest, SpiceSubcktInstantiation) {
|
|||
TEST_F(StreamPrintTest, SpiceMeasure) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".measure tran %s trig v(%s) val=%.1f %s=%.3e\n",
|
||||
sta::print(out, ".measure tran {} trig v({}) val={:.1f} {}={:.3e}\n",
|
||||
"delay", "in", 0.9, "targ", 1e-9);
|
||||
out.close();
|
||||
|
||||
|
|
@ -346,11 +346,11 @@ TEST_F(SpiceSmokeTest, TransitionInitFinalString) {
|
|||
// Additional SPICE tests for function coverage
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// streamPrint with integers
|
||||
// print with integers
|
||||
TEST_F(StreamPrintTest, IntegerFormats) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "R%d %d %d %d\n", 1, 100, 200, 50000);
|
||||
sta::print(out, "R{} {} {} {}\n", 1, 100, 200, 50000);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -359,11 +359,11 @@ TEST_F(StreamPrintTest, IntegerFormats) {
|
|||
EXPECT_EQ(line, "R1 100 200 50000");
|
||||
}
|
||||
|
||||
// streamPrint with mixed types
|
||||
// print with mixed types
|
||||
TEST_F(StreamPrintTest, MixedTypes) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".param %s=%g\n", "vdd", 1.8);
|
||||
sta::print(out, ".param {}={:g}\n", "vdd", 1.8);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -374,11 +374,11 @@ TEST_F(StreamPrintTest, MixedTypes) {
|
|||
EXPECT_NE(line.find("1.8"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint with percent
|
||||
// print with percent
|
||||
TEST_F(StreamPrintTest, PercentLiteral) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "value = 100%%\n");
|
||||
sta::print(out, "value = 100%\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -387,12 +387,12 @@ TEST_F(StreamPrintTest, PercentLiteral) {
|
|||
EXPECT_NE(line.find("100%"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint with very long format
|
||||
// print with very long format
|
||||
TEST_F(StreamPrintTest, VeryLongFormat) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
std::string long_name(500, 'n');
|
||||
streamPrint(out, ".subckt %s port1 port2 port3\n", long_name.c_str());
|
||||
sta::print(out, ".subckt {} port1 port2 port3\n", long_name.c_str());
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -502,11 +502,11 @@ TEST_F(SpiceSmokeTest, TransitionFind) {
|
|||
EXPECT_EQ(Transition::find("v"), Transition::fall());
|
||||
}
|
||||
|
||||
// Test streamPrint with empty format
|
||||
// Test print with empty format
|
||||
TEST_F(StreamPrintTest, EmptyFormat) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "%s", "");
|
||||
sta::print(out, "{}", "");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -515,11 +515,11 @@ TEST_F(StreamPrintTest, EmptyFormat) {
|
|||
EXPECT_EQ(content, "");
|
||||
}
|
||||
|
||||
// Test streamPrint with integer formatting
|
||||
// Test print with integer formatting
|
||||
TEST_F(StreamPrintTest, IntegerFormatting) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "R%d %d %d %.2f\n", 1, 10, 20, 100.5);
|
||||
sta::print(out, "R{} {} {} {:.2f}\n", 1, 10, 20, 100.5);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -528,13 +528,13 @@ TEST_F(StreamPrintTest, IntegerFormatting) {
|
|||
EXPECT_EQ(line, "R1 10 20 100.50");
|
||||
}
|
||||
|
||||
// Test streamPrint with multiple lines
|
||||
// Test print with multiple lines
|
||||
TEST_F(StreamPrintTest, MultipleLines) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "line1\n");
|
||||
streamPrint(out, "line2\n");
|
||||
streamPrint(out, "line3\n");
|
||||
sta::print(out, "line1\n");
|
||||
sta::print(out, "line2\n");
|
||||
sta::print(out, "line3\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -547,11 +547,11 @@ TEST_F(StreamPrintTest, MultipleLines) {
|
|||
EXPECT_EQ(line, "line3");
|
||||
}
|
||||
|
||||
// Test streamPrint with special characters
|
||||
// Test print with special characters
|
||||
TEST_F(StreamPrintTest, SpecialChars) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "* SPICE deck for %s\n", "test_design");
|
||||
sta::print(out, "* SPICE deck for {}\n", "test_design");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -609,12 +609,12 @@ TEST_F(SpiceSmokeTest, MinMaxOpposite) {
|
|||
// R6_ tests for Spice function coverage
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Test streamPrint with wide variety of format specifiers
|
||||
// Covers: streamPrint with many format types
|
||||
// Test print with wide variety of format specifiers
|
||||
// Covers: print with many format types
|
||||
TEST_F(StreamPrintTest, FormatSpecifiers) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "%c %s %d %f %e %g\n", 'A', "test", 42, 3.14, 1.5e-12, 1.8);
|
||||
sta::print(out, "{:c} {} {} {} {:e} {:g}\n", 'A', "test", 42, 3.14, 1.5e-12, 1.8);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -625,12 +625,12 @@ TEST_F(StreamPrintTest, FormatSpecifiers) {
|
|||
EXPECT_NE(line.find("42"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint with SPICE node naming
|
||||
// Covers: streamPrint for SPICE net naming patterns
|
||||
// Test print with SPICE node naming
|
||||
// Covers: print for SPICE net naming patterns
|
||||
TEST_F(StreamPrintTest, SpiceNodeNaming) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "C%d %s %s %.4e\n", 1, "n_top/sub/net:1", "0", 1.5e-15);
|
||||
sta::print(out, "C{} {} {} {:.4e}\n", 1, "n_top/sub/net:1", "0", 1.5e-15);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -640,12 +640,12 @@ TEST_F(StreamPrintTest, SpiceNodeNaming) {
|
|||
EXPECT_NE(line.find("n_top/sub/net:1"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint with SPICE .include directive
|
||||
// Covers: streamPrint for SPICE directives
|
||||
// Test print with SPICE .include directive
|
||||
// Covers: print for SPICE directives
|
||||
TEST_F(StreamPrintTest, SpiceIncludeDirective) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".include \"%s\"\n", "/path/to/models.spice");
|
||||
sta::print(out, ".include \"{}\"\n", "/path/to/models.spice");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -655,12 +655,12 @@ TEST_F(StreamPrintTest, SpiceIncludeDirective) {
|
|||
EXPECT_NE(line.find("/path/to/models.spice"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint SPICE voltage source
|
||||
// Covers: streamPrint for voltage sources
|
||||
// Test print SPICE voltage source
|
||||
// Covers: print for voltage sources
|
||||
TEST_F(StreamPrintTest, SpiceVoltageSource) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "v%s %s 0 %.3f\n", "dd", "vdd", 1.800);
|
||||
sta::print(out, "v{} {} 0 {:.3f}\n", "dd", "vdd", 1.800);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -669,12 +669,12 @@ TEST_F(StreamPrintTest, SpiceVoltageSource) {
|
|||
EXPECT_EQ(line, "vdd vdd 0 1.800");
|
||||
}
|
||||
|
||||
// Test streamPrint SPICE .tran with detailed parameters
|
||||
// Covers: streamPrint for transient analysis
|
||||
// Test print SPICE .tran with detailed parameters
|
||||
// Covers: print for transient analysis
|
||||
TEST_F(StreamPrintTest, SpiceTransAnalysis) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".tran %g %g %g %g\n", 1e-13, 5e-9, 0.0, 1e-12);
|
||||
sta::print(out, ".tran {:g} {:g} {:g} {:g}\n", 1e-13, 5e-9, 0.0, 1e-12);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -683,15 +683,15 @@ TEST_F(StreamPrintTest, SpiceTransAnalysis) {
|
|||
EXPECT_NE(line.find(".tran"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint SPICE PWL source
|
||||
// Covers: streamPrint with PWL voltage source
|
||||
// Test print SPICE PWL source
|
||||
// Covers: print with PWL voltage source
|
||||
TEST_F(StreamPrintTest, SpicePWLSource) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "v_in in 0 PWL(\n");
|
||||
streamPrint(out, "+%.3e %.3f\n", 0.0, 0.0);
|
||||
streamPrint(out, "+%.3e %.3f\n", 1e-10, 1.8);
|
||||
streamPrint(out, "+%.3e %.3f)\n", 2e-10, 1.8);
|
||||
sta::print(out, "v_in in 0 PWL(\n");
|
||||
sta::print(out, "+{:.3e} {:.3f}\n", 0.0, 0.0);
|
||||
sta::print(out, "+{:.3e} {:.3f}\n", 1e-10, 1.8);
|
||||
sta::print(out, "+{:.3e} {:.3f})\n", 2e-10, 1.8);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -812,12 +812,12 @@ TEST_F(SpiceSmokeTest, RiseFallShortName) {
|
|||
// R8_ tests for SPICE module coverage improvement
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Test streamPrint with SPICE transistor format (used in writeParasiticNetwork)
|
||||
// Covers: streamPrint paths used by WriteSpice
|
||||
// Test print with SPICE transistor format (used in writeParasiticNetwork)
|
||||
// Covers: print paths used by WriteSpice
|
||||
TEST_F(StreamPrintTest, SpiceTransistorFormat) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "M%d %s %s %s %s %s W=%.3e L=%.3e\n",
|
||||
sta::print(out, "M{} {} {} {} {} {} W={:.3e} L={:.3e}\n",
|
||||
1, "drain", "gate", "source", "bulk", "NMOS",
|
||||
1.0e-6, 45.0e-9);
|
||||
out.close();
|
||||
|
|
@ -830,13 +830,13 @@ TEST_F(StreamPrintTest, SpiceTransistorFormat) {
|
|||
EXPECT_NE(line.find("NMOS"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint with SPICE capacitor format (used in writeParasiticNetwork)
|
||||
// Covers: streamPrint paths used by WriteSpice::writeParasiticNetwork
|
||||
// Test print with SPICE capacitor format (used in writeParasiticNetwork)
|
||||
// Covers: print paths used by WriteSpice::writeParasiticNetwork
|
||||
TEST_F(StreamPrintTest, SpiceCapacitorFormat) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "C%d %s %s %.4e\n", 1, "net1:1", "0", 1.5e-15);
|
||||
streamPrint(out, "C%d %s %s %.4e\n", 2, "net1:2", "net1:3", 2.5e-15);
|
||||
sta::print(out, "C{} {} {} {:.4e}\n", 1, "net1:1", "0", 1.5e-15);
|
||||
sta::print(out, "C{} {} {} {:.4e}\n", 2, "net1:2", "net1:3", 2.5e-15);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -847,12 +847,12 @@ TEST_F(StreamPrintTest, SpiceCapacitorFormat) {
|
|||
EXPECT_TRUE(line2.find("C2") == 0);
|
||||
}
|
||||
|
||||
// Test streamPrint with SPICE voltage source (used in writeClkedStepSource)
|
||||
// Covers: streamPrint paths used by WriteSpice::writeClkedStepSource
|
||||
// Test print with SPICE voltage source (used in writeClkedStepSource)
|
||||
// Covers: print paths used by WriteSpice::writeClkedStepSource
|
||||
TEST_F(StreamPrintTest, SpiceVoltageSource2) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "v%s %s 0 pwl(0 %.3f %.3e %.3f)\n",
|
||||
sta::print(out, "v{} {} 0 pwl(0 {:.3f} {:.3e} {:.3f})\n",
|
||||
"clk", "clk_node", 0.0, 1e-9, 1.8);
|
||||
out.close();
|
||||
|
||||
|
|
@ -863,16 +863,16 @@ TEST_F(StreamPrintTest, SpiceVoltageSource2) {
|
|||
EXPECT_NE(line.find("pwl"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint with SPICE waveform format (used in writeWaveformVoltSource)
|
||||
// Covers: streamPrint paths used by WriteSpice::writeWaveformVoltSource
|
||||
// Test print with SPICE waveform format (used in writeWaveformVoltSource)
|
||||
// Covers: print paths used by WriteSpice::writeWaveformVoltSource
|
||||
TEST_F(StreamPrintTest, SpiceWaveformFormat) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "v%s %s 0 pwl(\n", "in", "in_node");
|
||||
streamPrint(out, "+ %.3e %.3f\n", 0.0, 0.0);
|
||||
streamPrint(out, "+ %.3e %.3f\n", 1e-10, 0.9);
|
||||
streamPrint(out, "+ %.3e %.3f\n", 2e-10, 1.8);
|
||||
streamPrint(out, "+)\n");
|
||||
sta::print(out, "v{} {} 0 pwl(\n", "in", "in_node");
|
||||
sta::print(out, "+ {:.3e} {:.3f}\n", 0.0, 0.0);
|
||||
sta::print(out, "+ {:.3e} {:.3f}\n", 1e-10, 0.9);
|
||||
sta::print(out, "+ {:.3e} {:.3f}\n", 2e-10, 1.8);
|
||||
sta::print(out, "+)\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -882,16 +882,16 @@ TEST_F(StreamPrintTest, SpiceWaveformFormat) {
|
|||
EXPECT_NE(content.find("pwl"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test streamPrint with SPICE .measure format (used in spiceTrans context)
|
||||
// Covers: streamPrint with RISE/FALL strings (used by WriteSpice::spiceTrans)
|
||||
// Test print with SPICE .measure format (used in spiceTrans context)
|
||||
// Covers: print with RISE/FALL strings (used by WriteSpice::spiceTrans)
|
||||
TEST_F(StreamPrintTest, SpiceMeasureRiseFall) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
// This mimics how spiceTrans returns RISE/FALL strings
|
||||
const char *rise_str = "RISE";
|
||||
const char *fall_str = "FALL";
|
||||
streamPrint(out, ".measure tran delay_rf trig v(in) val=0.9 %s=last\n", rise_str);
|
||||
streamPrint(out, "+targ v(out) val=0.9 %s=last\n", fall_str);
|
||||
sta::print(out, ".measure tran delay_rf trig v(in) val=0.9 {}=last\n", rise_str);
|
||||
sta::print(out, "+targ v(out) val=0.9 {}=last\n", fall_str);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -950,15 +950,15 @@ TEST_F(XyceCsvTest, ReadCsvManySignals) {
|
|||
// R9_ tests for SPICE module coverage improvement
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// streamPrint: SPICE subcircuit definition (used by WriteSpice)
|
||||
// print: SPICE subcircuit definition (used by WriteSpice)
|
||||
TEST_F(StreamPrintTest, SpiceSubcktDefinition) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".subckt %s %s %s %s %s\n",
|
||||
sta::print(out, ".subckt {} {} {} {} {}\n",
|
||||
"INV_X1", "VDD", "VSS", "A", "Y");
|
||||
streamPrint(out, "M1 Y A VDD VDD PMOS W=%.3e L=%.3e\n", 200e-9, 45e-9);
|
||||
streamPrint(out, "M2 Y A VSS VSS NMOS W=%.3e L=%.3e\n", 100e-9, 45e-9);
|
||||
streamPrint(out, ".ends %s\n", "INV_X1");
|
||||
sta::print(out, "M1 Y A VDD VDD PMOS W={:.3e} L={:.3e}\n", 200e-9, 45e-9);
|
||||
sta::print(out, "M2 Y A VSS VSS NMOS W={:.3e} L={:.3e}\n", 100e-9, 45e-9);
|
||||
sta::print(out, ".ends {}\n", "INV_X1");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -970,12 +970,12 @@ TEST_F(StreamPrintTest, SpiceSubcktDefinition) {
|
|||
EXPECT_NE(content.find("NMOS"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE resistor network (used in writeParasiticNetwork)
|
||||
// print: SPICE resistor network (used in writeParasiticNetwork)
|
||||
TEST_F(StreamPrintTest, SpiceResistorNetwork) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
streamPrint(out, "R%d n%d n%d %.4e\n", i+1, i, i+1, 50.0 + i*10.0);
|
||||
sta::print(out, "R{} n{} n{} {:.4e}\n", i+1, i, i+1, 50.0 + i*10.0);
|
||||
}
|
||||
out.close();
|
||||
|
||||
|
|
@ -986,12 +986,12 @@ TEST_F(StreamPrintTest, SpiceResistorNetwork) {
|
|||
EXPECT_NE(content.find("R10"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE capacitor network (used in writeParasiticNetwork)
|
||||
// print: SPICE capacitor network (used in writeParasiticNetwork)
|
||||
TEST_F(StreamPrintTest, SpiceCapacitorNetwork) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
streamPrint(out, "C%d n%d 0 %.4e\n", i+1, i, 1e-15 * (i+1));
|
||||
sta::print(out, "C{} n{} 0 {:.4e}\n", i+1, i, 1e-15 * (i+1));
|
||||
}
|
||||
out.close();
|
||||
|
||||
|
|
@ -1002,11 +1002,11 @@ TEST_F(StreamPrintTest, SpiceCapacitorNetwork) {
|
|||
EXPECT_NE(content.find("C10"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE .lib directive
|
||||
// print: SPICE .lib directive
|
||||
TEST_F(StreamPrintTest, SpiceLibDirective) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".lib '%s' %s\n", "/path/to/models.lib", "tt");
|
||||
sta::print(out, ".lib '{}' {}\n", "/path/to/models.lib", "tt");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -1016,11 +1016,11 @@ TEST_F(StreamPrintTest, SpiceLibDirective) {
|
|||
EXPECT_NE(line.find("tt"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE .option directive
|
||||
// print: SPICE .option directive
|
||||
TEST_F(StreamPrintTest, SpiceOptionDirective) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".option %s=%g %s=%g\n", "reltol", 1e-6, "abstol", 1e-12);
|
||||
sta::print(out, ".option {}={:g} {}={:g}\n", "reltol", 1e-6, "abstol", 1e-12);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -1030,11 +1030,11 @@ TEST_F(StreamPrintTest, SpiceOptionDirective) {
|
|||
EXPECT_NE(line.find("reltol"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE .print directive
|
||||
// print: SPICE .print directive
|
||||
TEST_F(StreamPrintTest, SpicePrintDirective) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".print tran v(%s) v(%s) v(%s)\n",
|
||||
sta::print(out, ".print tran v({}) v({}) v({})\n",
|
||||
"input", "output", "clk");
|
||||
out.close();
|
||||
|
||||
|
|
@ -1046,11 +1046,11 @@ TEST_F(StreamPrintTest, SpicePrintDirective) {
|
|||
EXPECT_NE(line.find("v(output)"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE pulse source
|
||||
// print: SPICE pulse source
|
||||
TEST_F(StreamPrintTest, SpicePulseSource) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "v%s %s 0 PULSE(%.3f %.3f %.3e %.3e %.3e %.3e %.3e)\n",
|
||||
sta::print(out, "v{} {} 0 PULSE({:.3f} {:.3f} {:.3e} {:.3e} {:.3e} {:.3e} {:.3e})\n",
|
||||
"clk", "clk_node", 0.0, 1.8, 0.0, 20e-12, 20e-12, 500e-12, 1e-9);
|
||||
out.close();
|
||||
|
||||
|
|
@ -1061,13 +1061,13 @@ TEST_F(StreamPrintTest, SpicePulseSource) {
|
|||
EXPECT_NE(line.find("PULSE"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE mutual inductance
|
||||
// print: SPICE mutual inductance
|
||||
TEST_F(StreamPrintTest, SpiceMutualInductance) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "L%d %s %s %.4e\n", 1, "n1", "n2", 1e-9);
|
||||
streamPrint(out, "L%d %s %s %.4e\n", 2, "n3", "n4", 1e-9);
|
||||
streamPrint(out, "K%d L%d L%d %.4f\n", 1, 1, 2, 0.5);
|
||||
sta::print(out, "L{} {} {} {:.4e}\n", 1, "n1", "n2", 1e-9);
|
||||
sta::print(out, "L{} {} {} {:.4e}\n", 2, "n3", "n4", 1e-9);
|
||||
sta::print(out, "K{} L{} L{} {:.4f}\n", 1, 1, 2, 0.5);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -1077,11 +1077,11 @@ TEST_F(StreamPrintTest, SpiceMutualInductance) {
|
|||
EXPECT_NE(content.find("K1"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE probe statement
|
||||
// print: SPICE probe statement
|
||||
TEST_F(StreamPrintTest, SpiceProbeStatement) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".probe v(%s) v(%s) i(%s)\n",
|
||||
sta::print(out, ".probe v({}) v({}) i({})\n",
|
||||
"out", "in", "v_supply");
|
||||
out.close();
|
||||
|
||||
|
|
@ -1091,12 +1091,12 @@ TEST_F(StreamPrintTest, SpiceProbeStatement) {
|
|||
EXPECT_NE(line.find(".probe"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE with escaped characters
|
||||
// print: SPICE with escaped characters
|
||||
TEST_F(StreamPrintTest, SpiceEscapedChars) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "* Node: %s\n", "top/sub/inst:pin");
|
||||
streamPrint(out, "R1 %s %s %.4e\n",
|
||||
sta::print(out, "* Node: {}\n", "top/sub/inst:pin");
|
||||
sta::print(out, "R1 {} {} {:.4e}\n",
|
||||
"top/sub/inst:pin", "top/sub/inst:int", 100.0);
|
||||
out.close();
|
||||
|
||||
|
|
@ -1106,25 +1106,25 @@ TEST_F(StreamPrintTest, SpiceEscapedChars) {
|
|||
EXPECT_NE(content.find("top/sub/inst:pin"), std::string::npos);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE full deck structure
|
||||
// print: SPICE full deck structure
|
||||
TEST_F(StreamPrintTest, SpiceFullDeck) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "* Full SPICE deck\n");
|
||||
streamPrint(out, ".include \"%s\"\n", "models.spice");
|
||||
streamPrint(out, ".subckt top VDD VSS IN OUT\n");
|
||||
streamPrint(out, "R1 IN n1 %.2e\n", 50.0);
|
||||
streamPrint(out, "C1 n1 VSS %.4e\n", 1e-15);
|
||||
streamPrint(out, "xinv VDD VSS n1 OUT INV_X1\n");
|
||||
streamPrint(out, ".ends top\n");
|
||||
streamPrint(out, "\n");
|
||||
streamPrint(out, "xinst VDD VSS IN OUT top\n");
|
||||
streamPrint(out, "vvdd VDD 0 %.3f\n", 1.8);
|
||||
streamPrint(out, "vvss VSS 0 0\n");
|
||||
streamPrint(out, "vin IN 0 PULSE(0 %.3f 0 %.3e %.3e %.3e %.3e)\n",
|
||||
sta::print(out, "* Full SPICE deck\n");
|
||||
sta::print(out, ".include \"{}\"\n", "models.spice");
|
||||
sta::print(out, ".subckt top VDD VSS IN OUT\n");
|
||||
sta::print(out, "R1 IN n1 {:.2e}\n", 50.0);
|
||||
sta::print(out, "C1 n1 VSS {:.4e}\n", 1e-15);
|
||||
sta::print(out, "xinv VDD VSS n1 OUT INV_X1\n");
|
||||
sta::print(out, ".ends top\n");
|
||||
sta::print(out, "\n");
|
||||
sta::print(out, "xinst VDD VSS IN OUT top\n");
|
||||
sta::print(out, "vvdd VDD 0 {:.3f}\n", 1.8);
|
||||
sta::print(out, "vvss VSS 0 0\n");
|
||||
sta::print(out, "vin IN 0 PULSE(0 {:.3f} 0 {:.3e} {:.3e} {:.3e} {:.3e})\n",
|
||||
1.8, 20e-12, 20e-12, 500e-12, 1e-9);
|
||||
streamPrint(out, ".tran %.3e %.3e\n", 1e-13, 2e-9);
|
||||
streamPrint(out, ".end\n");
|
||||
sta::print(out, ".tran {:.3e} {:.3e}\n", 1e-13, 2e-9);
|
||||
sta::print(out, ".end\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -1345,11 +1345,11 @@ TEST_F(XyceCsvTest, ReadCsvAlternatingSign) {
|
|||
EXPECT_EQ(waveforms.size(), 1u);
|
||||
}
|
||||
|
||||
// streamPrint: SPICE .end directive
|
||||
// print: SPICE .end directive
|
||||
TEST_F(StreamPrintTest, SpiceEndDirective) {
|
||||
std::ofstream out(tmpfile_);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, ".end\n");
|
||||
sta::print(out, ".end\n");
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpfile_);
|
||||
|
|
@ -1734,7 +1734,7 @@ TEST_F(SpiceDesignTest, InstanceCellName) {
|
|||
EXPECT_STREQ(cell_name, "DFF_X1");
|
||||
}
|
||||
|
||||
// Verify streamPrint with SPICE subcircuit instance format for design cells
|
||||
// Verify print with SPICE subcircuit instance format for design cells
|
||||
TEST_F(SpiceDesignTest, StreamPrintSubcktInst) {
|
||||
char tmpl[] = "/tmp/sta_spice_subckt_inst_XXXXXX";
|
||||
int fd = mkstemp(tmpl);
|
||||
|
|
@ -1749,7 +1749,7 @@ TEST_F(SpiceDesignTest, StreamPrintSubcktInst) {
|
|||
|
||||
std::ofstream out(tmpl);
|
||||
ASSERT_TRUE(out.is_open());
|
||||
streamPrint(out, "x%s VDD VSS %s\n", inst_name, cell_name);
|
||||
sta::print(out, "x{} VDD VSS {}\n", inst_name, cell_name);
|
||||
out.close();
|
||||
|
||||
std::ifstream in(tmpl);
|
||||
|
|
|
|||
|
|
@ -842,7 +842,7 @@ TEST(ReportTest, RedirectStringBasic)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLineString("hello world");
|
||||
report.reportLine("hello world");
|
||||
const char *result = report.redirectStringEnd();
|
||||
EXPECT_NE(result, nullptr);
|
||||
std::string s(result);
|
||||
|
|
@ -853,8 +853,8 @@ TEST(ReportTest, RedirectStringMultipleLines)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLineString("line1");
|
||||
report.reportLineString("line2");
|
||||
report.reportLine("line1");
|
||||
report.reportLine("line2");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("line1"), std::string::npos);
|
||||
|
|
@ -866,7 +866,7 @@ TEST(ReportTest, RedirectStringStdString)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string line = "std string line";
|
||||
report.reportLineString(line);
|
||||
report.reportLine(line);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("std string line"), std::string::npos);
|
||||
|
|
@ -886,7 +886,7 @@ TEST(ReportTest, ReportLineFormatted)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLine("value=%d", 42);
|
||||
report.report("value={}", 42);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("value=42"), std::string::npos);
|
||||
|
|
@ -897,7 +897,7 @@ TEST(ReportTest, LogToFile)
|
|||
Report report;
|
||||
const char *tmpfile = "/tmp/test_report_log.txt";
|
||||
report.logBegin(tmpfile);
|
||||
report.reportLineString("log test line");
|
||||
report.reportLine("log test line");
|
||||
report.logEnd();
|
||||
// Verify file was created with content
|
||||
FILE *f = fopen(tmpfile, "r");
|
||||
|
|
@ -924,7 +924,7 @@ TEST(ReportTest, RedirectFileBegin)
|
|||
Report report;
|
||||
const char *tmpfile = "/tmp/test_report_redirect.txt";
|
||||
report.redirectFileBegin(tmpfile);
|
||||
report.reportLineString("redirected line");
|
||||
report.reportLine("redirected line");
|
||||
report.redirectFileEnd();
|
||||
|
||||
FILE *f = fopen(tmpfile, "r");
|
||||
|
|
@ -943,12 +943,12 @@ TEST(ReportTest, RedirectFileAppendBegin)
|
|||
|
||||
// Write first
|
||||
report.redirectFileBegin(tmpfile);
|
||||
report.reportLineString("first");
|
||||
report.reportLine("first");
|
||||
report.redirectFileEnd();
|
||||
|
||||
// Append
|
||||
report.redirectFileAppendBegin(tmpfile);
|
||||
report.reportLineString("second");
|
||||
report.reportLine("second");
|
||||
report.redirectFileEnd();
|
||||
|
||||
FILE *f = fopen(tmpfile, "r");
|
||||
|
|
@ -997,7 +997,7 @@ TEST(ReportTest, WarnBasic)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.warn(100, "something bad %d", 42);
|
||||
report.warn(100, "something bad {}", 42);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 100:"), std::string::npos);
|
||||
|
|
@ -1008,7 +1008,7 @@ TEST(ReportTest, FileWarn)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.fileWarn(101, "test.v", 10, "missing %s", "semicolon");
|
||||
report.fileWarn(101, "test.v", 10, "missing {}", "semicolon");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 101:"), std::string::npos);
|
||||
|
|
@ -1022,7 +1022,7 @@ TEST(ReportTest, VwarnBasic)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
// Use vwarn indirectly via warn (vwarn is called by warn internals)
|
||||
report.warn(102, "vwarn test %s", "value");
|
||||
report.warn(102, "warn test {}", "value");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 102:"), std::string::npos);
|
||||
|
|
@ -1031,14 +1031,14 @@ TEST(ReportTest, VwarnBasic)
|
|||
TEST(ReportTest, ErrorThrows)
|
||||
{
|
||||
Report report;
|
||||
EXPECT_THROW(report.error(200, "error message %d", 1), ExceptionMsg);
|
||||
EXPECT_THROW(report.error(200, "error message {}", 1), ExceptionMsg);
|
||||
}
|
||||
|
||||
TEST(ReportTest, ErrorMessageContent)
|
||||
{
|
||||
Report report;
|
||||
try {
|
||||
report.error(200, "specific error %s", "info");
|
||||
report.error(200, "specific error {}", "info");
|
||||
FAIL() << "Expected ExceptionMsg";
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
|
|
@ -1056,7 +1056,7 @@ TEST(ReportTest, FileErrorContent)
|
|||
{
|
||||
Report report;
|
||||
try {
|
||||
report.fileError(201, "test.sdc", 5, "unexpected token %s", "foo");
|
||||
report.fileError(201, "test.sdc", 5, "unexpected token {}", "foo");
|
||||
FAIL() << "Expected ExceptionMsg";
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
|
|
@ -1146,7 +1146,7 @@ TEST(ReportTest, LogAndConsoleSimultaneous)
|
|||
const char *logfile = "/tmp/test_report_logconsole.txt";
|
||||
report.logBegin(logfile);
|
||||
// Print to console (with log capturing)
|
||||
report.reportLineString("dual output");
|
||||
report.reportLine("dual output");
|
||||
report.logEnd();
|
||||
|
||||
FILE *f = fopen(logfile, "r");
|
||||
|
|
@ -1177,38 +1177,35 @@ TEST(StringUtilTest, StringCopyNull)
|
|||
EXPECT_EQ(copy, nullptr);
|
||||
}
|
||||
|
||||
TEST(StringUtilTest, StdstrPrint)
|
||||
TEST(StringUtilTest, StaFormat)
|
||||
{
|
||||
std::string s = stdstrPrint("value=%d", 42);
|
||||
std::string s = sta::format("value={}", 42);
|
||||
EXPECT_EQ(s, "value=42");
|
||||
}
|
||||
|
||||
TEST(StringUtilTest, StringPrintToStdString)
|
||||
TEST(StringUtilTest, StaFormatToStdString)
|
||||
{
|
||||
std::string s;
|
||||
stringPrint(s, "test %s %d", "abc", 123);
|
||||
std::string s = sta::format("test {} {}", "abc", 123);
|
||||
EXPECT_EQ(s, "test abc 123");
|
||||
}
|
||||
|
||||
TEST(StringUtilTest, StringAppendToStdString)
|
||||
TEST(StringUtilTest, StaFormatAppendToStdString)
|
||||
{
|
||||
std::string s = "prefix ";
|
||||
stringAppend(s, "suffix %d", 1);
|
||||
s += sta::format("suffix {}", 1);
|
||||
EXPECT_EQ(s, "prefix suffix 1");
|
||||
}
|
||||
|
||||
TEST(StringUtilTest, StringPrintAllocates)
|
||||
TEST(StringUtilTest, StaFormatAllocates)
|
||||
{
|
||||
char *s = stringPrint("number %d", 99);
|
||||
EXPECT_STREQ(s, "number 99");
|
||||
stringDelete(s);
|
||||
std::string s = sta::format("number {}", 99);
|
||||
EXPECT_EQ(s, "number 99");
|
||||
}
|
||||
|
||||
TEST(StringUtilTest, StringPrintTmp)
|
||||
TEST(StringUtilTest, StaFormatTmp)
|
||||
{
|
||||
char *s = stringPrintTmp("tmp %d", 42);
|
||||
EXPECT_STREQ(s, "tmp 42");
|
||||
// tmp strings should not be freed by the caller
|
||||
std::string s = sta::format("tmp {}", 42);
|
||||
EXPECT_EQ(s, "tmp 42");
|
||||
}
|
||||
|
||||
TEST(StringUtilTest, MakeTmpString)
|
||||
|
|
@ -1229,7 +1226,8 @@ TEST(StringUtilTest, MakeTmpStringFromStdString)
|
|||
|
||||
TEST(StringUtilTest, IsTmpString)
|
||||
{
|
||||
char *tmp = stringPrintTmp("test");
|
||||
char *tmp = makeTmpString(10);
|
||||
strcpy(tmp, "test");
|
||||
EXPECT_TRUE(isTmpString(tmp));
|
||||
|
||||
char local[] = "local";
|
||||
|
|
@ -1370,7 +1368,7 @@ TEST(DebugTest, ReportLine)
|
|||
debug.setLevel("test", 1);
|
||||
// Redirect output to string to capture the debug line
|
||||
report.redirectStringBegin();
|
||||
debug.reportLine("test", "value %d", 42);
|
||||
debug.report("test", "value {}", 42);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("test"), std::string::npos);
|
||||
|
|
@ -1378,125 +1376,91 @@ TEST(DebugTest, ReportLine)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Helper functions to test va_list variants of Report
|
||||
// Tests for variadic template Report methods (warn, fileWarn, error, fileError)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static void callVwarn(Report &report, int id, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
report.vwarn(id, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void callVfileWarn(Report &report, int id, const char *filename,
|
||||
int line, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
report.vfileWarn(id, filename, line, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void callVerror(Report &report, int id, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
report.verror(id, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void callVfileError(Report &report, int id, const char *filename,
|
||||
int line, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
report.vfileError(id, filename, line, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VwarnBasic)
|
||||
TEST(ReportVaTest, WarnBasic)
|
||||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
callVwarn(report, 300, "vwarn message %d", 42);
|
||||
report.warn(300, "warn message {}", 42);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 300:"), std::string::npos);
|
||||
EXPECT_NE(s.find("vwarn message 42"), std::string::npos);
|
||||
EXPECT_NE(s.find("warn message 42"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VwarnSuppressed)
|
||||
TEST(ReportVaTest, WarnSuppressed)
|
||||
{
|
||||
Report report;
|
||||
report.suppressMsgId(300);
|
||||
report.redirectStringBegin();
|
||||
callVwarn(report, 300, "suppressed vwarn");
|
||||
report.warn(300, "suppressed warn");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_EQ(s.find("suppressed vwarn"), std::string::npos);
|
||||
EXPECT_EQ(s.find("suppressed warn"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VfileWarnBasic)
|
||||
TEST(ReportVaTest, FileWarnBasic)
|
||||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
callVfileWarn(report, 301, "test.v", 15, "vfile warn msg %s", "detail");
|
||||
report.fileWarn(301, "test.v", 15, "file warn msg {}", "detail");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 301:"), std::string::npos);
|
||||
EXPECT_NE(s.find("test.v"), std::string::npos);
|
||||
EXPECT_NE(s.find("line 15"), std::string::npos);
|
||||
EXPECT_NE(s.find("vfile warn msg detail"), std::string::npos);
|
||||
EXPECT_NE(s.find("file warn msg detail"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VfileWarnSuppressed)
|
||||
TEST(ReportVaTest, FileWarnSuppressed)
|
||||
{
|
||||
Report report;
|
||||
report.suppressMsgId(301);
|
||||
report.redirectStringBegin();
|
||||
callVfileWarn(report, 301, "test.v", 15, "suppressed vfile warn");
|
||||
report.fileWarn(301, "test.v", 15, "suppressed file warn");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_EQ(s.find("suppressed vfile warn"), std::string::npos);
|
||||
EXPECT_EQ(s.find("suppressed file warn"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VerrorThrows)
|
||||
TEST(ReportVaTest, ErrorThrows)
|
||||
{
|
||||
Report report;
|
||||
EXPECT_THROW(callVerror(report, 400, "verror msg %d", 99), ExceptionMsg);
|
||||
EXPECT_THROW(report.error(400, "error msg {}", 99), ExceptionMsg);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VerrorContent)
|
||||
TEST(ReportVaTest, ErrorContent)
|
||||
{
|
||||
Report report;
|
||||
try {
|
||||
callVerror(report, 400, "verror content %s", "test");
|
||||
report.error(400, "error content {}", "test");
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
EXPECT_NE(what.find("verror content test"), std::string::npos);
|
||||
EXPECT_NE(what.find("error content test"), std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VfileErrorThrows)
|
||||
TEST(ReportVaTest, FileErrorThrows)
|
||||
{
|
||||
Report report;
|
||||
EXPECT_THROW(callVfileError(report, 401, "myfile.sdc", 20, "vfile error msg"),
|
||||
EXPECT_THROW(report.fileError(401, "myfile.sdc", 20, "file error msg"),
|
||||
ExceptionMsg);
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VfileErrorContent)
|
||||
TEST(ReportVaTest, FileErrorContent)
|
||||
{
|
||||
Report report;
|
||||
try {
|
||||
callVfileError(report, 401, "myfile.sdc", 20, "vfile error %d", 42);
|
||||
report.fileError(401, "myfile.sdc", 20, "file error {}", 42);
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
EXPECT_NE(what.find("myfile.sdc"), std::string::npos);
|
||||
EXPECT_NE(what.find("line 20"), std::string::npos);
|
||||
EXPECT_NE(what.find("vfile error 42"), std::string::npos);
|
||||
EXPECT_NE(what.find("file error 42"), std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1507,7 +1471,7 @@ TEST(ReportTest, LongReportLine)
|
|||
report.redirectStringBegin();
|
||||
// Create a string longer than the initial 1000 char buffer
|
||||
std::string long_str(2000, 'x');
|
||||
report.reportLine("%s", long_str.c_str());
|
||||
report.reportLine(long_str);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find(long_str), std::string::npos);
|
||||
|
|
@ -1518,7 +1482,7 @@ TEST(ReportTest, LongWarnLine)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string long_str(2000, 'y');
|
||||
report.warn(500, "%s", long_str.c_str());
|
||||
report.warn(500, "{}", long_str);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 500:"), std::string::npos);
|
||||
|
|
@ -1526,23 +1490,23 @@ TEST(ReportTest, LongWarnLine)
|
|||
}
|
||||
|
||||
// Test ExceptionMsg suppressed flag
|
||||
TEST(ReportVaTest, VerrorSuppressedFlag)
|
||||
TEST(ReportVaTest, ErrorSuppressedFlag)
|
||||
{
|
||||
Report report;
|
||||
report.suppressMsgId(400);
|
||||
try {
|
||||
callVerror(report, 400, "suppressed verror");
|
||||
report.error(400, "suppressed error");
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
EXPECT_TRUE(e.suppressed());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ReportVaTest, VerrorNotSuppressedFlag)
|
||||
TEST(ReportVaTest, ErrorNotSuppressedFlag)
|
||||
{
|
||||
Report report;
|
||||
try {
|
||||
callVerror(report, 400, "not suppressed");
|
||||
report.error(400, "not suppressed");
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
EXPECT_FALSE(e.suppressed());
|
||||
|
|
@ -1820,19 +1784,18 @@ TEST(TransitionCovTest, RiseFallToString)
|
|||
// Additional StringUtil coverage
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(StringUtilCovTest, StringPrintArgs)
|
||||
TEST(StringUtilCovTest, StaFormatArgs)
|
||||
{
|
||||
// stringPrintArgs is called by stringPrint internally; test via stringPrint
|
||||
char *s = stringPrint("args test %d %s", 42, "hello");
|
||||
EXPECT_STREQ(s, "args test 42 hello");
|
||||
stringDelete(s);
|
||||
// Test sta::format with multiple arguments
|
||||
std::string s = sta::format("args test {} {}", 42, "hello");
|
||||
EXPECT_EQ(s, "args test 42 hello");
|
||||
}
|
||||
|
||||
// stringDeleteCheck (only for non-tmp strings - should not crash)
|
||||
TEST(StringUtilCovTest, StringDeleteCheckNonTmp)
|
||||
{
|
||||
ASSERT_NO_THROW(( [&](){
|
||||
char *s = stringPrint("not tmp");
|
||||
char *s = stringCopy("not tmp");
|
||||
// This should not crash or exit; it's not a tmp string
|
||||
stringDeleteCheck(s);
|
||||
stringDelete(s);
|
||||
|
|
@ -1849,23 +1812,21 @@ TEST(StringUtilCovTest, IsTmpStringHeap)
|
|||
delete [] s;
|
||||
}
|
||||
|
||||
// Long stringPrintTmp (forces buffer growth)
|
||||
TEST(StringUtilCovTest, LongStringPrintTmp)
|
||||
// Long sta::format string
|
||||
TEST(StringUtilCovTest, LongStaFormat)
|
||||
{
|
||||
std::string long_str(500, 'z');
|
||||
char *tmp = stringPrintTmp("%s", long_str.c_str());
|
||||
EXPECT_STREQ(tmp, long_str.c_str());
|
||||
std::string result = sta::format("{}", long_str);
|
||||
EXPECT_EQ(result, long_str);
|
||||
}
|
||||
|
||||
// stringAppend (char* version) inline in header
|
||||
TEST(StringUtilCovTest, StringAppendCharPtr)
|
||||
// std::string append
|
||||
TEST(StringUtilCovTest, StringAppendStd)
|
||||
{
|
||||
char buf[100];
|
||||
char *p = buf;
|
||||
stringAppend(p, "hello");
|
||||
stringAppend(p, " world");
|
||||
*p = '\0';
|
||||
EXPECT_STREQ(buf, "hello world");
|
||||
std::string s;
|
||||
s += "hello";
|
||||
s += " world";
|
||||
EXPECT_EQ(s, "hello world");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1886,7 +1847,7 @@ TEST(ReportCovTest, ReportLineStringEmpty)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLineString("");
|
||||
report.reportLine("");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
// Empty line should just have a newline
|
||||
|
|
@ -1899,7 +1860,7 @@ TEST(ReportCovTest, ReportLineLongFormatted)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string fmt_str(2000, 'a');
|
||||
report.reportLine("%s end", fmt_str.c_str());
|
||||
report.report("{} end", fmt_str);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find(fmt_str), std::string::npos);
|
||||
|
|
@ -1914,12 +1875,12 @@ TEST(ReportCovTest, ReportRedirectSequence)
|
|||
|
||||
// Redirect to file first
|
||||
report.redirectFileBegin(tmpfile);
|
||||
report.reportLineString("file output");
|
||||
report.reportLine("file output");
|
||||
report.redirectFileEnd();
|
||||
|
||||
// Then redirect to string
|
||||
report.redirectStringBegin();
|
||||
report.reportLineString("string output");
|
||||
report.reportLine("string output");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("string output"), std::string::npos);
|
||||
|
|
@ -1935,7 +1896,7 @@ TEST(ReportCovTest, LogDuringStringRedirect)
|
|||
|
||||
report.logBegin(logfile);
|
||||
report.redirectStringBegin();
|
||||
report.reportLineString("string only");
|
||||
report.reportLine("string only");
|
||||
const char *result = report.redirectStringEnd();
|
||||
report.logEnd();
|
||||
|
||||
|
|
@ -1950,7 +1911,7 @@ TEST(ReportCovTest, WarnWithLongMessage)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string long_msg(1500, 'w');
|
||||
report.warn(999, "prefix %s suffix", long_msg.c_str());
|
||||
report.warn(999, "prefix {} suffix", long_msg);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 999:"), std::string::npos);
|
||||
|
|
@ -1964,7 +1925,7 @@ TEST(ReportCovTest, FileWarnLongMessage)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string long_msg(1500, 'f');
|
||||
report.fileWarn(998, "bigfile.v", 100, "detail: %s", long_msg.c_str());
|
||||
report.fileWarn(998, "bigfile.v", 100, "detail: {}", long_msg);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 998:"), std::string::npos);
|
||||
|
|
@ -1978,7 +1939,7 @@ TEST(ReportCovTest, ErrorLongMessage)
|
|||
Report report;
|
||||
std::string long_msg(1500, 'e');
|
||||
try {
|
||||
report.error(997, "err: %s", long_msg.c_str());
|
||||
report.error(997, "err: {}", long_msg);
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
|
|
@ -1993,7 +1954,7 @@ TEST(ReportCovTest, FileErrorLongMessage)
|
|||
Report report;
|
||||
std::string long_msg(1500, 'x');
|
||||
try {
|
||||
report.fileError(996, "big.sdc", 50, "detail: %s", long_msg.c_str());
|
||||
report.fileError(996, "big.sdc", 50, "detail: {}", long_msg);
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
|
|
@ -2396,14 +2357,14 @@ TEST(ReportCovTest, RedirectStringPrintMultiple)
|
|||
EXPECT_STREQ(result, "abcdefghi");
|
||||
}
|
||||
|
||||
// Test Report printToBuffer with va_list
|
||||
// Covers: Report::printToBuffer(const char*, va_list)
|
||||
TEST(ReportCovTest, PrintToBufferViaReportLine)
|
||||
// Test Report::report with format args
|
||||
// Covers: Report::report(std::string_view, Args&&...)
|
||||
TEST(ReportCovTest, ReportFormatViaReport)
|
||||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
// reportLine calls printToBuffer internally
|
||||
report.reportLine("value=%d", 42);
|
||||
// report() uses std::format style formatting
|
||||
report.report("value={}", 42);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("value=42"), std::string::npos);
|
||||
|
|
@ -2414,7 +2375,7 @@ TEST(ReportCovTest, ReportLineString)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLineString("test line");
|
||||
report.reportLine("test line");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("test line"), std::string::npos);
|
||||
|
|
@ -2426,7 +2387,7 @@ TEST(ReportCovTest, ReportLineStringStd)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string line = "std string line";
|
||||
report.reportLineString(line);
|
||||
report.reportLine(line);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("std string line"), std::string::npos);
|
||||
|
|
@ -2461,7 +2422,7 @@ TEST(ReportStdCovTest, PrintErrorConsoleViaWarn)
|
|||
ASSERT_NO_THROW(( [&](){
|
||||
Report *report = makeReportStd();
|
||||
// warn uses printErrorConsole path
|
||||
report->warn(9999, "test warning %d", 42);
|
||||
report->warn(9999, "test warning {}", 42);
|
||||
delete report;
|
||||
|
||||
}() ));
|
||||
|
|
@ -2496,7 +2457,7 @@ TEST(ReportCovTest, LogBeginEnd)
|
|||
Report report;
|
||||
const char *logfile = "/tmp/sta_test_log_r5.log";
|
||||
report.logBegin(logfile);
|
||||
report.reportLine("log line %d", 1);
|
||||
report.report("log line {}", 1);
|
||||
report.logEnd();
|
||||
// Verify log file exists and has content
|
||||
std::ifstream in(logfile);
|
||||
|
|
@ -2590,7 +2551,7 @@ TEST(GzStreamTest, GzStreamWriteRead)
|
|||
TEST(ReportCovTest, ErrorThrowsException)
|
||||
{
|
||||
Report report;
|
||||
EXPECT_THROW(report.error(1, "test error %s", "msg"), ExceptionMsg);
|
||||
EXPECT_THROW(report.error(1, "test error {}", "msg"), ExceptionMsg);
|
||||
}
|
||||
|
||||
// Test Report fileError throws ExceptionMsg
|
||||
|
|
@ -2618,7 +2579,7 @@ TEST(ReportCovTest, ReportErrorFormatting)
|
|||
{
|
||||
Report report;
|
||||
try {
|
||||
report.error(999, "critical format test %s %d", "value", 42);
|
||||
report.error(999, "critical format test {} {}", "value", 42);
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
|
|
@ -2632,7 +2593,7 @@ TEST(ReportCovTest, ReportFileErrorFormatting)
|
|||
{
|
||||
Report report;
|
||||
try {
|
||||
report.fileError(998, "critical.v", 42, "critical file error %s", "detail");
|
||||
report.fileError(998, "critical.v", 42, "critical file error {}", "detail");
|
||||
FAIL();
|
||||
} catch (const ExceptionMsg &e) {
|
||||
std::string what = e.what();
|
||||
|
|
@ -2660,7 +2621,7 @@ TEST(ReportCovTest, ReportStdCreation)
|
|||
ASSERT_NE(report, nullptr);
|
||||
// Verify it works as a Report
|
||||
report->redirectStringBegin();
|
||||
report->reportLineString("test via ReportStd");
|
||||
report->reportLine("test via ReportStd");
|
||||
const char *result = report->redirectStringEnd();
|
||||
EXPECT_NE(result, nullptr);
|
||||
std::string s(result);
|
||||
|
|
@ -2675,7 +2636,7 @@ TEST(ReportCovTest, ReportStdWarn)
|
|||
Report *report = makeReportStd();
|
||||
ASSERT_NE(report, nullptr);
|
||||
report->redirectStringBegin();
|
||||
report->warn(700, "reportstd warn test %d", 99);
|
||||
report->warn(700, "reportstd warn test {}", 99);
|
||||
const char *result = report->redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 700:"), std::string::npos);
|
||||
|
|
@ -2701,7 +2662,7 @@ TEST(ReportCovTest, ReportPrintToBufferLong)
|
|||
report.redirectStringBegin();
|
||||
// Create a string exceeding the initial 1000-char buffer
|
||||
std::string long_str(3000, 'Z');
|
||||
report.reportLine("%s", long_str.c_str());
|
||||
report.reportLine(long_str);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find(long_str), std::string::npos);
|
||||
|
|
@ -2780,7 +2741,7 @@ TEST(ReportCovTest, WarnLongMessage)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string long_msg(5000, 'W');
|
||||
report.warn(800, "%s", long_msg.c_str());
|
||||
report.warn(800, "{}", long_msg);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 800:"), std::string::npos);
|
||||
|
|
@ -2794,7 +2755,7 @@ TEST(ReportCovTest, FileWarnLongMessage2)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string long_msg(2000, 'F');
|
||||
report.fileWarn(801, "long_file.v", 999, "%s", long_msg.c_str());
|
||||
report.fileWarn(801, "long_file.v", 999, "{}", long_msg);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning 801:"), std::string::npos);
|
||||
|
|
@ -2841,13 +2802,13 @@ TEST(ReportCovTest, ErrorNotSuppressed)
|
|||
// because it calls abort(). Instead, test printToBuffer and
|
||||
// redirectStringPrint paths.
|
||||
|
||||
// Test Report::printToBuffer via reportLine
|
||||
// Covers: Report::printToBuffer(const char*, va_list)
|
||||
TEST(ReportCovTest, PrintToBufferViaReportLine2)
|
||||
// Test Report::report with multiple format args
|
||||
// Covers: Report::report(std::string_view, Args&&...)
|
||||
TEST(ReportCovTest, ReportFormatViaReport2)
|
||||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLine("test %d %s %.2f", 42, "hello", 3.14);
|
||||
report.report("test {} {} {:.2f}", 42, "hello", 3.14);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("42"), std::string::npos);
|
||||
|
|
@ -2878,23 +2839,23 @@ TEST(ReportCovTest, RedirectStringPrintLong)
|
|||
Report report;
|
||||
report.redirectStringBegin();
|
||||
std::string long_str(5000, 'X');
|
||||
report.reportLineString(long_str);
|
||||
report.reportLine(long_str);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("XXXXX"), std::string::npos);
|
||||
}
|
||||
|
||||
// Test Report::printToBuffer with various format strings
|
||||
// Covers: Report::printToBuffer(const char*, va_list)
|
||||
TEST(ReportCovTest, PrintToBufferFormats)
|
||||
// Test Report::report with various format strings
|
||||
// Covers: Report::report(std::string_view, Args&&...)
|
||||
TEST(ReportCovTest, ReportFormatVariousFormats)
|
||||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
// Exercise various printf formats
|
||||
report.reportLine("int: %d", 12345);
|
||||
report.reportLine("float: %f", 1.5);
|
||||
report.reportLine("string: %s", "test_string");
|
||||
report.reportLine("hex: %x", 0xFF);
|
||||
// Exercise various std::format specifiers
|
||||
report.report("int: {}", 12345);
|
||||
report.report("float: {}", 1.5);
|
||||
report.report("string: {}", "test_string");
|
||||
report.report("hex: {:x}", 0xFF);
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("12345"), std::string::npos);
|
||||
|
|
@ -2908,9 +2869,9 @@ TEST(ReportStdCovTest, ReportStdConstructorAndPrint)
|
|||
Report *report = makeReportStd();
|
||||
ASSERT_NE(report, nullptr);
|
||||
// warn() calls printErrorConsole
|
||||
report->warn(10001, "R8 test warning %s", "message");
|
||||
report->warn(10001, "R8 test warning {}", "message");
|
||||
// reportLine calls printConsole
|
||||
report->reportLine("R8 test print %d", 42);
|
||||
report->report("R8 test print {}", 42);
|
||||
delete report;
|
||||
}
|
||||
|
||||
|
|
@ -2920,7 +2881,7 @@ TEST(ReportStdCovTest, PrintErrorConsoleViaFileWarn)
|
|||
{
|
||||
Report *report = makeReportStd();
|
||||
ASSERT_NE(report, nullptr);
|
||||
report->fileWarn(10002, "test_file.v", 100, "file warning %d", 99);
|
||||
report->fileWarn(10002, "test_file.v", 100, "file warning {}", 99);
|
||||
delete report;
|
||||
}
|
||||
|
||||
|
|
@ -2930,7 +2891,7 @@ TEST(ReportCovTest, PrintToBufferEmpty)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.reportLine("%s", "");
|
||||
report.reportLine("");
|
||||
const char *result = report.redirectStringEnd();
|
||||
// Should have at least a newline
|
||||
EXPECT_NE(result, nullptr);
|
||||
|
|
@ -2942,7 +2903,7 @@ TEST(ReportCovTest, WarnWithRedirect)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.warn(10003, "warning %d: %s", 1, "test");
|
||||
report.warn(10003, "warning {}: {}", 1, "test");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning"), std::string::npos);
|
||||
|
|
@ -2955,7 +2916,7 @@ TEST(ReportCovTest, FileWarnWithRedirect)
|
|||
{
|
||||
Report report;
|
||||
report.redirectStringBegin();
|
||||
report.fileWarn(10004, "myfile.tcl", 42, "file issue %s", "here");
|
||||
report.fileWarn(10004, "myfile.tcl", 42, "file issue {}", "here");
|
||||
const char *result = report.redirectStringEnd();
|
||||
std::string s(result);
|
||||
EXPECT_NE(s.find("Warning"), std::string::npos);
|
||||
|
|
|
|||
|
|
@ -51,31 +51,31 @@ TEST_F(VerilogTest, InstanceWithSlash) {
|
|||
// Verilog to STA conversions
|
||||
TEST_F(VerilogTest, ModuleToSta) {
|
||||
std::string name = "top";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
EXPECT_EQ(result, "top");
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, InstanceToSta) {
|
||||
std::string name = "inst1";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_EQ(result, "inst1");
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, EscapedToSta) {
|
||||
std::string name = "\\esc_name ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, NetToSta) {
|
||||
std::string name = "net1";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_EQ(result, "net1");
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, PortToSta) {
|
||||
std::string name = "port_a";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_EQ(result, "port_a");
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ TEST_F(VerilogTest, CellEscapePrefix) {
|
|||
// Verilog-to-STA conversions with escaped names
|
||||
TEST_F(VerilogTest, EscapedModuleToSta) {
|
||||
std::string name = "\\my/module ";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
// Should strip leading \ and trailing space, but escape special chars
|
||||
EXPECT_FALSE(result.empty());
|
||||
EXPECT_NE(result.front(), '\\');
|
||||
|
|
@ -173,38 +173,38 @@ TEST_F(VerilogTest, EscapedModuleToSta) {
|
|||
|
||||
TEST_F(VerilogTest, EscapedNetToSta) {
|
||||
std::string name = "\\net[0] ";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, EscapedPortToSta) {
|
||||
std::string name = "\\port/a ";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, PlainModuleToSta) {
|
||||
std::string name = "top_module";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
EXPECT_EQ(result, "top_module");
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, PlainNetToSta) {
|
||||
std::string name = "wire1";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_EQ(result, "wire1");
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, PlainPortToSta) {
|
||||
std::string name = "port_b";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_EQ(result, "port_b");
|
||||
}
|
||||
|
||||
// Escaped name with brackets (bus notation)
|
||||
TEST_F(VerilogTest, EscapedInstanceWithBracket) {
|
||||
std::string name = "\\inst[0] ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
// Brackets should be escaped in STA name
|
||||
EXPECT_NE(result.find("\\["), std::string::npos);
|
||||
|
|
@ -213,7 +213,7 @@ TEST_F(VerilogTest, EscapedInstanceWithBracket) {
|
|||
// Escaped name with divider
|
||||
TEST_F(VerilogTest, EscapedInstanceWithDivider) {
|
||||
std::string name = "\\u1/u2 ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
// Divider should be escaped in STA name
|
||||
EXPECT_NE(result.find("\\/"), std::string::npos);
|
||||
|
|
@ -222,14 +222,14 @@ TEST_F(VerilogTest, EscapedInstanceWithDivider) {
|
|||
// Escaped name with escape character
|
||||
TEST_F(VerilogTest, EscapedNameWithEscapeChar) {
|
||||
std::string name = "\\esc\\val ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
// Escaped name without trailing space
|
||||
TEST_F(VerilogTest, EscapedNoTrailingSpace) {
|
||||
std::string name = "\\esc_name";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
|
|
@ -303,7 +303,7 @@ TEST_F(VerilogTest, InstanceWithAt) {
|
|||
// verilogToSta: escaped name with multiple special chars
|
||||
TEST_F(VerilogTest, EscapedMultipleSpecial) {
|
||||
std::string name = "\\u1/u2[3] ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
// Both / and [ and ] should be escaped
|
||||
EXPECT_NE(result.find("\\/"), std::string::npos);
|
||||
|
|
@ -314,7 +314,7 @@ TEST_F(VerilogTest, EscapedMultipleSpecial) {
|
|||
// verilogToSta: escaped name with backslash inside
|
||||
TEST_F(VerilogTest, EscapedWithBackslash) {
|
||||
std::string name = "\\a\\b ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
// The backslash inside should be escaped as \\
|
||||
EXPECT_NE(result.find("\\\\"), std::string::npos);
|
||||
|
|
@ -342,25 +342,25 @@ TEST_F(VerilogTest, CellDoubleBackslash) {
|
|||
// netVerilogToSta with plain name
|
||||
TEST_F(VerilogTest, NetToStaPlain) {
|
||||
std::string name = "simple_wire";
|
||||
EXPECT_EQ(netVerilogToSta(&name), "simple_wire");
|
||||
EXPECT_EQ(netVerilogToSta(name), "simple_wire");
|
||||
}
|
||||
|
||||
// portVerilogToSta with plain name
|
||||
TEST_F(VerilogTest, PortToStaPlain) {
|
||||
std::string name = "port_clk";
|
||||
EXPECT_EQ(portVerilogToSta(&name), "port_clk");
|
||||
EXPECT_EQ(portVerilogToSta(name), "port_clk");
|
||||
}
|
||||
|
||||
// moduleVerilogToSta plain
|
||||
TEST_F(VerilogTest, ModuleToStaPlain) {
|
||||
std::string name = "mod_top";
|
||||
EXPECT_EQ(moduleVerilogToSta(&name), "mod_top");
|
||||
EXPECT_EQ(moduleVerilogToSta(name), "mod_top");
|
||||
}
|
||||
|
||||
// verilogToSta: escaped name without trailing space
|
||||
TEST_F(VerilogTest, EscapedNoSpace) {
|
||||
std::string name = "\\name";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
// "ame" (without leading 'n' because 'n' is first char after \ which is stripped)
|
||||
// Actually: ignoring leading '\', copy the rest. "name" has no trailing space.
|
||||
|
|
@ -421,14 +421,14 @@ TEST_F(VerilogTest, InstanceWithBrackets) {
|
|||
// verilogToSta: empty escaped name
|
||||
TEST_F(VerilogTest, EmptyEscapedName) {
|
||||
std::string name = "\\";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_TRUE(result.empty());
|
||||
}
|
||||
|
||||
// verilogToSta: escaped name with only space
|
||||
TEST_F(VerilogTest, EscapedOnlySpace) {
|
||||
std::string name = "\\ ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_TRUE(result.empty());
|
||||
}
|
||||
|
||||
|
|
@ -454,28 +454,28 @@ TEST_F(VerilogTest, CellOnlySpecialChars) {
|
|||
// instanceVerilogToSta: plain unescaped name
|
||||
TEST_F(VerilogTest, UnescapedInstance) {
|
||||
std::string name = "plain_inst";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_EQ(result, "plain_inst");
|
||||
}
|
||||
|
||||
// netVerilogToSta: escaped name with bus notation
|
||||
TEST_F(VerilogTest, EscapedNetBus) {
|
||||
std::string name = "\\data[7:0] ";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
// moduleVerilogToSta: escaped module name
|
||||
TEST_F(VerilogTest, EscapedModule) {
|
||||
std::string name = "\\mod/special ";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
// portVerilogToSta: escaped port name
|
||||
TEST_F(VerilogTest, EscapedPort) {
|
||||
std::string name = "\\port$gen ";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +521,7 @@ TEST_F(VerilogTest, PortWithPlus) {
|
|||
// instanceVerilogToSta: escaped name with various special chars
|
||||
TEST_F(VerilogTest, EscapedInstanceComplex) {
|
||||
std::string name = "\\inst.a/b[c] ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
// The result should contain the original special characters in some form
|
||||
EXPECT_GT(result.size(), 3u);
|
||||
|
|
@ -530,21 +530,21 @@ TEST_F(VerilogTest, EscapedInstanceComplex) {
|
|||
// netVerilogToSta: plain net with underscore
|
||||
TEST_F(VerilogTest, PlainNetUnderscore) {
|
||||
std::string name = "_net_wire_";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_EQ(result, "_net_wire_");
|
||||
}
|
||||
|
||||
// portVerilogToSta: plain port with numbers
|
||||
TEST_F(VerilogTest, PlainPortNumeric) {
|
||||
std::string name = "port_123";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_EQ(result, "port_123");
|
||||
}
|
||||
|
||||
// moduleVerilogToSta: plain module with mixed case
|
||||
TEST_F(VerilogTest, PlainModuleMixedCase) {
|
||||
std::string name = "MyModule_V2";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
EXPECT_EQ(result, "MyModule_V2");
|
||||
}
|
||||
|
||||
|
|
@ -575,14 +575,14 @@ TEST_F(VerilogTest, PortWithPipe) {
|
|||
// instanceVerilogToSta: escaped name without trailing space (edge case)
|
||||
TEST_F(VerilogTest, EscapedNoTrailingSpaceComplex) {
|
||||
std::string name = "\\inst/a[0]";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
// cellVerilogName: very long name
|
||||
TEST_F(VerilogTest, CellLongName) {
|
||||
std::string long_name(200, 'a');
|
||||
std::string result = cellVerilogName(long_name.c_str());
|
||||
std::string result = cellVerilogName(long_name);
|
||||
EXPECT_EQ(result, long_name);
|
||||
}
|
||||
|
||||
|
|
@ -590,7 +590,7 @@ TEST_F(VerilogTest, CellLongName) {
|
|||
TEST_F(VerilogTest, CellLongEscapedName) {
|
||||
std::string long_name(200, 'a');
|
||||
long_name[100] = '/';
|
||||
std::string result = cellVerilogName(long_name.c_str());
|
||||
std::string result = cellVerilogName(long_name);
|
||||
EXPECT_EQ(result.front(), '\\');
|
||||
EXPECT_EQ(result.back(), ' ');
|
||||
}
|
||||
|
|
@ -1014,21 +1014,21 @@ TEST_F(VerilogTest, InstanceWithLessThan) {
|
|||
// VerilogToSta: net with bus range
|
||||
TEST_F(VerilogTest, EscapedNetRange) {
|
||||
std::string name = "\\data[7:0] ";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
// VerilogToSta: module with digit prefix
|
||||
TEST_F(VerilogTest, ModuleDigitPrefix) {
|
||||
std::string name = "123module";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
EXPECT_EQ(result, "123module");
|
||||
}
|
||||
|
||||
// portVerilogToSta: escaped
|
||||
TEST_F(VerilogTest, EscapedPortComplex) {
|
||||
std::string name = "\\port.a[0]/b ";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1036,7 +1036,7 @@ TEST_F(VerilogTest, EscapedPortComplex) {
|
|||
TEST_F(VerilogTest, RoundTripSpecialCell) {
|
||||
// STA name with escaped bracket
|
||||
std::string sta_name = "cell\\[0\\]";
|
||||
std::string verilog = cellVerilogName(sta_name.c_str());
|
||||
std::string verilog = cellVerilogName(sta_name);
|
||||
EXPECT_FALSE(verilog.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1427,25 +1427,25 @@ TEST_F(VerilogTest, PortNameWithBacktick) {
|
|||
// Verilog to STA conversions: edge cases
|
||||
TEST_F(VerilogTest, EscapedInstanceOnlyBrackets) {
|
||||
std::string name = "\\[0] ";
|
||||
std::string result = instanceVerilogToSta(&name);
|
||||
std::string result = instanceVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, EscapedNetOnlySlash) {
|
||||
std::string name = "\\/ ";
|
||||
std::string result = netVerilogToSta(&name);
|
||||
std::string result = netVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, ModuleToStaEscapedComplex) {
|
||||
std::string name = "\\mod.a/b[1] ";
|
||||
std::string result = moduleVerilogToSta(&name);
|
||||
std::string result = moduleVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, PortToStaEscapedBracket) {
|
||||
std::string name = "\\port[3] ";
|
||||
std::string result = portVerilogToSta(&name);
|
||||
std::string result = portVerilogToSta(name);
|
||||
EXPECT_FALSE(result.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1727,35 +1727,35 @@ TEST_F(VerilogTest, PortNameMixedSpecial) {
|
|||
// Round-trip tests: staToVerilog -> verilogToSta should preserve identity for simple names
|
||||
TEST_F(VerilogTest, RoundTripSimpleName) {
|
||||
std::string sta_name = "simple_wire";
|
||||
std::string verilog = netVerilogName(sta_name.c_str());
|
||||
std::string back = netVerilogToSta(&verilog);
|
||||
std::string verilog = netVerilogName(sta_name);
|
||||
std::string back = netVerilogToSta(verilog);
|
||||
EXPECT_EQ(back, sta_name);
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, RoundTripSimpleCell) {
|
||||
std::string sta_name = "my_cell_123";
|
||||
std::string verilog = cellVerilogName(sta_name.c_str());
|
||||
std::string verilog = cellVerilogName(sta_name);
|
||||
EXPECT_EQ(verilog, sta_name); // no escaping needed
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, RoundTripSimpleInstance) {
|
||||
std::string sta_name = "u1_abc";
|
||||
std::string verilog = instanceVerilogName(sta_name.c_str());
|
||||
std::string back = instanceVerilogToSta(&verilog);
|
||||
std::string verilog = instanceVerilogName(sta_name);
|
||||
std::string back = instanceVerilogToSta(verilog);
|
||||
EXPECT_EQ(back, sta_name);
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, RoundTripSimplePort) {
|
||||
std::string sta_name = "clk_in";
|
||||
std::string verilog = portVerilogName(sta_name.c_str());
|
||||
std::string back = portVerilogToSta(&verilog);
|
||||
std::string verilog = portVerilogName(sta_name);
|
||||
std::string back = portVerilogToSta(verilog);
|
||||
EXPECT_EQ(back, sta_name);
|
||||
}
|
||||
|
||||
TEST_F(VerilogTest, RoundTripSimpleModule) {
|
||||
std::string sta_name = "top_module";
|
||||
std::string verilog = cellVerilogName(sta_name.c_str());
|
||||
std::string back = moduleVerilogToSta(&verilog);
|
||||
std::string verilog = cellVerilogName(sta_name);
|
||||
std::string back = moduleVerilogToSta(verilog);
|
||||
EXPECT_EQ(back, sta_name);
|
||||
}
|
||||
|
||||
|
|
@ -1802,7 +1802,7 @@ TEST_F(VerilogTest, DclBusPortName) {
|
|||
TEST_F(VerilogTest, NetBusRangeConversion) {
|
||||
// Verilog bus notation should convert properly
|
||||
std::string verilog_name = "data[3]";
|
||||
std::string net_name = netVerilogToSta(&verilog_name);
|
||||
std::string net_name = netVerilogToSta(verilog_name);
|
||||
EXPECT_FALSE(net_name.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1838,7 +1838,7 @@ TEST_F(VerilogTest, EmptyNames) {
|
|||
// Covers: netVerilogToSta with bus notation
|
||||
TEST_F(VerilogTest, BusVerilogToSta) {
|
||||
std::string verilog_name = "bus[7:0]";
|
||||
std::string bus = netVerilogToSta(&verilog_name);
|
||||
std::string bus = netVerilogToSta(verilog_name);
|
||||
EXPECT_FALSE(bus.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1846,7 +1846,7 @@ TEST_F(VerilogTest, BusVerilogToSta) {
|
|||
// Covers: instanceVerilogToSta with escaped name
|
||||
TEST_F(VerilogTest, EscapedInstanceToSta) {
|
||||
std::string verilog_name = "\\inst[0] ";
|
||||
std::string name = instanceVerilogToSta(&verilog_name);
|
||||
std::string name = instanceVerilogToSta(verilog_name);
|
||||
EXPECT_FALSE(name.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1854,10 +1854,10 @@ TEST_F(VerilogTest, EscapedInstanceToSta) {
|
|||
// Covers: netVerilogToSta bracket handling
|
||||
TEST_F(VerilogTest, NetVerilogToStaBrackets) {
|
||||
std::string name1 = "wire1";
|
||||
std::string net1 = netVerilogToSta(&name1);
|
||||
std::string net1 = netVerilogToSta(name1);
|
||||
EXPECT_EQ(net1, "wire1");
|
||||
std::string name2 = "bus[0]";
|
||||
std::string net2 = netVerilogToSta(&name2);
|
||||
std::string net2 = netVerilogToSta(name2);
|
||||
EXPECT_FALSE(net2.empty());
|
||||
}
|
||||
|
||||
|
|
@ -1893,7 +1893,7 @@ TEST_F(VerilogTest, PortHierSep) {
|
|||
// Covers: instanceVerilogToSta simple case
|
||||
TEST_F(VerilogTest, InstanceToStaSimple) {
|
||||
std::string verilog_name = "u1";
|
||||
std::string name = instanceVerilogToSta(&verilog_name);
|
||||
std::string name = instanceVerilogToSta(verilog_name);
|
||||
EXPECT_EQ(name, "u1");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue