Parametric load model in SOLT calibration

This commit is contained in:
Jan Käberich 2020-11-09 12:21:44 +01:00
parent df2af0f2bf
commit c3b52165f7
6 changed files with 94 additions and 30 deletions

View File

@ -24,13 +24,7 @@ Calkit::Calkit()
}
}
Calkit::Calkit(const Calkit &c) :
// only copy standard definitions, leave cache state and json_descr pointers at default values
SOLT(c.SOLT),
TRL(c.TRL)
{
}
#include <QDebug>
void Calkit::toFile(std::string filename)
{
@ -195,7 +189,18 @@ class Calkit::SOLT Calkit::toSOLT(double frequency)
ref.Load = ts_load->interpolate(frequency).S[0];
} else {
auto imp_load = complex<double>(SOLT.Load.Z0, 0);
// Add parallel capacitor to impedance
if(SOLT.Load.Cparallel > 0) {
auto imp_C = complex<double>(0, -1.0 / (frequency * 2 * M_PI * SOLT.Load.Cparallel));
imp_load = (imp_load * imp_C) / (imp_load + imp_C);
}
// add series inductor to impedance
auto imp_L = complex<double>(0, frequency * 2 * M_PI * SOLT.Load.Lseries);
imp_load += imp_L;
ref.Load = (imp_load - complex<double>(50.0)) / (imp_load + complex<double>(50.0));
// apply phaseshift due to delay
double load_phaseshift = -2 * M_PI * frequency * 2 * SOLT.Load.delay * 1e-12;
ref.Load *= polar<double>(1.0, load_phaseshift);
}
if(SOLT.Open.useMeasurements) {

View File

@ -12,11 +12,11 @@ class Calkit
friend class CalkitDialog;
public:
Calkit();
Calkit(const Calkit& c);
Calkit& operator=(const Calkit& other)
{
this->SOLT = other.SOLT;
this->TRL = other.TRL;
this->startDialogWithSOLT = other.startDialogWithSOLT;
return *this;
}
@ -61,7 +61,7 @@ private:
int Sparam;
} Short;
struct {
double Z0;
double Z0, delay, Cparallel, Lseries;
QString file;
bool useMeasurements;
int Sparam;
@ -94,7 +94,7 @@ private:
QString name;
QVariant def;
};
const std::array<JSONDescription, 37> json_descr = {{
const std::array<JSONDescription, 40> json_descr = {{
{&SOLT.Open.Z0, "SOLT/Open/Param/Z0", 50.0},
{&SOLT.Open.delay, "SOLT/Open/Param/Delay", 0.0},
{&SOLT.Open.loss, "SOLT/Open/Param/Loss", 0.0},
@ -118,6 +118,9 @@ private:
{&SOLT.Short.Sparam, "SOLT/Short/Measurements/Port", 0},
{&SOLT.Load.Z0, "SOLT/Load/Param/Z0", 50.0},
{&SOLT.Load.delay, "SOLT/Load/Param/Delay", 0.0},
{&SOLT.Load.Cparallel, "SOLT/Load/Param/C", 0.0},
{&SOLT.Load.Lseries, "SOLT/Load/Param/L", 0.0},
{&SOLT.Load.useMeasurements, "SOLT/Load/Measurements/Use", false},
{&SOLT.Load.file, "SOLT/Load/Measurements/File", ""},
{&SOLT.Load.Sparam, "SOLT/Load/Measurements/Port", 0},

View File

@ -38,6 +38,15 @@ CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) :
ui->load_touchstone->setPorts(1);
ui->through_touchstone->setPorts(2);
ui->short_Z0->setUnit("Ω");
ui->open_Z0->setUnit("Ω");
ui->load_Z0->setUnit("Ω");
ui->load_parC->setUnit("F");
ui->load_parC->setPrefixes("fpnum ");
ui->load_serL->setUnit("H");
ui->load_serL->setPrefixes("fpnum ");
ui->through_Z0->setUnit("Ω");
ui->TRL_line_max->setUnit("Hz");
ui->TRL_line_max->setPrecision(4);
ui->TRL_line_max->setPrefixes(" kMG");
@ -143,7 +152,7 @@ void CalkitDialog::parseEntries()
ownKit.SOLT.Through.useMeasurements = ui->through_measurement->isChecked();
// coefficients
ownKit.SOLT.Open.Z0 = ui->open_Z0->text().toDouble();
ownKit.SOLT.Open.Z0 = ui->open_Z0->value();
ownKit.SOLT.Open.delay = ui->open_delay->text().toDouble();
ownKit.SOLT.Open.loss = ui->open_loss->text().toDouble();
ownKit.SOLT.Open.C0 = ui->open_C0->text().toDouble();
@ -151,7 +160,7 @@ void CalkitDialog::parseEntries()
ownKit.SOLT.Open.C2 = ui->open_C2->text().toDouble();
ownKit.SOLT.Open.C3 = ui->open_C3->text().toDouble();
ownKit.SOLT.Short.Z0 = ui->short_Z0->text().toDouble();
ownKit.SOLT.Short.Z0 = ui->short_Z0->value();
ownKit.SOLT.Short.delay = ui->short_delay->text().toDouble();
ownKit.SOLT.Short.loss = ui->short_loss->text().toDouble();
ownKit.SOLT.Short.L0 = ui->short_L0->text().toDouble();
@ -159,9 +168,12 @@ void CalkitDialog::parseEntries()
ownKit.SOLT.Short.L2 = ui->short_L2->text().toDouble();
ownKit.SOLT.Short.L3 = ui->short_L3->text().toDouble();
ownKit.SOLT.Load.Z0 = ui->load_Z0->text().toDouble();
ownKit.SOLT.Load.Z0 = ui->load_Z0->value();
ownKit.SOLT.Load.delay = ui->load_delay->text().toDouble();
ownKit.SOLT.Load.Cparallel = ui->load_parC->value();
ownKit.SOLT.Load.Lseries = ui->load_serL->value();
ownKit.SOLT.Through.Z0 = ui->through_Z0->text().toDouble();
ownKit.SOLT.Through.Z0 = ui->through_Z0->value();
ownKit.SOLT.Through.delay = ui->through_delay->text().toDouble();
ownKit.SOLT.Through.loss = ui->through_loss->text().toDouble();
@ -190,7 +202,7 @@ void CalkitDialog::parseEntries()
void CalkitDialog::updateEntries()
{
// Coefficients
ui->open_Z0->setText(QString::number(ownKit.SOLT.Open.Z0));
ui->open_Z0->setValue(ownKit.SOLT.Open.Z0);
ui->open_delay->setText(QString::number(ownKit.SOLT.Open.delay));
ui->open_loss->setText(QString::number(ownKit.SOLT.Open.loss));
ui->open_C0->setText(QString::number(ownKit.SOLT.Open.C0));
@ -198,7 +210,7 @@ void CalkitDialog::updateEntries()
ui->open_C2->setText(QString::number(ownKit.SOLT.Open.C2));
ui->open_C3->setText(QString::number(ownKit.SOLT.Open.C3));
ui->short_Z0->setText(QString::number(ownKit.SOLT.Short.Z0));
ui->short_Z0->setValue(ownKit.SOLT.Short.Z0);
ui->short_delay->setText(QString::number(ownKit.SOLT.Short.delay));
ui->short_loss->setText(QString::number(ownKit.SOLT.Short.loss));
ui->short_L0->setText(QString::number(ownKit.SOLT.Short.L0));
@ -206,7 +218,10 @@ void CalkitDialog::updateEntries()
ui->short_L2->setText(QString::number(ownKit.SOLT.Short.L2));
ui->short_L3->setText(QString::number(ownKit.SOLT.Short.L3));
ui->load_Z0->setText(QString::number(ownKit.SOLT.Load.Z0));
ui->load_Z0->setValue(ownKit.SOLT.Load.Z0);
ui->load_delay->setText(QString::number(ownKit.SOLT.Load.delay));
ui->load_parC->setValue(ownKit.SOLT.Load.Cparallel);
ui->load_serL->setValue(ownKit.SOLT.Load.Lseries);
ui->through_Z0->setText(QString::number(ownKit.SOLT.Through.Z0));
ui->through_delay->setText(QString::number(ownKit.SOLT.Through.delay));

View File

@ -150,7 +150,7 @@
<widget class="QLineEdit" name="short_L3"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="short_Z0">
<widget class="SIUnitEdit" name="short_Z0">
<property name="enabled">
<bool>false</bool>
</property>
@ -296,7 +296,7 @@
<widget class="QLineEdit" name="open_C3"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="open_Z0">
<widget class="SIUnitEdit" name="open_Z0">
<property name="enabled">
<bool>false</bool>
</property>
@ -389,12 +389,42 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="load_Z0">
<widget class="SIUnitEdit" name="load_Z0">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Offset delay [ps]:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="load_delay"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Parallel C:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Series L:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="load_parC"/>
</item>
<item row="3" column="1">
<widget class="SIUnitEdit" name="load_serL"/>
</item>
</layout>
</item>
</layout>
@ -475,7 +505,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="through_Z0">
<widget class="SIUnitEdit" name="through_Z0">
<property name="enabled">
<bool>false</bool>
</property>
@ -903,10 +933,10 @@
</connection>
</connections>
<buttongroups>
<buttongroup name="ShortType"/>
<buttongroup name="LoadType"/>
<buttongroup name="TRL_Rtype"/>
<buttongroup name="OpenType"/>
<buttongroup name="ThroughType"/>
<buttongroup name="TRL_Rtype"/>
<buttongroup name="ShortType"/>
<buttongroup name="OpenType"/>
<buttongroup name="LoadType"/>
</buttongroups>
</ui>

View File

@ -13,6 +13,10 @@ TouchstoneImport::TouchstoneImport(QWidget *parent, int ports) :
status(false)
{
ui->setupUi(this);
ui->lowerFreq->setUnit("Hz");
ui->lowerFreq->setPrefixes(" kMG");
ui->upperFreq->setUnit("Hz");
ui->upperFreq->setPrefixes(" kMG");
connect(ui->browse, &QPushButton::clicked, this, &TouchstoneImport::evaluateFile);
ui->port1Group->setId(ui->port1_1, 0);
ui->port1Group->setId(ui->port1_2, 1);
@ -143,8 +147,8 @@ void TouchstoneImport::evaluateFile()
ui->port2_4->setEnabled(touchstone.ports() >= 4);
}
ui->points->setText(QString::number(touchstone.points()));
ui->lowerFreq->setText(QString::number(touchstone.minFreq()));
ui->upperFreq->setText(QString::number(touchstone.maxFreq()));
ui->lowerFreq->setValue(touchstone.minFreq());
ui->upperFreq->setValue(touchstone.maxFreq());
if(ui->port1Group->checkedId() == -1 || !ui->port1Group->checkedButton()->isEnabled()) {
// no or invalid S parameter selected
ui->port1_1->setChecked(true);

View File

@ -279,7 +279,7 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lowerFreq">
<widget class="SIUnitEdit" name="lowerFreq">
<property name="enabled">
<bool>false</bool>
</property>
@ -293,7 +293,7 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="upperFreq">
<widget class="SIUnitEdit" name="upperFreq">
<property name="enabled">
<bool>false</bool>
</property>
@ -303,10 +303,17 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SIUnitEdit</class>
<extends>QLineEdit</extends>
<header>CustomWidgets/siunitedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="port2Group"/>
<buttongroup name="port1Group"/>
<buttongroup name="port2Group"/>
</buttongroups>
</ui>