FIR Filter Box Instrument

The FIR Filter Box implements finite impulse response (FIR) filters at up to 15 MS/s and with over 14,000 coefficients at 244 kS/s. The instrument has two independent filter chains, a control matrix to combine signals from both ADCs, input/output scaling and offsets and oscilloscope monitor probes to view signals at different points in the instrument.

Example Usage

The following example code and a wide range of other pymoku demo scripts can be found at the pymoku Github repository.

firfilter_basic.py
# pymoku example: Basic FIR Filter Box
#
# This example demonstrates how to run the FIR Filter Box and configure its
# individual filter channel coefficients.
#
# (c) 2019 Liquid Instruments Pty. Ltd.
#
from pymoku import Moku
from pymoku.instruments import FIRFilter

# The following two example arrays are simple rectangular FIR kernels with 50
# and 400 taps respectively. A rectangular kernel produces a sinc shaped
# transfer function with width inversely proportional to the length of the
# kernel. FIR kernels must have a normalised power of <= 1.0, so the value of
# each tap is the inverse of the total number of taps.
filt_coeff1 = [1.0 / 50.0] * 50
filt_coeff2 = [1.0 / 400.0] * 400

# Connect to your Moku by its device name
# Alternatively, use Moku.get_by_serial('#####') or Moku('192.168.###.###')
m = Moku.get_by_name('Moku')

try:
	i = m.deploy_or_connect(FIRFilter)

	# Configure the Moku:Lab's frontend settings
	i.set_frontend(1, fiftyr=True, atten=False, ac=False)
	i.set_frontend(2, fiftyr=True, atten=False, ac=False)

	# Load the coefficients for each FIR filter channel.
	#
	# The channel's decimation factor determines the filter sample rate (Fs) and
	# the maximum number of filter kernel coefficients (N) for the channel.
	# The defining equations are given by:
	#
	#   3 <= decimation_factor <= 10,
	# 	Fs = 125 MHz / 2^decimation_factor,
	# 	N  = 2^(decimation_factor) * 29.
	#
	# To implement 50 FIR taps, N = 2^(3) * 29 = 232 > 50
	i.set_filter(1, decimation_factor=3, filter_coefficients=filt_coeff1)
	# To implement 400 FIR taps, N = 2^(4) * 29 = 464 > 400
	i.set_filter(2, decimation_factor=4, filter_coefficients=filt_coeff2)

	# Both channels have unity gain and no offsets
	i.set_gains_offsets(1, input_gain=1.0, output_gain=1.0, input_offset=0,
		output_offset=0)
	i.set_gains_offsets(2, input_gain=1.0, output_gain=1.0, input_offset=0,
		output_offset=0)

finally:
	m.close()

The FIRFilter Class

class pymoku.instruments.FIRFilter

The FIR Filter Box instrument implements two Finite Impulse Response (FIR) filter channels with kernels consisting of over 14,000 coefficients. The transfer function can be written:

\[H(z) = \sum_{k=1}^{N} b_k * z^{-k} \]

where \(N\) is the number of coefficients and \(b_k\) is the k-th coefficient.

To configure a filter kernel, call the set_filter() function with a 1-D coefficient array containing all coefficients in your filter kernel. Note that the array does not need to be zero-padded to the maximum kernel length, and the coefficients must be normalised to the range [-1.0, 1.0]. i.e.

\[[b_1, b_2, b_3, ... b_N] = [ 0.3, -0.2, 0.12, ... 0.5 ]\]

Internally, the coefficients are represented as signed 25-bit fixed-point numbers. Filter coefficients can be computed using signal processing toolboxes in e.g. MATLAB or SciPy.

Each filter channel can run at one of eight sampling rates, as summarised in the table below. These sample rates correspond to a division of the 125 MHz clock by powers of 2 between 3-10. Sample rates are configured in the set_filter() function by specifying the power of 2 exponent as the decimation_factor function argument.

The maximum number of kernel coefficients that can be implemented follows the following formula:

\[N_{max} = min(29 * 2^{decimation\_factor}, 14819)\]
Sample rate Decimation Factor Max # Coefficients
15.625 MHz 3 232
7.8125 MHz 4 464
~3.906 MHz 5 928
~1.953 MHz 6 1856
~976.6 kHz 7 3712
~488.3 kHz 8 7424
~244.2 kHz 9 14819
~122.1 kHz 10 14819

Warning

The overall output gain of the instrument is the product of the gain of the filter, set in the coefficient kernel array. To avoid clipping with full-range input signals, you should ensure that the sum of all coefficients in the kernel is <= 1.0.

To run a new FIR Filter Box instrument, this class should be instantiated and deployed via a connected Moku object using deploy_instrument. Alternatively, a pre-configured instrument object can be obtained by discovering an already running FIR Filter Box instrument on a Moku:Lab device via deploy_or_connect.

