ccs waveform rf

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2023-03-30 18:52:43 -07:00
parent cc1bc54ee7
commit 54f1c5bd50
4 changed files with 64 additions and 60 deletions

View File

@ -361,8 +361,7 @@ public:
float &value, float &value,
bool &extrapolated) const; bool &extrapolated) const;
float findValue(float axis_value1) const; float findValue(float axis_value1) const;
float findValueClip(float axis_value1, float findValueClip(float axis_value1) const;
float clip_value) const;
FloatSeq *values() const { return values_; } FloatSeq *values() const { return values_; }
using Table::findValue; using Table::findValue;
@ -501,9 +500,11 @@ class OutputWaveforms
public: public:
OutputWaveforms(TableAxisPtr slew_axis, OutputWaveforms(TableAxisPtr slew_axis,
TableAxisPtr cap_axis, TableAxisPtr cap_axis,
const RiseFall *rf,
Table1Seq &current_waveforms, Table1Seq &current_waveforms,
Table1 *ref_times); Table1 *ref_times);
~OutputWaveforms(); ~OutputWaveforms();
const RiseFall *rf() const { return rf_; }
Table1 voltageWaveform(float in_slew, Table1 voltageWaveform(float in_slew,
float load_cap); float load_cap);
Table1 currentWaveform(float slew, Table1 currentWaveform(float slew,
@ -519,6 +520,7 @@ private:
TableAxisPtr slew_axis_; TableAxisPtr slew_axis_;
// Column. // Column.
TableAxisPtr cap_axis_; TableAxisPtr cap_axis_;
const RiseFall *rf_;
Table1Seq current_waveforms_; Table1Seq current_waveforms_;
Table1Seq voltage_waveforms_; Table1Seq voltage_waveforms_;
Table1 *ref_times_; Table1 *ref_times_;

View File

@ -2532,7 +2532,7 @@ LibertyReader::endOutputCurrentRiseFall(LibertyGroup *group)
waveform->cap()); waveform->cap());
} }
Table1 *ref_time_tbl = new Table1(ref_times, slew_axis); Table1 *ref_time_tbl = new Table1(ref_times, slew_axis);
OutputWaveforms *output_current = new OutputWaveforms(slew_axis, cap_axis, OutputWaveforms *output_current = new OutputWaveforms(slew_axis, cap_axis, rf_,
current_waveforms, current_waveforms,
ref_time_tbl); ref_time_tbl);
timing_->setOutputWaveforms(rf_, output_current); timing_->setOutputWaveforms(rf_, output_current);

View File

