Skip to content

Commit 84150e9

Browse files
committed
prima ceff
Signed-off-by: James Cherry <cherry@parallaxsw.com>
1 parent aedddce commit 84150e9

2 files changed

Lines changed: 51 additions & 8 deletions

File tree

dcalc/PrimaDelayCalc.cc

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -399,6 +399,7 @@ void
399399
PrimaDelayCalc::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

745781
void
@@ -895,7 +931,7 @@ std::string
895931
PrimaDelayCalc::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 "";

dcalc/PrimaDelayCalc.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ public:
108108
Waveform watchWaveform(const Pin *pin) override;
109109

110110
protected:
111+
void delaySlewPocv(ArcDcalcArg &dcalc_arg,
112+
size_t drvr_idx,
113+
ArcDelay &gate_delay,
114+
Slew &drvr_slew);
111115
ArcDcalcResultSeq tableDcalcResults();
112116
void simulate();
113117
void simulate1(const MatrixSd &G,
@@ -215,6 +219,8 @@ protected:
215219

216220
// Indexed by driver index.
217221
std::vector<double> ceff_;
222+
// Ceff at Vth
223+
std::vector<double> ceff_vth_;
218224
std::vector<double> drvr_current_;
219225

220226
double time_step_;

0 commit comments

Comments
 (0)