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: 56b6fcf9feb6
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 06cd31a0ec19
Choose a head ref
  • 1 commit
  • 4 files changed
  • 1 contributor

Commits on Aug 16, 2020

  1. Copy the full SHA
    06cd31a View commit details
Showing with 49 additions and 6 deletions.
  1. +7 −0 scopehal/Unit.cpp
  2. +1 −0 scopehal/Unit.h
  3. +40 −5 scopeprotocols/FFTDecoder.cpp
  4. +1 −1 scopeprotocols/WaterfallDecoder.cpp
7 changes: 7 additions & 0 deletions scopehal/Unit.cpp
Original file line number Diff line number Diff line change
@@ -142,6 +142,13 @@ string Unit::PrettyPrint(double value)
unit = "bps";
break;

//dBm are always reported as is, with no SI prefixes
case UNIT_DBM:
unit = "dBm";
scale = "";
value_rescaled = value;
break;

//Dimensionless unit, no scaling applied
case UNIT_PERCENT:
unit = "%";
1 change: 1 addition & 0 deletions scopehal/Unit.h
Original file line number Diff line number Diff line change
@@ -56,6 +56,7 @@ class Unit
UNIT_BITRATE, //Bits per second
UNIT_PERCENT, //Dimensionless ratio
UNIT_DB, //Dimensionless ratio
UNIT_DBM, //dB mW (more common than dBW)
UNIT_COUNTS, //Dimensionless ratio (histogram)
UNIT_LOG_BER, //Dimensionless ratio (log scale)
UNIT_SAMPLERATE, //Sample rate (Hz but displayed as S/s)
45 changes: 40 additions & 5 deletions scopeprotocols/FFTDecoder.cpp
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ FFTDecoder::FFTDecoder(string color)
: ProtocolDecoder(OscilloscopeChannel::CHANNEL_TYPE_ANALOG, color, CAT_RF)
{
m_xAxisUnit = Unit(Unit::UNIT_HZ);
m_yAxisUnit = Unit(Unit::UNIT_DB);
m_yAxisUnit = Unit(Unit::UNIT_DBM);

//Set up channels
m_signalNames.push_back("din");
@@ -193,6 +193,9 @@ void FFTDecoder::Refresh()
*/
void FFTDecoder::NormalizeOutput(AnalogWaveform* cap, size_t nouts, size_t npoints)
{
//assume constant 50 ohms for now
const float impedance = 50;

for(size_t i=0; i<nouts; i++)
{
cap->m_offsets[i] = i;
@@ -201,7 +204,10 @@ void FFTDecoder::NormalizeOutput(AnalogWaveform* cap, size_t nouts, size_t npoin
float real = m_rdout[i*2];
float imag = m_rdout[i*2 + 1];

cap->m_samples[i] = sqrtf(real*real + imag*imag) / npoints;
float voltage = sqrtf(real*real + imag*imag) / npoints;

//Convert to dBm
cap->m_samples[i] = (10 * log10(voltage*voltage / impedance) + 30);
}
}

@@ -228,6 +234,18 @@ void FFTDecoder::NormalizeOutputAVX2(AnalogWaveform* cap, size_t nouts, size_t n
float norm = 2.0f / npoints;
__m256 norm_f = { norm, norm, norm, norm, norm, norm, norm, norm };

//1 / nominal line impedance
float impedance = 50;
__m256 inv_imp =
{
1/impedance, 1/impedance, 1/impedance, 1/impedance,
1/impedance, 1/impedance, 1/impedance, 1/impedance
};

//Constant values for dBm conversion
__m256 const_10 = {10, 10, 10, 10, 10, 10, 10, 10 };
__m256 const_30 = {30, 30, 30, 30, 30, 30, 30, 30 };

float* pout = (float*)&cap->m_samples[0];

//Vectorized processing (8 samples per iteration)
@@ -266,8 +284,22 @@ void FFTDecoder::NormalizeOutputAVX2(AnalogWaveform* cap, size_t nouts, size_t n
__m256 mag = _mm256_sqrt_ps(sum);
mag = _mm256_mul_ps(mag, norm_f);

//Done
_mm256_store_ps(pout + k, mag);
//Convert to watts
__m256 vsq = _mm256_mul_ps(mag, mag);
__m256 watts = _mm256_mul_ps(vsq, inv_imp);

//TODO: figure out better way to do efficient logarithm
_mm256_store_ps(pout + k, watts);
for(size_t i=k; i<k+8; i++)
pout[i] = log10(pout[i]);
__m256 logpwr = _mm256_load_ps(pout + k);

//Final scaling
logpwr = _mm256_mul_ps(logpwr, const_10);
logpwr = _mm256_add_ps(logpwr, const_30);

//and store the actual
_mm256_store_ps(pout + k, logpwr);
}

//Get any extras we didn't get in the SIMD loop
@@ -279,6 +311,9 @@ void FFTDecoder::NormalizeOutputAVX2(AnalogWaveform* cap, size_t nouts, size_t n
float real = m_rdout[k*2];
float imag = m_rdout[k*2 + 1];

cap->m_samples[k] = sqrtf(real*real + imag*imag) / npoints;
float voltage = sqrtf(real*real + imag*imag) / npoints;

//Convert to dBm
pout[k] = (10 * log10(voltage*voltage / impedance) + 30);
}
}
2 changes: 1 addition & 1 deletion scopeprotocols/WaterfallDecoder.cpp
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ WaterfallDecoder::WaterfallDecoder(string color)

bool WaterfallDecoder::ValidateChannel(size_t i, OscilloscopeChannel* channel)
{
if( (i == 0) && (channel->GetYAxisUnits() != Unit::UNIT_DB) )
if( (i == 0) && (channel->GetYAxisUnits() != Unit::UNIT_DBM) )
return true;
return false;
}