@ -871,35 +871,8 @@ Table1::findValue(float axis_value1,
float float
Table1::findValue(float axis_value1) const Table1::findValue(float axis_value1) const
{ {
float value; if (axis1_->size() == 1)
bool extrapolated; return this->value(axis_value1);
findValue(axis_value1, value, extrapolated);
return value;
}
float
Table1::findValueClip(float axis_value1,
float clip_value) const
{
float value;
bool extrapolated;
findValue(axis_value1, value, extrapolated);
if (extrapolated)
return clip_value;
else
return value;
}
void
Table1::findValue(float axis_value1,
// Return values.
float &value,
bool &extrapolated) const
{
if (axis1_->size() == 1) {
value = this->value(axis_value1);
extrapolated = false;
}
else { else {
size_t axis_index1 = axis1_->findAxisIndex(axis_value1); size_t axis_index1 = axis1_->findAxisIndex(axis_value1);
float x1 = axis_value1; float x1 = axis_value1;
@ -908,8 +881,30 @@ Table1::findValue(float axis_value1,
float y1 = this->value(axis_index1); float y1 = this->value(axis_index1);
float y2 = this->value(axis_index1 + 1); float y2 = this->value(axis_index1 + 1);
float dx1 = (x1 - x1l) / (x1u - x1l); float dx1 = (x1 - x1l) / (x1u - x1l);
value = (1 - dx1) * y1 + dx1 * y2; return (1 - dx1) * y1 + dx1 * y2;
extrapolated = (x1 < x1l || x1 >= x1u); }
}
float
Table1::findValueClip(float axis_value1) const
{
if (axis1_->size() == 1)
return this->value(axis_value1);
else {
size_t axis_index1 = axis1_->findAxisIndex(axis_value1);
float x1 = axis_value1;
float x1l = axis1_->axisValue(axis_index1);
float x1u = axis1_->axisValue(axis_index1 + 1);
if (x1 < x1l)
return this->value(0);
else if (x1 > x1u)
return this->value(axis1_->size() - 1);
else {
float y1 = this->value(axis_index1);
float y2 = this->value(axis_index1 + 1);
float dx1 = (x1 - x1l) / (x1u - x1l);
return (1 - dx1) * y1 + dx1 * y2;
}
} }
} }
@ -1584,10 +1579,12 @@ tableVariableUnit(TableAxisVariable variable,
OutputWaveforms::OutputWaveforms(TableAxisPtr slew_axis, OutputWaveforms::OutputWaveforms(TableAxisPtr slew_axis,
TableAxisPtr cap_axis, TableAxisPtr cap_axis,
const RiseFall *rf,
Table1Seq &current_waveforms, Table1Seq &current_waveforms,
Table1 *ref_times) : Table1 *ref_times) :
slew_axis_(slew_axis), slew_axis_(slew_axis),
cap_axis_(cap_axis), cap_axis_(cap_axis),
rf_(rf),
current_waveforms_(current_waveforms), current_waveforms_(current_waveforms),
voltage_waveforms_(current_waveforms.size()), voltage_waveforms_(current_waveforms.size()),
ref_times_(ref_times) ref_times_(ref_times)
@ -1655,7 +1652,6 @@ OutputWaveforms::voltageWaveform(float slew,
time_values); time_values);
// Interpolate waveform samples at time steps. // Interpolate waveform samples at time steps.
float value = values00->value(values00->values()->size() - 1);
size_t index1 = slew_index; size_t index1 = slew_index;
size_t index2 = cap_index; size_t index2 = cap_index;
float x1 = slew; float x1 = slew;
@ -1667,30 +1663,26 @@ OutputWaveforms::voltageWaveform(float slew,
float x2u = cap_axis_->axisValue(index2 + 1); float x2u = cap_axis_->axisValue(index2 + 1);
float dx2 = (x2 - x2l) / (x2u - x2l); float dx2 = (x2 - x2l) / (x2u - x2l);
FloatSeq *values = new FloatSeq; FloatSeq *values = new FloatSeq;
bool waveform_started = false;
float prev_value = 0.0; float prev_value = 0.0;
constexpr float value_tol = .01; constexpr float value_tol = .0001;
float value_end = value * (1.0 - value_tol);
for (size_t i = 0; i <= time_step_count; i++) { for (size_t i = 0; i <= time_step_count; i++) {
float time = time_min + time_step * i; float time = time_min + time_step * i;
float y00 = values00->findValue(time); if (time > time_max)
float y10 = values10->findValue(time); break;
float y11 = values11->findValue(time); float y00 = values00->findValueClip(time);
float y01 = values01->findValue(time); float y10 = values10->findValueClip(time);
float voltage float y11 = values11->findValueClip(time);
float y01 = values01->findValueClip(time);
float value
= (1 - dx1) * (1 - dx2) * y00 = (1 - dx1) * (1 - dx2) * y00
+ dx1 * (1 - dx2) * y10 + dx1 * (1 - dx2) * y10
+ dx1 * dx2 * y11 + dx1 * dx2 * y11
+ (1 - dx1) * dx2 * y01; + (1 - dx1) * dx2 * y01;
if (voltage > value_tol) if (i == 0 || abs(value - prev_value) > value_tol) {
waveform_started = true;
if (waveform_started) {
time_values->push_back(time); time_values->push_back(time);
values->push_back(voltage); values->push_back(value);
} }
if (prev_value > value_end) prev_value = value;
break;
prev_value = voltage;
} }
return Table1(values, time_axis); return Table1(values, time_axis);
} }
@ -1713,7 +1705,8 @@ OutputWaveforms::voltageWaveform(size_t wave_index,
float prev_current = currents->value(0); float prev_current = currents->value(0);
float voltage = 0.0; float voltage = 0.0;
voltages1->push_back(voltage); voltages1->push_back(voltage);
bool invert = currents->value(time_axis->size() - 1) < 0.0; bool always_rise = true;
bool invert = (always_rise && rf_ == RiseFall::fall());
for (size_t i = 1; i < time_axis->size(); i++) { for (size_t i = 1; i < time_axis->size(); i++) {
float time = time_axis->axisValue(i); float time = time_axis->axisValue(i);
float current = currents->value(i); float current = currents->value(i);
@ -1723,6 +1716,10 @@ OutputWaveforms::voltageWaveform(size_t wave_index,
prev_time = time; prev_time = time;
prev_current = current; prev_current = current;
} }
if (!always_rise && rf_ == RiseFall::fall()) {
for (size_t i = 0; i < voltages1->size(); i++)
(*voltages1)[i] -= voltage;
}
} }
return voltages; return voltages;
} }
@ -1773,21 +1770,26 @@ OutputWaveforms::currentWaveform(float slew,
float x2u = cap_axis_->axisValue(index2 + 1); float x2u = cap_axis_->axisValue(index2 + 1);
float dx2 = (x2 - x2l) / (x2u - x2l); float dx2 = (x2 - x2l) / (x2u - x2l);
FloatSeq *values = new FloatSeq; FloatSeq *values = new FloatSeq;
float prev_value = 0.0;
constexpr float value_tol = 1e-6;
for (size_t i = 0; i <= time_step_count; i++) { for (size_t i = 0; i <= time_step_count; i++) {
float time = time_min + time_step * i; float time = time_min + time_step * i;
float y00 = values00->findValueClip(time, 0.0); if (time > time_max)
float y10 = values10->findValueClip(time, 0.0); break;
float y11 = values11->findValueClip(time, 0.0); float y00 = values00->findValueClip(time);
float y01 = values01->findValueClip(time, 0.0); float y10 = values10->findValueClip(time);
float y11 = values11->findValueClip(time);
float y01 = values01->findValueClip(time);
float value float value
= (1 - dx1) * (1 - dx2) * y00 = (1 - dx1) * (1 - dx2) * y00
+ dx1 * (1 - dx2) * y10 + dx1 * (1 - dx2) * y10
+ dx1 * dx2 * y11 + dx1 * dx2 * y11
+ (1 - dx1) * dx2 * y01; + (1 - dx1) * dx2 * y01;
time_values->push_back(time); if (i == 0 || abs(value - prev_value) > value_tol) {
values->push_back(value); time_values->push_back(time);
if (time > time_max) values->push_back(value);
break; }
prev_value = value;
} }
return Table1(values, time_axis); return Table1(values, time_axis);
} }

View File

@ -408,7 +408,7 @@ WritePathSpice::maxTime()
else { else {
float end_slew = findSlew(path_); float end_slew = findSlew(path_);
float arrival = delayAsFloat(path_->arrival(this)); float arrival = delayAsFloat(path_->arrival(this));
float max_time = input_slew / 2.0 + arrival + end_slew; float max_time = input_slew + arrival + end_slew;
return max_time; return max_time;
} }
} }