analogdevicesinc / scopy

A software oscilloscope and signal analysis toolset
http://wiki.analog.com/scopy
GNU General Public License v3.0
385 stars 158 forks source link

Add HDL generated pattern for the Pattern Generator #49

Open acostina opened 7 years ago

acostina commented 7 years ago

In case we are streaming from the buffer a waveform with a relatively small number of samples (high frequency) and on another channel we want to have a periodic PWM-like signal at a low frequency (which would require a large number of samples), we could generate the low frequency waveform in HDL.

adisuciu commented 7 years ago

It's not just high frequency and low frequency signals in the same buffer. The problem also occurs when you try to generate signals which are coprime or have low common divisors.

In order to ensure periodicity of the signals one needs to make sure that the signals are periodic within the buffer (they both end on the same sample, regardless of how many periods there are in the buffer). Therefore we need to compute the sampling rate and the number of samples for each signal and then do the least common multiplier between these values.

Let's take for example 2 signals:

  1. 1333Hz , 20% duty cycle - 5 samples/period - minimum sampling frequency = 5 * 1333 Hz = 6665 Hz
  2. 5000Hz, 25% duty cycle - 4 samples/period - minimum sampling frequency = 4 * 5000 Hz = 20000 Hz

The frequency which would ensure correct sampling of both these frequencies would be the least common multiplier between the 2 sampling frequencies. LCM(1333,5000) = 26 660 000 Hz

Since M2K cannot generate this sampling frequency we take the next suitable frequency which is 40MHz Using 40MHz as sampling frequency, we need to compute the necessary number of samples for each signal period:

samplerate / frequency

  1. 40 000 000 / 1333 = 30007.5 - samples required for 1 period (error occurs due to rounding of sampling frequency from 26.66MHz to 40MHz)
  2. 40 000 000 / 5000 = 8000 - samples required for 1 period

Creating a buffer of size 30008 samples will not do because the second signal will not fit perfectly within a 30008 sample buffer. In order to make both signals fit perfectly within the buffer, a least common multiplier needs to be computed between the 2 buffer sizes.

LCM(30008, 8000) = 30 008 000

This is buffer size in samples. The size of the allocated memory is ~60 MB. If we decided to take a 30007 sample buffer instead of 30008, the resulting memory would be:

LCM(30007, 8000) = 240 056 000 (the numbers are coprime) ~ 0.5 GB

The allocated memory is huge even if we decide to stream the data to the M2K( which i'm not sure is possible, having 40MHz sampling rate)

Of course we can introduce errors in order to minimize the sampling rate/buffersize, but there are other sets of data for which would yield these huge buffers.

My proposed solution would be generating all clock-like signals in HDL using a simple counter component for each channel. Each channel could be configured via IIO in buffer/counter mode. When buffer mode is selected, data will be outputted from the DMA. When counter mode is enabled, the output pin is driven by the indepenendtly running counter. The counters should be configurable via IIO and the counter/buffer should be synchronized so the counter/buffer uses the same start signal to output the data.