From 66d0914e4c1b3936f2acefe6590c434c39ff5cd8 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 25 Aug 2024 19:05:34 -0500 Subject: [PATCH 1/5] set_false_path -through genclk src pin Signed-off-by: James Cherry --- sdc/Sdc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index ee14c6c1..f02b9d6a 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -5240,6 +5240,8 @@ Sdc::exceptionFromClkStates(const Pin *pin, exceptionFromStates(first_from_inst_exceptions_.findKey(inst), pin, rf, min_max, true, states); } + exceptionThruStates(first_thru_pin_exceptions_.findKey(pin), + rf, min_max, states); } if (!first_from_clk_exceptions_.empty()) exceptionFromStates(first_from_clk_exceptions_.findKey(clk), From 253b6bf458e78c87209956c6168bd928e3a5e0c5 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 3 Sep 2024 19:02:55 -0300 Subject: [PATCH 2/5] add cell footprint support Signed-off-by: Arthur Koucher --- include/sta/EquivCells.hh | 4 ++++ include/sta/Liberty.hh | 7 +++++++ liberty/EquivCells.cc | 10 +++++++++- liberty/Liberty.cc | 27 ++++++++++++++++++++++++++- liberty/LibertyReader.cc | 25 +++++++++++++++++++++++++ liberty/LibertyReaderPvt.hh | 4 ++++ 6 files changed, 75 insertions(+), 2 deletions(-) diff --git a/include/sta/EquivCells.hh b/include/sta/EquivCells.hh index d695b79b..400e1ec7 100644 --- a/include/sta/EquivCells.hh +++ b/include/sta/EquivCells.hh @@ -73,4 +73,8 @@ bool equivCellSequentials(const LibertyCell *cell1, const LibertyCell *cell2); +bool +equivCellFootprints(const LibertyCell *cell1, + const LibertyCell *cell2); + } // namespace diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 4763a8d0..8b568ae3 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -83,6 +83,8 @@ typedef Map SupplyVoltageMap; typedef Map LibertyPgPortMap; typedef Map DriverWaveformMap; typedef Vector DcalcAnalysisPtSeq; +typedef int LibertyCellFootprintIndex; +typedef Vector LibertyCellFootprintSeq; enum class ClockGateType { none, latch_posedge, latch_negedge, other }; @@ -142,6 +144,7 @@ public: // Liberty cells that are buffers. LibertyCellSeq *buffers(); LibertyCellSeq *inverters(); + void addFootprint(const char *footprint); DelayModelType delayModelType() const { return delay_model_type_; } void setDelayModelType(DelayModelType type); @@ -371,6 +374,7 @@ protected: SupplyVoltageMap supply_voltage_map_; LibertyCellSeq *buffers_; LibertyCellSeq *inverters_; + LibertyCellFootprintSeq footprints_; DriverWaveformMap driver_waveform_map_; // Unnamed driver waveform. DriverWaveform *driver_waveform_default_; @@ -541,6 +545,8 @@ public: // for all the defined corners. static void checkLibertyCorners(); void ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps); + void setFootprintIndex(LibertyCellFootprintIndex footprint_index); + const char *footprint() const; protected: void addPort(ConcretePort *port); @@ -631,6 +637,7 @@ protected: bool has_internal_ports_; bool have_voltage_waveforms_; std::mutex waveform_lock_; + LibertyCellFootprintIndex footprint_index_; private: friend class LibertyLibrary; diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index 5e43cb98..a9a74130 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -325,7 +325,8 @@ equivCells(const LibertyCell *cell1, && equivCellPgPorts(cell1, cell2) && equivCellSequentials(cell1, cell2) && equivCellStatetables(cell1, cell2) - && equivCellTimingArcSets(cell1, cell2); + && equivCellTimingArcSets(cell1, cell2) + && equivCellFootprints(cell1, cell2); } bool @@ -525,4 +526,11 @@ equivCellTimingArcSets(const LibertyCell *cell1, } } +bool +equivCellFootprints(const LibertyCell *cell1, + const LibertyCell *cell2) +{ + return strcmp(cell1->footprint(), cell2->footprint()) == 0; +} + } // namespace diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index ac15e702..173b233d 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -128,6 +128,9 @@ LibertyLibrary::~LibertyLibrary() delete inverters_; driver_waveform_map_.deleteContents(); delete driver_waveform_default_; + + for (auto footprint : footprints_) + stringDelete(footprint); } LibertyCell * @@ -181,6 +184,12 @@ LibertyLibrary::buffers() return buffers_; } +void +LibertyLibrary::addFootprint(const char *footprint) +{ + footprints_.push_back(stringCopy(footprint)); +} + void LibertyLibrary::setDelayModelType(DelayModelType type) { @@ -940,7 +949,8 @@ LibertyCell::LibertyCell(LibertyLibrary *library, leakage_power_(0.0), leakage_power_exists_(false), has_internal_ports_(false), - have_voltage_waveforms_(false) + have_voltage_waveforms_(false), + footprint_index_(-1) { liberty_cell_ = this; } @@ -1989,6 +1999,21 @@ LibertyCell::ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps) } } +void +LibertyCell::setFootprintIndex(LibertyCellFootprintIndex footprint_index) +{ + footprint_index_ = footprint_index; +} + +const char* +LibertyCell::footprint() const +{ + if (footprint_index_ != -1) { + return libertyLibrary()->footprints_[footprint_index_]; + } + return ""; +} + //////////////////////////////////////////////////////////////// LibertyCellPortIterator::LibertyCellPortIterator(const LibertyCell *cell) : diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index b5033005..1bc00da2 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -310,6 +310,7 @@ LibertyReader::defineVisitors() defineAttrVisitor("switch_cell_type", &LibertyReader::visitSwitchCellType); defineAttrVisitor("interface_timing", &LibertyReader::visitInterfaceTiming); defineAttrVisitor("scaling_factors", &LibertyReader::visitScalingFactors); + defineAttrVisitor("cell_footprint", &LibertyReader::visitCellFootprint); // Pins defineGroupVisitor("pin", &LibertyReader::beginPin,&LibertyReader::endPin); @@ -725,6 +726,9 @@ LibertyReader::endLibraryAttrs(LibertyGroup *group) if (missing_threshold) libError(1149, group, "Library %s is missing one or more thresholds.", library_->name()); + + for (auto [footprint, footprint_index] : footprint_index_map_) + stringDelete(footprint); } void @@ -3065,6 +3069,27 @@ LibertyReader::visitClockGatingIntegratedCell(LibertyAttr *attr) } } +void +LibertyReader::visitCellFootprint(LibertyAttr *attr) +{ + if (cell_) { + const char *footprint = getAttrString(attr); + if (!footprint) { + return; + } + LibertyCellFootprintIndex footprint_index; + auto itr = footprint_index_map_.find(footprint); + if (itr != footprint_index_map_.end()) { + footprint_index = itr->second; + } else { + footprint_index = static_cast(footprint_index_map_.size()); + footprint_index_map_[stringCopy(footprint)] = footprint_index; + library()->addFootprint(stringCopy(footprint)); + } + cell_->setFootprintIndex(footprint_index); + } +} + //////////////////////////////////////////////////////////////// void diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 9a812f3c..de146e74 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -65,6 +65,8 @@ typedef Vector LeakagePowerGroupSeq; typedef void (LibertyPort::*LibertyPortBoolSetter)(bool value); typedef Vector OutputWaveformSeq; typedef vector StdStringSeq; +typedef Map LibertyCellFootprintIndexMap; class LibertyReader : public LibertyGroupVisitor { @@ -205,6 +207,7 @@ public: virtual void visitInterfaceTiming(LibertyAttr *attr); virtual void visitScalingFactors(LibertyAttr *attr); virtual void visitCellLeakagePower(LibertyAttr *attr); + virtual void visitCellFootprint(LibertyAttr *attr); virtual void beginPin(LibertyGroup *group); virtual void endPin(LibertyGroup *group); @@ -663,6 +666,7 @@ protected: float reference_time_; bool reference_time_exists_; const char *driver_waveform_name_; + LibertyCellFootprintIndexMap footprint_index_map_; static constexpr char escape_ = '\\'; From c0cf80ef5629d5ea38e8af61e25650489dc571d4 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 4 Sep 2024 18:17:47 -0300 Subject: [PATCH 3/5] keep footprint string inside its cell Signed-off-by: Arthur Koucher --- include/sta/Liberty.hh | 8 ++------ liberty/Liberty.cc | 25 +++++++++---------------- liberty/LibertyReader.cc | 18 ++---------------- liberty/LibertyReaderPvt.hh | 3 --- 4 files changed, 13 insertions(+), 41 deletions(-) diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 8b568ae3..dc2de8b5 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -83,8 +83,6 @@ typedef Map SupplyVoltageMap; typedef Map LibertyPgPortMap; typedef Map DriverWaveformMap; typedef Vector DcalcAnalysisPtSeq; -typedef int LibertyCellFootprintIndex; -typedef Vector LibertyCellFootprintSeq; enum class ClockGateType { none, latch_posedge, latch_negedge, other }; @@ -144,7 +142,6 @@ public: // Liberty cells that are buffers. LibertyCellSeq *buffers(); LibertyCellSeq *inverters(); - void addFootprint(const char *footprint); DelayModelType delayModelType() const { return delay_model_type_; } void setDelayModelType(DelayModelType type); @@ -374,7 +371,6 @@ protected: SupplyVoltageMap supply_voltage_map_; LibertyCellSeq *buffers_; LibertyCellSeq *inverters_; - LibertyCellFootprintSeq footprints_; DriverWaveformMap driver_waveform_map_; // Unnamed driver waveform. DriverWaveform *driver_waveform_default_; @@ -545,8 +541,8 @@ public: // for all the defined corners. static void checkLibertyCorners(); void ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps); - void setFootprintIndex(LibertyCellFootprintIndex footprint_index); const char *footprint() const; + void setFootprint(const char *footprint); protected: void addPort(ConcretePort *port); @@ -637,7 +633,7 @@ protected: bool has_internal_ports_; bool have_voltage_waveforms_; std::mutex waveform_lock_; - LibertyCellFootprintIndex footprint_index_; + const char *footprint_; private: friend class LibertyLibrary; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 173b233d..b9a00751 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -128,9 +128,6 @@ LibertyLibrary::~LibertyLibrary() delete inverters_; driver_waveform_map_.deleteContents(); delete driver_waveform_default_; - - for (auto footprint : footprints_) - stringDelete(footprint); } LibertyCell * @@ -184,12 +181,6 @@ LibertyLibrary::buffers() return buffers_; } -void -LibertyLibrary::addFootprint(const char *footprint) -{ - footprints_.push_back(stringCopy(footprint)); -} - void LibertyLibrary::setDelayModelType(DelayModelType type) { @@ -950,7 +941,7 @@ LibertyCell::LibertyCell(LibertyLibrary *library, leakage_power_exists_(false), has_internal_ports_(false), have_voltage_waveforms_(false), - footprint_index_(-1) + footprint_(nullptr) { liberty_cell_ = this; } @@ -978,6 +969,8 @@ LibertyCell::~LibertyCell() ocv_derate_map_.deleteContents(); pg_port_map_.deleteContents(); + + stringDelete(footprint_); } LibertyPort * @@ -2000,18 +1993,18 @@ LibertyCell::ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps) } void -LibertyCell::setFootprintIndex(LibertyCellFootprintIndex footprint_index) +LibertyCell::setFootprint(const char *footprint) { - footprint_index_ = footprint_index; + footprint_ = stringCopy(footprint); } const char* LibertyCell::footprint() const { - if (footprint_index_ != -1) { - return libertyLibrary()->footprints_[footprint_index_]; - } - return ""; + if (footprint_) + return footprint_; + else + return ""; } //////////////////////////////////////////////////////////////// diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 1bc00da2..032a5376 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -726,9 +726,6 @@ LibertyReader::endLibraryAttrs(LibertyGroup *group) if (missing_threshold) libError(1149, group, "Library %s is missing one or more thresholds.", library_->name()); - - for (auto [footprint, footprint_index] : footprint_index_map_) - stringDelete(footprint); } void @@ -3074,19 +3071,8 @@ LibertyReader::visitCellFootprint(LibertyAttr *attr) { if (cell_) { const char *footprint = getAttrString(attr); - if (!footprint) { - return; - } - LibertyCellFootprintIndex footprint_index; - auto itr = footprint_index_map_.find(footprint); - if (itr != footprint_index_map_.end()) { - footprint_index = itr->second; - } else { - footprint_index = static_cast(footprint_index_map_.size()); - footprint_index_map_[stringCopy(footprint)] = footprint_index; - library()->addFootprint(stringCopy(footprint)); - } - cell_->setFootprintIndex(footprint_index); + if (footprint) + cell_->setFootprint(stringCopy(footprint)); } } diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index de146e74..23106440 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -65,8 +65,6 @@ typedef Vector LeakagePowerGroupSeq; typedef void (LibertyPort::*LibertyPortBoolSetter)(bool value); typedef Vector OutputWaveformSeq; typedef vector StdStringSeq; -typedef Map LibertyCellFootprintIndexMap; class LibertyReader : public LibertyGroupVisitor { @@ -666,7 +664,6 @@ protected: float reference_time_; bool reference_time_exists_; const char *driver_waveform_name_; - LibertyCellFootprintIndexMap footprint_index_map_; static constexpr char escape_ = '\\'; From 3fb703b4b1d9444da6e690e0e93ee0b82ee443d4 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 5 Sep 2024 16:21:07 -0700 Subject: [PATCH 4/5] issue82 hierarchical spef annotation Signed-off-by: James Cherry --- include/sta/Parasitics.hh | 2 + parasitics/ConcreteParasitics.cc | 16 +++++- parasitics/ConcreteParasitics.hh | 1 + parasitics/ConcreteParasiticsPvt.hh | 2 +- parasitics/Parasitics.cc | 42 ++++++++++++++ parasitics/ReduceParasitics.cc | 89 +++++++++++++---------------- 6 files changed, 101 insertions(+), 51 deletions(-) diff --git a/include/sta/Parasitics.hh b/include/sta/Parasitics.hh index 7cf45d33..a5a34c11 100644 --- a/include/sta/Parasitics.hh +++ b/include/sta/Parasitics.hh @@ -154,6 +154,8 @@ public: bool includes_pin_caps, const ParasiticAnalysisPt *ap) = 0; virtual ParasiticNodeSeq nodes(const Parasitic *parasitic) const = 0; + virtual void report(const Parasitic *parasitic) const; + virtual const Net *net(const Parasitic *parasitic) const = 0; virtual ParasiticResistorSeq resistors(const Parasitic *parasitic) const = 0; virtual ParasiticCapacitorSeq capacitors(const Parasitic *parasitic) const = 0; // Delete parasitic network if it exists. diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index ec76fdcb..d636ea05 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -596,13 +596,14 @@ ConcreteParasiticNetwork::findParasiticNode(const Pin *pin) const ConcreteParasiticNode * ConcreteParasiticNetwork::ensureParasiticNode(const Net *net, int id, - const Network *) + const Network *network) { ConcreteParasiticNode *node; NetIdPair net_id(net, id); auto id_node = sub_nodes_.find(net_id); if (id_node == sub_nodes_.end()) { - node = new ConcreteParasiticNode(net, id, net != net_); + Net *net1 = network->highestNetAbove(const_cast(net)); + node = new ConcreteParasiticNode(net, id, network->highestNetAbove(net1) != net_); sub_nodes_[net_id] = node; if (net == net_) max_node_id_ = max((int) max_node_id_, id); @@ -1287,6 +1288,17 @@ ConcreteParasitics::deleteParasiticNetworks(const Net *net) } } +const Net * +ConcreteParasitics::net(const Parasitic *parasitic) const +{ + const ConcreteParasiticNetwork *cparasitic = + static_cast(parasitic); + if (cparasitic->isParasiticNetwork()) + return cparasitic->net(); + else + return nullptr; +} + bool ConcreteParasitics::includesPinCaps(const Parasitic *parasitic) const { diff --git a/parasitics/ConcreteParasitics.hh b/parasitics/ConcreteParasitics.hh index fbb1b3d4..f9259fd2 100644 --- a/parasitics/ConcreteParasitics.hh +++ b/parasitics/ConcreteParasitics.hh @@ -112,6 +112,7 @@ public: void deleteParasiticNetwork(const Net *net, const ParasiticAnalysisPt *ap) override; void deleteParasiticNetworks(const Net *net) override; + const Net *net(const Parasitic *parasitic) const override; bool includesPinCaps(const Parasitic *parasitic) const override; ParasiticNode *findParasiticNode(Parasitic *parasitic, const Net *net, diff --git a/parasitics/ConcreteParasiticsPvt.hh b/parasitics/ConcreteParasiticsPvt.hh index b4503b70..e098b2bb 100644 --- a/parasitics/ConcreteParasiticsPvt.hh +++ b/parasitics/ConcreteParasiticsPvt.hh @@ -207,7 +207,7 @@ public: const Network *network); virtual ~ConcreteParasiticNetwork(); virtual bool isParasiticNetwork() const { return true; } - const Net *net() { return net_; } + const Net *net() const { return net_; } bool includesPinCaps() const { return includes_pin_caps_; } ConcreteParasiticNode *findParasiticNode(const Net *net, int id, diff --git a/parasitics/Parasitics.cc b/parasitics/Parasitics.cc index 65b62a1d..a82a96e7 100644 --- a/parasitics/Parasitics.cc +++ b/parasitics/Parasitics.cc @@ -18,6 +18,7 @@ #include "Error.hh" #include "Debug.hh" +#include "Units.hh" #include "Liberty.hh" #include "Wireload.hh" #include "Network.hh" @@ -34,6 +35,47 @@ Parasitics::Parasitics(StaState *sta) : { } +void +Parasitics::report(const Parasitic *parasitic) const +{ + if (isParasiticNetwork(parasitic)) { + const Unit *cap_unit = units_->capacitanceUnit(); + report_->reportLine("Net %s %s", + network_->pathName(net(parasitic)), + cap_unit->asString(capacitance(parasitic))); + report_->reportLine("Nodes:"); + for (ParasiticNode *node : nodes(parasitic)) + report_->reportLine("%s%s %s", + name(node), + isExternal(node) ? " (ext)" : "", + cap_unit->asString(nodeGndCap(node))); + report_->reportLine("Resistors:"); + for (ParasiticResistor *res : resistors(parasitic)) { + ParasiticNode *node1 = this->node1(res); + ParasiticNode *node2 = this->node2(res); + report_->reportLine("%zu %s%s %s%s %s", + id(res), + name(node1), + isExternal(node1) ? " (ext)" : "", + name(node2), + isExternal(node2) ? " (ext)" : "", + units_->resistanceUnit()->asString(value(res))); + } + report_->reportLine("Coupling Capacitors:"); + for (ParasiticCapacitor *cap : capacitors(parasitic)) { + ParasiticNode *node1 = this->node1(cap); + ParasiticNode *node2 = this->node2(cap); + report_->reportLine("%zu %s%s %s%s %s", + id(cap), + name(node1), + isExternal(node1) ? " (ext)" : "", + name(node2), + isExternal(node2) ? " (ext)" : "", + cap_unit->asString(value(cap))); + } + } +} + const Net * Parasitics::findParasiticNet(const Pin *pin) const { diff --git a/parasitics/ReduceParasitics.cc b/parasitics/ReduceParasitics.cc index 07c5b733..a4190b3f 100644 --- a/parasitics/ReduceParasitics.cc +++ b/parasitics/ReduceParasitics.cc @@ -155,60 +155,53 @@ ReduceToPi::reducePiDfs(const Pin *drvr_pin, double &dwn_cap, double &max_resistance) { - if (parasitics_->isExternal(node)) { - y1 = y2 = y3 = 0.0; - max_resistance = 0.0; - dwn_cap = 0.0; - } - else { - double coupling_cap = 0.0; - ParasiticCapacitorSeq &capacitors = capacitor_map_[node]; - for (ParasiticCapacitor *capacitor : capacitors) - coupling_cap += parasitics_->value(capacitor); + double coupling_cap = 0.0; + ParasiticCapacitorSeq &capacitors = capacitor_map_[node]; + for (ParasiticCapacitor *capacitor : capacitors) + coupling_cap += parasitics_->value(capacitor); - dwn_cap = parasitics_->nodeGndCap(node) - + coupling_cap * coupling_cap_multiplier_ - + pinCapacitance(node); - y1 = dwn_cap; - y2 = y3 = 0.0; - max_resistance = max(max_resistance, src_resistance); + dwn_cap = parasitics_->nodeGndCap(node) + + coupling_cap * coupling_cap_multiplier_ + + pinCapacitance(node); + y1 = dwn_cap; + y2 = y3 = 0.0; + max_resistance = max(max_resistance, src_resistance); - visit(node); - ParasiticResistorSeq &resistors = resistor_map_[node]; - for (ParasiticResistor *resistor : resistors) { - if (!isLoopResistor(resistor)) { - ParasiticNode *onode = parasitics_->otherNode(resistor, node); - // One commercial extractor creates resistors with identical from/to nodes. - if (onode != node - && resistor != from_res) { - if (isVisited(onode)) { - // Resistor loop. - debugPrint(debug_, "parasitic_reduce", 2, " loop detected thru resistor %zu", - parasitics_->id(resistor)); - markLoopResistor(resistor); - } - else { - double r = parasitics_->value(resistor); - double yd1, yd2, yd3, dcap; - reducePiDfs(drvr_pin, onode, resistor, src_resistance + r, - yd1, yd2, yd3, dcap, max_resistance); - // Rule 3. Upstream traversal of a series resistor. - // Rule 4. Parallel admittances add. - y1 += yd1; - y2 += yd2 - r * yd1 * yd1; - y3 += yd3 - 2 * r * yd1 * yd2 + r * r * yd1 * yd1 * yd1; - dwn_cap += dcap; - } + visit(node); + ParasiticResistorSeq &resistors = resistor_map_[node]; + for (ParasiticResistor *resistor : resistors) { + if (!isLoopResistor(resistor)) { + ParasiticNode *onode = parasitics_->otherNode(resistor, node); + // One commercial extractor creates resistors with identical from/to nodes. + if (onode != node + && resistor != from_res) { + if (isVisited(onode)) { + // Resistor loop. + debugPrint(debug_, "parasitic_reduce", 2, " loop detected thru resistor %zu", + parasitics_->id(resistor)); + markLoopResistor(resistor); + } + else { + double r = parasitics_->value(resistor); + double yd1, yd2, yd3, dcap; + reducePiDfs(drvr_pin, onode, resistor, src_resistance + r, + yd1, yd2, yd3, dcap, max_resistance); + // Rule 3. Upstream traversal of a series resistor. + // Rule 4. Parallel admittances add. + y1 += yd1; + y2 += yd2 - r * yd1 * yd1; + y3 += yd3 - 2 * r * yd1 * yd2 + r * r * yd1 * yd1 * yd1; + dwn_cap += dcap; } } } - - setDownstreamCap(node, dwn_cap); - leave(node); - debugPrint(debug_, "parasitic_reduce", 3, - " node %s y1=%.3g y2=%.3g y3=%.3g cap=%.3g", - parasitics_->name(node), y1, y2, y3, dwn_cap); } + + setDownstreamCap(node, dwn_cap); + leave(node); + debugPrint(debug_, "parasitic_reduce", 3, + " node %s y1=%.3g y2=%.3g y3=%.3g cap=%.3g", + parasitics_->name(node), y1, y2, y3, dwn_cap); } float From 2de024f6e8b3fa5f30ff19a8801b36c495656ab0 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 6 Sep 2024 11:44:17 -0300 Subject: [PATCH 5/5] return nullptr rather than empty string Signed-off-by: Arthur Koucher --- liberty/EquivCells.cc | 2 +- liberty/Liberty.cc | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index a9a74130..113ec673 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -530,7 +530,7 @@ bool equivCellFootprints(const LibertyCell *cell1, const LibertyCell *cell2) { - return strcmp(cell1->footprint(), cell2->footprint()) == 0; + return stringEqIf(cell1->footprint(), cell2->footprint()); } } // namespace diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index b9a00751..055aaf27 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -2001,10 +2001,7 @@ LibertyCell::setFootprint(const char *footprint) const char* LibertyCell::footprint() const { - if (footprint_) - return footprint_; - else - return ""; + return footprint_; } ////////////////////////////////////////////////////////////////