__init__()

Must be called as the first line from any child implementations.

type = "firfilter"

Name of this instrument.

commit()

Apply all modified settings.

Note

If the autocommit feature has been turned off, this function can be used to manually apply any instrument settings to the Moku device. These instrument settings are those configured by calling all set_ and gen_ type functions. Manually calling this function allows you to atomically apply many instrument settings at once.

disable_output(*args, **kwargs)

Disables the output of the specified FIR filter channel.

Parameters:ch (int; {1,2}) – target channel
get_data(timeout=None, wait=True)

Get full-resolution data from the instrument.

This will pause the instrument and download the entire contents of the instrument’s internal memory. This may include slightly more data than the instrument is set up to record due to rounding of some parameters in the instrument.

All settings must be committed before you call this function. If pymoku.autocommit=True (the default) then this will always be true, otherwise you will need to have called commit first.

The download process may take a second or so to complete. If you require high rate data, e.g. for rendering a plot, see get_realtime_data.

If the wait parameter is true (the default), this function will wait for any new settings to be applied before returning. That is, if you have set a new timebase (for example), calling this with wait=True will guarantee that the data returned has this new timebase.

Note that if instrument configuration is changed, a trigger event must occur before data captured with that configuration set can become available. This can take an arbitrary amount of time. For this reason the timeout should be set appropriately.

Parameters:
  • timeout (float) – Maximum time to wait for new data, or None for indefinite.
  • wait (bool) – If true (default), waits for a new waveform to be captured with the most recently-applied settings, otherwise just return the most recently captured valid data.
Returns:

InstrumentData subclass, specific to the instrument.

get_frontend(channel)

Get the analog frontend configuration.

Parameters:channel (int; {1,2}) – Channel for which the relay settings are being retrieved
Returns:Array of bool with the front end configuration of channels - [0] 50 Ohm - [1] 10xAttenuation - [2] AC Coupling
get_realtime_data(timeout=None, wait=True)

Get downsampled data from the instrument with low latency.

Returns a new InstrumentData subclass (instrument-specific), containing a version of the data that may have been downsampled from the original in order to be transferred quickly.

This function always returns a new object at framerate (10Hz by default), whether or not there is new data in that object. This can be verified by checking the return object’s waveformid parameter, which increments each time a new waveform is captured internally.

The downsampled, low-latency nature of this data makes it particularly suitable for plotting in real time. If you require high-accuracy, high-resolution data for analysis, see get_data.

If the wait parameter is true (the default), this function will wait for any new settings to be applied before returning. That is, if you have set a new timebase (for example), calling this with wait=True will guarantee that the data returned has this new timebase.

Note that if instrument configuration is changed, a trigger event must occur before data captured with that configuration set can become available. This can take an arbitrary amount of time. For this reason the timeout should be set appropriately.

Parameters:
  • timeout (float) – Maximum time to wait for new data, or None for indefinite.
  • wait (bool) – If true (default), waits for a new waveform to be captured with the most recently-applied settings, otherwise just return the most recently captured valid data.
Returns:

InstrumentData subclass, specific to the instrument.

get_samplerate()
Returns:The current instrument sample rate (Hz)
set_control_matrix(*args, **kwargs)

Configure the input control matrix specifying the input signal mixing for the specified filter channel.

Input mixing allows a filter channel to act on a linear combination of the two input signals.

Parameters:
  • ch (int, {1, 2}) – target filter channel
  • scale_in1 (float, [-20, 20]) – linear scale factor of input 1 signal added to target filter channel input. To avoid quantization, use at most one decimal place.
  • scale_in2 (float, [-20, 20]) – linear scale factor of input 2 signal added to target filter channel input. To avoid quantization, use at most one decimal place.
set_defaults(*args, **kwargs)

Reset the Oscilloscope to sane defaults.

set_filter(ch, decimation_factor, filter_coefficients)

Set FIR filter sample rate and kernel coefficients for the specified filter channel. This will enable the specified channel output. See class documentation for information on the filter_coefficients array formatting and how decimation_factor relates to instrument sample rate.

Parameters:
  • ch (int; {1,2}) – Filter channel.
  • decimation_factor (int; [3,10]) – the binary exponent n specifying the filter sample rate: \(Fs = 125 MHz / 2^n\).
  • filter_coefficients (array(float)) – array of FIR filter coefficients. The length of the array must not exceed \(N = min(29*2^n, 14819)\).
set_framerate(*args, **kwargs)

Set framerate

set_frontend(channel, fiftyr=True, atten=False, ac=False)

Configures gain, coupling and termination for each channel.

Parameters:
  • channel (int; {1,2}) – Channel to which the settings should be applied
  • fiftyr (bool) – 50Ohm termination; default is 1MOhm.
  • atten (bool) – Turn on 10x attenuation. Changes the dynamic range between 1Vpp and 10Vpp.
  • ac (bool) – AC-couple; default DC.
set_gains_offsets(*args, **kwargs)

Configure pre- and post-filter scales and offsets for a given filter channel.

Note

The overall output gain of the instrument is the product of the gain of the filter, set by the filter coefficients, and the input/output stage gain set here.

Parameters:
  • ch (int, {1,2}) – target filter channel
  • output_gain (input_gain,) – channel scalars before and after the FIR filter
  • input_offset (float, volts, [-1.0,1.0]) – channel offset before the FIR filter
  • output_offset (float, volts, [-2.0,2.0]) – channel offset after the FIR filter
set_monitor(*args, **kwargs)

Configures the specified monitor channel to view the desired filterbox signal.

There are two 12-bit monitoring channels available, ‘a’ and ‘b’; each of these can be assigned to source signals from any of the internal filterbox monitoring points. Signals larger than 12-bits must be either truncated or clipped to the allowed size.

The source is one of:
  • adc1 : Channel 1 ADC input
  • in1 : Filter Channel 1 input (after mixing, offset and scaling)
  • out1 : Filter Channel 1 output
  • adc2 : Channel 2 ADC Input
  • in2 : Filter Channel 2 input (after mixing, offset and scaling)
  • out2 : Filter Channel 2 output
Parameters:
  • monitor_ch (str; {'a','b'}) – Monitor channel
  • source (str; {'adc1', 'in1', 'out1', 'adc2', 'in2', 'out2'}) – Signal to connect to the monitor channel
  • clip (bool;) – Enable signal clipping to the allowed size (truncate is default).
set_precision_mode(*args, **kwargs)

Change aquisition mode between downsampling and decimation. Precision mode, a.k.a Decimation, samples at full rate and applies a low-pass filter to the data. This improves precision. Normal mode works by direct downsampling, throwing away points it doesn’t need.

Parameters:state (bool) – Select Precision Mode
set_samplerate(*args, **kwargs)

Manually set the sample rate of the instrument.

The sample rate is automatically calculated and set in set_timebase.

This interface allows you to specify the rate at which data is sampled, and set a trigger offset in number of samples. This interface is useful for datalogging and capturing of data frames.

Parameters:
  • samplerate (float; 0 < samplerate <= MAX_SAMPLERATE smp/s) – Target samples per second. Will get rounded to the nearest allowable unit.
  • trigger_offset (int; -2^16 < trigger_offset < 2^31) – Number of samples before (-) or after (+) the trigger point to start capturing.
Raises:

ValueOutOfRangeException – if either parameter is out of range.

set_timebase(*args, **kwargs)

Set the left- and right-hand span for the time axis. Units are seconds relative to the trigger point.

Parameters:
  • t1 (float) – Time, in seconds, from the trigger point to the left of screen. This may be negative (trigger on-screen) or positive (trigger off the left of screen).
  • t2 (float) – As t1 but to the right of screen.
Raises:

InvalidConfigurationException – if the timebase is backwards or zero.

set_trigger(*args, **kwargs)

Set the trigger source for the monitor channel signals. This can be either of the input or monitor signals, or the external input.

Parameters:
  • source (string, {'in1','in2','A','B','ext'}) – Trigger Source. May be either an input or monitor channel (as set by set_monitor()), or external. External refers to the back-panel connector of the same name, allowing triggering from an externally-generated digital [LV]TTL or CMOS signal.
  • edge (string, {'rising','falling','both'}) – Which edge to trigger on. In Pulse Width modes this specifies whether the pulse is positive (rising) or negative (falling), with the ‘both’ option being invalid.
  • level (float, [-10.0, 10.0] volts) – Trigger level
  • minwidth (float, seconds) – Minimum Pulse Width. 0 <= minwidth < (2^32/samplerate). Can’t be used with maxwidth.
  • maxwidth (float, seconds) – Maximum Pulse Width. 0 <= maxwidth < (2^32/samplerate). Can’t be used with minwidth.
  • hysteresis (float, [100e-6, 1.0] volts) – Hysteresis around trigger point.
  • hf_reject (bool) – Enable high-frequency noise rejection
  • mode (string, {'auto', 'normal'}) – Trigger mode.
set_xmode(*args, **kwargs)

Set rendering mode for the horizontal axis.

Parameters:xmode (string, {'roll','sweep','fullframe'}) – Respectively; Roll Mode (scrolling), Sweep Mode (normal oscilloscope trace sweeping across the screen) or Full Frame (like sweep, but waits for the frame to be completed).