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: d8db8f20b228
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ede70ff08b1f
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Aug 9, 2020

  1. Copy the full SHA
    9614f63 View commit details
  2. Copy the full SHA
    ede70ff View commit details
Showing with 62 additions and 25 deletions.
  1. +53 −25 scopeprotocols/DeEmbedDecoder.cpp
  2. +9 −0 scopeprotocols/DeEmbedDecoder.h
78 changes: 53 additions & 25 deletions scopeprotocols/DeEmbedDecoder.cpp
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@

#include "../scopehal/scopehal.h"
#include "DeEmbedDecoder.h"
#include <ffts.h>

using namespace std;

@@ -52,6 +51,26 @@ DeEmbedDecoder::DeEmbedDecoder(string color)
m_offset = 0;
m_min = FLT_MAX;
m_max = -FLT_MAX;
m_cachedBinSize = 0;

m_forwardPlan = NULL;
m_reversePlan = NULL;
m_cachedNumPoints = 0;
}

DeEmbedDecoder::~DeEmbedDecoder()
{
if(m_forwardPlan)
{
ffts_free(m_forwardPlan);
m_forwardPlan = NULL;
}

if(m_reversePlan)
{
ffts_free(m_reversePlan);
m_reversePlan = NULL;
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -161,6 +180,10 @@ void DeEmbedDecoder::DoRefresh(bool invert)
m_sparams.Clear();
for(auto f : fnames)
m_sparams *= TouchstoneParser(f);

//Clear out cached S-parameters
m_cachedBinSize = 0;
m_resampledSparams.clear();
}

//Don't die if the file couldn't be loaded
@@ -170,8 +193,6 @@ void DeEmbedDecoder::DoRefresh(bool invert)
return;
}

//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();
if(npoints_raw == 0)
@@ -211,26 +232,45 @@ void DeEmbedDecoder::DoRefresh(bool invert)
posix_memalign((void**)&rdout, 32, 2 * nouts * sizeof(float));
#endif

//Calculate the FFT
auto plan = ffts_init_1d_real(npoints, FFTS_FORWARD);
ffts_execute(plan, &rdin[0], &rdout[0]);
ffts_free(plan);
//Set up the FFT if we change point count
if(m_cachedNumPoints != npoints)
{
if(m_forwardPlan)
ffts_free(m_forwardPlan);
m_forwardPlan = ffts_init_1d_real(npoints, FFTS_FORWARD);

if(m_reversePlan)
ffts_free(m_reversePlan);
m_reversePlan = ffts_init_1d_real(npoints, FFTS_BACKWARD);

m_cachedNumPoints = npoints;
}

//Do the actual FFT
ffts_execute(m_forwardPlan, &rdin[0], &rdout[0]);

//Calculate size of each bin
double ps = din->m_timescale * (din->m_offsets[1] - din->m_offsets[0]);
double sample_ghz = 1000 / ps;
double bin_hz = round((0.5f * sample_ghz * 1e9f) / nouts);

//Resample S21 to our FFT bin size
if(fabs(m_cachedBinSize - bin_hz) > FLT_EPSILON)
{
m_cachedBinSize = bin_hz;

for(size_t i=0; i<nouts; i++)
m_resampledSparams.push_back( m_sparams.SamplePoint(2, 1, bin_hz * i) );
}

//Do the actual de-embed
if(invert)
{
for(size_t i=0; i<nouts; i++)
{
//Resample the S-parameter file for our point
float freq = bin_hz * i;
auto point = m_sparams.SamplePoint(2, 1, freq);
auto &point = m_resampledSparams[i];

//Zero channel response = flatten
//Zero channel response = flatten rather than dividing by zero
if(fabs(point.m_amplitude) < FLT_EPSILON)
{
rdout[i*2 + 0] = 0;
@@ -260,17 +300,7 @@ void DeEmbedDecoder::DoRefresh(bool invert)
{
for(size_t i=0; i<nouts; i++)
{
//Resample the S-parameter file for our point
float freq = bin_hz * i;
auto point = m_sparams.SamplePoint(2, 1, freq);

//Zero channel response = flatten
if(fabs(point.m_amplitude) < FLT_EPSILON)
{
rdout[i*2 + 0] = 0;
rdout[i*2 + 1] = 0;
continue;
}
auto &point = m_resampledSparams[i];

float cosval = cos(point.m_phase);
float sinval = sin(point.m_phase);
@@ -298,9 +328,7 @@ void DeEmbedDecoder::DoRefresh(bool invert)
#endif

//Calculate the inverse FFT
plan = ffts_init_1d_real(npoints, FFTS_BACKWARD);
ffts_execute(plan, &rdout[0], &ddout[0]);
ffts_free(plan);
ffts_execute(m_reversePlan, &rdout[0], &ddout[0]);

//Calculate maximum group delay for the first few S-parameter bins (approx propagation delay of the channel)
auto& s21 = m_sparams[SPair(2,1)];
9 changes: 9 additions & 0 deletions scopeprotocols/DeEmbedDecoder.h
Original file line number Diff line number Diff line change
@@ -36,11 +36,13 @@
#define DeEmbedDecoder_h

#include "../scopehal/ProtocolDecoder.h"
#include <ffts/ffts.h>

class DeEmbedDecoder : public ProtocolDecoder
{
public:
DeEmbedDecoder(std::string color);
virtual ~DeEmbedDecoder();

virtual void Refresh();

@@ -70,7 +72,14 @@ class DeEmbedDecoder : public ProtocolDecoder
float m_range;
float m_offset;

double m_cachedBinSize;
std::vector<SParameterPoint> m_resampledSparams;

TouchstoneParser m_sparams;

ffts_plan_t* m_forwardPlan;
ffts_plan_t* m_reversePlan;
size_t m_cachedNumPoints;
};

#endif