@@ -194,8 +194,8 @@ PrimaDelayCalc::gateDelay(const Pin *drvr_pin,
194194 ArcDcalcArgSeq dcalc_args;
195195 dcalc_args.emplace_back (nullptr , drvr_pin, nullptr , arc, in_slew, load_cap,
196196 parasitic);
197- ArcDcalcResultSeq dcalc_results =
198- gateDelays (dcalc_args, load_pin_index_map, scene, min_max);
197+ ArcDcalcResultSeq dcalc_results = gateDelays (dcalc_args, load_pin_index_map,
198+ scene, min_max);
199199 return dcalc_results[0 ];
200200}
201201
399399PrimaDelayCalc::initSim ()
400400{
401401 ceff_.resize (drvr_count_);
402+ ceff_vth_.resize (drvr_count_);
402403 drvr_current_.resize (drvr_count_);
403404
404405 findNodeCount ();
@@ -615,8 +616,12 @@ PrimaDelayCalc::updateCeffIdrvr()
615616 if (drvr_rf_ == RiseFall::rise ()) {
616617 if (drvr_current != 0.0 && dv > 0.0 ) {
617618 double ceff = drvr_current * time_step_ / dv;
618- if (output_waveforms_[drvr_idx]->capAxis ()->inBounds (ceff))
619+ if (output_waveforms_[drvr_idx]->capAxis ()->inBounds (ceff)) {
619620 ceff_[drvr_idx] = ceff;
621+ // Record the Ceff at Vth.
622+ if (v1 >= vth_ && v2 < vth_)
623+ ceff_vth_[drvr_idx] = ceff;
624+ }
620625 }
621626 if (v1 > (vdd_ - .01 ))
622627 // Whoa partner. Head'n for the weeds.
@@ -628,8 +633,12 @@ PrimaDelayCalc::updateCeffIdrvr()
628633 else {
629634 if (drvr_current != 0.0 && dv < 0.0 ) {
630635 double ceff = drvr_current * time_step_ / dv;
631- if (output_waveforms_[drvr_idx]->capAxis ()->inBounds (ceff))
636+ if (output_waveforms_[drvr_idx]->capAxis ()->inBounds (ceff)) {
632637 ceff_[drvr_idx] = ceff;
638+ // Record the Ceff at Vth.
639+ if (v1 <= vth_ && v2 > vth_)
640+ ceff_vth_[drvr_idx] = ceff;
641+ }
633642 }
634643 if (v1 < 0.01 ) {
635644 // Whoa partner. Head'n for the weeds.
@@ -711,8 +720,13 @@ PrimaDelayCalc::dcalcResults()
711720 float ref_time = output_waveforms_[drvr_idx]->referenceTime (dcalc_arg.inSlewFlt ());
712721 double gate_delay = drvr_times[threshold_vth] - ref_time;
713722 double drvr_slew = std::abs (drvr_times[threshold_vh] - drvr_times[threshold_vl]);
714- dcalc_result.setGateDelay (gate_delay);
715- dcalc_result.setDrvrSlew (drvr_slew);
723+
724+ ArcDelay gate_delay2 (gate_delay);
725+ Slew drvr_slew2 (drvr_slew);
726+ delaySlewPocv (dcalc_arg, drvr_idx, gate_delay2, drvr_slew2);
727+ dcalc_result.setGateDelay (gate_delay2);
728+ dcalc_result.setDrvrSlew (drvr_slew2);
729+
716730 debugPrint (debug_, " ccs_dcalc" , 2 , " {} gate delay {} slew {}" ,
717731 network_->pathName (drvr_pin), delayAsString (gate_delay, this ),
718732 delayAsString (drvr_slew, this ));
@@ -740,6 +754,28 @@ PrimaDelayCalc::dcalcResults()
740754 return dcalc_results;
741755}
742756
757+ // Fill in pocv parameters in gate_delay/drvr_slew.
758+ void
759+ PrimaDelayCalc::delaySlewPocv (ArcDcalcArg &dcalc_arg,
760+ size_t drvr_idx,
761+ ArcDelay &gate_delay,
762+ Slew &drvr_slew)
763+ {
764+ if (variables_->pocvEnabled ()) {
765+ GateTableModel *table_model = dcalc_arg.arc ()->gateTableModel (scene_, min_max_);
766+ if (table_model) {
767+ double ceff = ceff_vth_[drvr_idx];
768+ if (ceff == 0.0 )
769+ ceff = dcalc_arg.loadCap ();
770+ float in_slew = delayAsFloat (dcalc_arg.inSlew ());
771+ const Pvt *pvt = pinPvt (dcalc_arg.drvrPin (), scene_, min_max_);
772+ table_model->gateDelayPocv (pvt, in_slew, ceff, min_max_,
773+ variables_->pocvMode (),
774+ gate_delay, drvr_slew);
775+ }
776+ }
777+ }
778+
743779// //////////////////////////////////////////////////////////////
744780
745781void
@@ -895,7 +931,7 @@ std::string
895931PrimaDelayCalc::reportGateDelay (const Pin *drvr_pin,
896932 const TimingArc *arc,
897933 const Slew &in_slew,
898- float load_cap ,
934+ float ,
899935 const Parasitic *,
900936 const LoadPinIndexMap &,
901937 const Scene *scene,
@@ -905,8 +941,9 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin,
905941 GateTimingModel *model = arc->gateModel (scene, min_max);
906942 if (model) {
907943 float in_slew1 = delayAsFloat (in_slew);
944+ float ceff = ceff_vth_[0 ];
908945 return model->reportGateDelay (pinPvt (drvr_pin, scene, min_max),
909- in_slew1, load_cap , min_max,
946+ in_slew1, ceff , min_max,
910947 PocvMode::scalar, digits);
911948 }
912949 return " " ;
0 commit comments