From 84150e925b96cde239336722d56d4ff916a9b809 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 4 Apr 2026 09:21:34 -0700 Subject: [PATCH] prima ceff Signed-off-by: James Cherry --- dcalc/PrimaDelayCalc.cc | 53 ++++++++++++++++++++++++++++++++++------- dcalc/PrimaDelayCalc.hh | 6 +++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index 9cea3ea6..be0a3d89 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -194,8 +194,8 @@ PrimaDelayCalc::gateDelay(const Pin *drvr_pin, ArcDcalcArgSeq dcalc_args; dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, load_cap, parasitic); - ArcDcalcResultSeq dcalc_results = - gateDelays(dcalc_args, load_pin_index_map, scene, min_max); + ArcDcalcResultSeq dcalc_results = gateDelays(dcalc_args, load_pin_index_map, + scene, min_max); return dcalc_results[0]; } @@ -399,6 +399,7 @@ void PrimaDelayCalc::initSim() { ceff_.resize(drvr_count_); + ceff_vth_.resize(drvr_count_); drvr_current_.resize(drvr_count_); findNodeCount(); @@ -615,8 +616,12 @@ PrimaDelayCalc::updateCeffIdrvr() if (drvr_rf_ == RiseFall::rise()) { if (drvr_current != 0.0 && dv > 0.0) { double ceff = drvr_current * time_step_ / dv; - if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) + if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) { ceff_[drvr_idx] = ceff; + // Record the Ceff at Vth. + if (v1 >= vth_ && v2 < vth_) + ceff_vth_[drvr_idx] = ceff; + } } if (v1 > (vdd_ - .01)) // Whoa partner. Head'n for the weeds. @@ -628,8 +633,12 @@ PrimaDelayCalc::updateCeffIdrvr() else { if (drvr_current != 0.0 && dv < 0.0) { double ceff = drvr_current * time_step_ / dv; - if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) + if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) { ceff_[drvr_idx] = ceff; + // Record the Ceff at Vth. + if (v1 <= vth_ && v2 > vth_) + ceff_vth_[drvr_idx] = ceff; + } } if (v1 < 0.01) { // Whoa partner. Head'n for the weeds. @@ -711,8 +720,13 @@ PrimaDelayCalc::dcalcResults() float ref_time = output_waveforms_[drvr_idx]->referenceTime(dcalc_arg.inSlewFlt()); double gate_delay = drvr_times[threshold_vth] - ref_time; double drvr_slew = std::abs(drvr_times[threshold_vh] - drvr_times[threshold_vl]); - dcalc_result.setGateDelay(gate_delay); - dcalc_result.setDrvrSlew(drvr_slew); + + ArcDelay gate_delay2(gate_delay); + Slew drvr_slew2(drvr_slew); + delaySlewPocv(dcalc_arg, drvr_idx, gate_delay2, drvr_slew2); + dcalc_result.setGateDelay(gate_delay2); + dcalc_result.setDrvrSlew(drvr_slew2); + debugPrint(debug_, "ccs_dcalc", 2, "{} gate delay {} slew {}", network_->pathName(drvr_pin), delayAsString(gate_delay, this), delayAsString(drvr_slew, this)); @@ -740,6 +754,28 @@ PrimaDelayCalc::dcalcResults() return dcalc_results; } +// Fill in pocv parameters in gate_delay/drvr_slew. +void +PrimaDelayCalc::delaySlewPocv(ArcDcalcArg &dcalc_arg, + size_t drvr_idx, + ArcDelay &gate_delay, + Slew &drvr_slew) +{ + if (variables_->pocvEnabled()) { + GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene_, min_max_); + if (table_model) { + double ceff = ceff_vth_[drvr_idx]; + if (ceff == 0.0) + ceff = dcalc_arg.loadCap(); + float in_slew = delayAsFloat(dcalc_arg.inSlew()); + const Pvt *pvt = pinPvt(dcalc_arg.drvrPin(), scene_, min_max_); + table_model->gateDelayPocv(pvt, in_slew, ceff, min_max_, + variables_->pocvMode(), + gate_delay, drvr_slew); + } + } +} + //////////////////////////////////////////////////////////////// void @@ -895,7 +931,7 @@ std::string PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, const TimingArc *arc, const Slew &in_slew, - float load_cap, + float, const Parasitic *, const LoadPinIndexMap &, const Scene *scene, @@ -905,8 +941,9 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, GateTimingModel *model = arc->gateModel(scene, min_max); if (model) { float in_slew1 = delayAsFloat(in_slew); + float ceff = ceff_vth_[0]; return model->reportGateDelay(pinPvt(drvr_pin, scene, min_max), - in_slew1, load_cap, min_max, + in_slew1, ceff, min_max, PocvMode::scalar, digits); } return ""; diff --git a/dcalc/PrimaDelayCalc.hh b/dcalc/PrimaDelayCalc.hh index 8ed47a05..c0b39ba7 100644 --- a/dcalc/PrimaDelayCalc.hh +++ b/dcalc/PrimaDelayCalc.hh @@ -108,6 +108,10 @@ public: Waveform watchWaveform(const Pin *pin) override; protected: + void delaySlewPocv(ArcDcalcArg &dcalc_arg, + size_t drvr_idx, + ArcDelay &gate_delay, + Slew &drvr_slew); ArcDcalcResultSeq tableDcalcResults(); void simulate(); void simulate1(const MatrixSd &G, @@ -215,6 +219,8 @@ protected: // Indexed by driver index. std::vector ceff_; + // Ceff at Vth + std::vector ceff_vth_; std::vector drvr_current_; double time_step_;