ccs waveform rf
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
cc1bc54ee7
commit
54f1c5bd50
|
|
@ -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 ¤t_waveforms,
|
Table1Seq ¤t_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_;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 ¤t_waveforms,
|
Table1Seq ¤t_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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue