Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e8c8c06ccaf8
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ac9922700cad
Choose a head ref
  • 4 commits
  • 7 files changed
  • 1 contributor

Commits on Jul 29, 2020

  1. Copy the full SHA
    5041a0d View commit details
  2. Copy the full SHA
    e1596dc View commit details
  3. Copy the full SHA
    3462c86 View commit details
  4. Copy the full SHA
    ac99227 View commit details
22 changes: 22 additions & 0 deletions scopehal/ProtocolDecoder.cpp
Original file line number Diff line number Diff line change
@@ -110,6 +110,7 @@ void ProtocolDecoderParameter::ParseString(string str)
break;

case TYPE_FILENAME:
case TYPE_FILENAMES:
m_intval = 0;
m_floatval = 0;
m_filename = str;
@@ -153,6 +154,7 @@ string ProtocolDecoderParameter::ToString()
break;
break;
case TYPE_FILENAME:
case TYPE_FILENAMES:
return m_filename;
break;
}
@@ -174,25 +176,45 @@ string ProtocolDecoderParameter::GetFileName()
return m_filename;
}

vector<string> ProtocolDecoderParameter::GetFileNames()
{
return m_filenames;
}

void ProtocolDecoderParameter::SetIntVal(int i)
{
m_intval = i;
m_floatval = i;
m_filename = "";
m_filenames.clear();
}

void ProtocolDecoderParameter::SetFloatVal(float f)
{
m_intval = f;
m_floatval = f;
m_filename = "";
m_filenames.clear();
}

void ProtocolDecoderParameter::SetFileName(string f)
{
m_intval = 0;
m_floatval = 0;
m_filename = f;
m_filenames.clear();
m_filenames.push_back(f);
}

void ProtocolDecoderParameter::SetFileNames(vector<string> names)
{
m_intval = 0;
m_floatval = 0;
if(names.empty())
m_filename = "";
else
m_filename = names[0];
m_filenames = names;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
14 changes: 9 additions & 5 deletions scopehal/ProtocolDecoder.h
Original file line number Diff line number Diff line change
@@ -46,7 +46,8 @@ class ProtocolDecoderParameter
TYPE_FLOAT,
TYPE_INT,
TYPE_BOOL,
TYPE_FILENAME
TYPE_FILENAME, //one file
TYPE_FILENAMES //multiple files
};

ProtocolDecoderParameter(ParameterTypes type = TYPE_INT);
@@ -60,26 +61,29 @@ class ProtocolDecoderParameter
int GetIntVal();
float GetFloatVal();
std::string GetFileName();
std::vector<std::string> GetFileNames();

void SetBoolVal(bool b)
{ m_intval = b; }
void SetIntVal(int i);
void SetFloatVal(float f);
void SetFileName(std::string f);
void SetFileNames(std::vector<std::string> names);

ParameterTypes GetType()
{ return m_type; }

//File filters for TYPE_FILENAME (otherwise ignored)
//File filters for TYPE_FILENAME / TYPE_FILENAMES(otherwise ignored)
std::string m_fileFilterMask;
std::string m_fileFilterName;

protected:
ParameterTypes m_type;

int m_intval;
float m_floatval;
std::string m_filename;
int m_intval;
float m_floatval;
std::string m_filename;
std::vector<std::string> m_filenames;
};

/**
90 changes: 76 additions & 14 deletions scopehal/TouchstoneParser.cpp
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ using namespace std;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SParameterVector

SParameterPoint SParameterVector::InterpolatePoint(float frequency)
SParameterPoint SParameterVector::InterpolatePoint(float frequency) const
{
//Binary search to find the points straddling us
size_t len = m_points.size();
@@ -49,10 +49,7 @@ SParameterPoint SParameterVector::InterpolatePoint(float frequency)

//If out of range, clip
if(frequency < m_points[0].m_frequency)
{
return SParameterPoint(frequency, 1, 0);
//return m_points[0];
}
else if(frequency > m_points[len-1].m_frequency)
return SParameterPoint(frequency, 0, 0);
else
@@ -87,7 +84,11 @@ SParameterPoint SParameterVector::InterpolatePoint(float frequency)
float freq_lo = m_points[last_lo].m_frequency;
float freq_hi = m_points[last_hi].m_frequency;
float dfreq = freq_hi - freq_lo;
float frac = (frequency - freq_lo) / dfreq;
float frac;
if(dfreq > FLT_EPSILON)
frac = (frequency - freq_lo) / dfreq;
else
frac = 0;

//Interpolate amplitude
SParameterPoint ret;
@@ -133,6 +134,33 @@ SParameterPoint SParameterVector::InterpolatePoint(float frequency)
return ret;
}

/**
@brief Multiplies this vector by another set of S-parameters.
Sampling points are kept unchanged, and incident points are interpolated as necessary.
*/
SParameterVector& SParameterVector::operator *=(const SParameterVector& rhs)
{
size_t len = m_points.size();
for(size_t i=0; i<len; i++)
{
auto& us = m_points[i];
auto point = rhs.InterpolatePoint(us.m_frequency);

//Phases add mod +/- pi
us.m_phase += point.m_phase;
if(us.m_phase < -M_PI)
us.m_phase += 2*M_PI;
if(us.m_phase > M_PI)
us.m_phase -= 2*M_PI;

//Amplitudes get multiplied
us.m_amplitude *= point.m_amplitude;
}

return *this;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TouchstoneParser

@@ -161,14 +189,7 @@ void TouchstoneParser::Clear()
bool TouchstoneParser::Load(string fname)
{
Clear();

//Allocate new arrays to hold the S-parameters.
//For now, assume full 2 port.
for(int d=1; d <= 2; d++)
{
for(int s=1; s <= 2; s++)
m_params[SPair(d, s)] = new SParameterVector;
}
Allocate();

//If file doesn't exist, bail early
FILE* fp = fopen(fname.c_str(), "r");
@@ -253,7 +274,48 @@ bool TouchstoneParser::Load(string fname)
//Clean up
fclose(fp);

LogDebug("Loaded %zu S-parameter points\n", m_params[SPair(2,1)]->m_points.size());
LogTrace("Loaded %zu S-parameter points\n", m_params[SPair(2,1)]->m_points.size());

return true;
}

void TouchstoneParser::Allocate()
{
//Allocate new arrays to hold the S-parameters.
//For now, assume full 2 port.
for(int d=1; d <= 2; d++)
{
for(int s=1; s <= 2; s++)
m_params[SPair(d, s)] = new SParameterVector;
}
}

/**
@brief Applies a second set of S-parameters after this one
*/
TouchstoneParser& TouchstoneParser::operator *=(const TouchstoneParser& rhs)
{
//If we have no parameters, just copy whatever is there
if(m_params.empty())
{
Allocate();

for(int d=1; d <= 2; d++)
{
for(int s=1; s <= 2; s++)
*m_params[SPair(d, s)] = *rhs.m_params.find(SPair(d,s))->second;
}
}

//If we have parameters, append the new ones
else
{
for(int d=1; d <= 2; d++)
{
for(int s=1; s <= 2; s++)
*m_params[SPair(d, s)] *= *rhs.m_params.find(SPair(d,s))->second;
}
}

return *this;
}
12 changes: 11 additions & 1 deletion scopehal/TouchstoneParser.h
Original file line number Diff line number Diff line change
@@ -64,9 +64,11 @@ class SParameterVector
{
public:

SParameterPoint InterpolatePoint(float frequency);
SParameterPoint InterpolatePoint(float frequency) const;

std::vector<SParameterPoint> m_points;

SParameterVector& operator *=(const SParameterVector& rhs);
};

/**
@@ -76,6 +78,10 @@ class TouchstoneParser
{
public:
TouchstoneParser();

TouchstoneParser(std::string fname)
{ Load(fname); }

virtual ~TouchstoneParser();

void Clear();
@@ -89,7 +95,11 @@ class TouchstoneParser
SParameterPoint SamplePoint(int to, int from, float frequency)
{ return m_params[ SPair(to, from) ]->InterpolatePoint(frequency); }

TouchstoneParser& operator *=(const TouchstoneParser& rhs);

protected:
void Allocate();

std::map< SPair , SParameterVector*> m_params;
};

10 changes: 8 additions & 2 deletions scopeprotocols/ChannelEmulationDecoder.cpp
Original file line number Diff line number Diff line change
@@ -52,8 +52,14 @@ string ChannelEmulationDecoder::GetProtocolName()

void ChannelEmulationDecoder::SetDefaultName()
{
string fname = m_parameters[m_fname].GetFileName();
string base = basename(fname.c_str());
vector<string> fnames = m_parameters[m_fname].GetFileNames();
string base;
for(auto f : fnames)
{
if(base != "")
base += ", ";
base += basename(f.c_str());
}

char hwname[256];
snprintf(
34 changes: 21 additions & 13 deletions scopeprotocols/DeEmbedDecoder.cpp
Original file line number Diff line number Diff line change
@@ -43,8 +43,8 @@ DeEmbedDecoder::DeEmbedDecoder(string color)
m_signalNames.push_back("din");
m_channels.push_back(NULL);

m_fname = "SxP Path";
m_parameters[m_fname] = ProtocolDecoderParameter(ProtocolDecoderParameter::TYPE_FILENAME);
m_fname = "S-Parameters";
m_parameters[m_fname] = ProtocolDecoderParameter(ProtocolDecoderParameter::TYPE_FILENAMES);
m_parameters[m_fname].m_fileFilterMask = "*.s2p";
m_parameters[m_fname].m_fileFilterName = "Touchstone S-parameter files (*.s2p)";
}
@@ -91,8 +91,14 @@ bool DeEmbedDecoder::NeedsConfig()

void DeEmbedDecoder::SetDefaultName()
{
string fname = m_parameters[m_fname].GetFileName();
string base = basename(fname.c_str());
vector<string> fnames = m_parameters[m_fname].GetFileNames();
string base;
for(auto f : fnames)
{
if(base != "")
base += ", ";
base += basename(f.c_str());
}

char hwname[256];
snprintf(
@@ -133,16 +139,18 @@ void DeEmbedDecoder::DoRefresh(bool invert)
return;
}

//Reload the S-parameters from the Touchstone file if the filename has changed
string fname = m_parameters[m_fname].GetFileName();
if(fname != m_cachedFileName)
//Reload the S-parameters from the Touchstone file(s) if the filename has changed
vector<string> fnames = m_parameters[m_fname].GetFileNames();
if(fnames != m_cachedFileNames)
{
m_cachedFileName = fname;
LogDebug("reloading from %s\n", fname.c_str());
m_sparams.Load(fname);
m_cachedFileNames = fnames;

m_sparams.Clear();
for(auto f : fnames)
m_sparams *= TouchstoneParser(f);
}

//TODO: optimization, resample s-parameters to our sample rate once vs ever waveform update
//TODO: optimization, resample s-parameters to our sample rate once vs every waveform update

//We need meaningful data
const size_t npoints_raw = din->m_samples.size();
@@ -154,8 +162,8 @@ void DeEmbedDecoder::DoRefresh(bool invert)

//Truncate to next power of 2 down
const size_t npoints = pow(2,floor(log2(npoints_raw)));
LogTrace("DeEmbedDecoder: processing %zu raw points\n", npoints_raw);
LogTrace("Rounded to %zu\n", npoints);
//LogTrace("DeEmbedDecoder: processing %zu raw points\n", npoints_raw);
//LogTrace("Rounded to %zu\n", npoints);

//Format the input data as raw samples for the FFT
//TODO: handle non-uniform sample rates
2 changes: 1 addition & 1 deletion scopeprotocols/DeEmbedDecoder.h
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ class DeEmbedDecoder : public ProtocolDecoder
protected:
std::string m_fname;

std::string m_cachedFileName;
std::vector<std::string> m_cachedFileNames;

TouchstoneParser m_sparams;
};