diff --git a/dcalc/DmpDelayCalc.cc b/dcalc/DmpDelayCalc.cc index 03fbe83e5..00a619976 100644 --- a/dcalc/DmpDelayCalc.cc +++ b/dcalc/DmpDelayCalc.cc @@ -148,6 +148,11 @@ class DmpCeffTwoPoleDelayCalc : public DmpCeffDelayCalc const RiseFall *rf, const Scene *scene, const MinMax *min_max) override; + Parasitic *reduceParasitic(const Parasitic *parasitic_network, + const Pin *drvr_pin, + const RiseFall *rf, + const Scene *scene, + const MinMax *min_max) override; ArcDcalcResult inputPortDelay(const Pin *port_pin, float in_slew, const RiseFall *rf, @@ -165,6 +170,8 @@ class DmpCeffTwoPoleDelayCalc : public DmpCeffDelayCalc const MinMax *min_max) override; protected: + using ArcDelayCalc::reduceParasitic; + void loadDelaySlew(const Pin *load_pin, double drvr_slew, const RiseFall *rf, @@ -257,6 +264,18 @@ DmpCeffTwoPoleDelayCalc::findParasitic(const Pin *drvr_pin, return parasitic; } +Parasitic * +DmpCeffTwoPoleDelayCalc::reduceParasitic(const Parasitic *parasitic_network, + const Pin *drvr_pin, + const RiseFall *rf, + const Scene *scene, + const MinMax *min_max) +{ + Parasitics *parasitics = scene->parasitics(min_max); + return parasitics->reduceToPiPoleResidue2( + parasitic_network, drvr_pin, rf, scene, min_max); +} + ArcDcalcResult DmpCeffTwoPoleDelayCalc::inputPortDelay(const Pin *, float in_slew, diff --git a/dcalc/test/cpp/TestDcalc.cc b/dcalc/test/cpp/TestDcalc.cc index 7b461fdf2..f82d9a7b5 100644 --- a/dcalc/test/cpp/TestDcalc.cc +++ b/dcalc/test/cpp/TestDcalc.cc @@ -3592,6 +3592,46 @@ TEST_F(DesignDcalcTest, DmpCeffTwoPoleWithParasitics) { EXPECT_GT(graph->vertexCount(), 0); } +TEST_F(DesignDcalcTest, DmpCeffTwoPoleReducesToPiPoleResidue) { + ASSERT_TRUE(design_loaded_); + Scene *corner = sta_->cmdScene(); + Network *network = sta_->network(); + Instance *top = network->topInstance(); + const bool read_spef = sta_->readSpef("spef", + "test/reg1_asap7.spef", + top, + corner, + MinMaxAll::all(), + false, + false, + 1.0f, + false); + ASSERT_TRUE(read_spef); + + Instance *u1 = network->findChild(top, "u1"); + ASSERT_NE(u1, nullptr); + Pin *y_pin = network->findPin(u1, "Y"); + ASSERT_NE(y_pin, nullptr); + const Net *net = network->net(y_pin); + ASSERT_NE(net, nullptr); + + Parasitics *parasitics = sta_->findParasitics("spef"); + ASSERT_NE(parasitics, nullptr); + Parasitic *network_parasitic = parasitics->findParasiticNetwork(net); + ASSERT_NE(network_parasitic, nullptr); + + ArcDelayCalc *calc = makeDelayCalc("dmp_ceff_two_pole", sta_); + ASSERT_NE(calc, nullptr); + Parasitic *reduced = calc->reduceParasitic(network_parasitic, + y_pin, + RiseFall::rise(), + corner, + MinMax::max()); + ASSERT_NE(reduced, nullptr); + EXPECT_TRUE(parasitics->isPiPoleResidue(reduced)); + delete calc; +} + // R10_ DesignDcalcTest: reportDelayCalc exercises report path // Covers: GraphDelayCalc::reportDelayCalc TEST_F(DesignDcalcTest, ReportDelayCalcDmpElmore2) {