N109X-Series Osciloscope with N1076/7A

This Python example uses an N109X-series DCA-M oscilloscope and N1076/7A clock recovery to perform an eye measurement (bit rate) on channel 6A. It is the same as N109X-Series Osciloscope example, but adds clock recovery. The programs performs the following tasks:

  • Places FlexDCA to its default settings. This places the FlexDCA triggering to front panel which is required to view a valid eye diagram.
  • Configures the clock recovery.
  • Configures N109X.
  • Queries the N109X to see if it supports pattern locking (option PLK) and then turns on pattern locking if available.
  • Returns the measured trigger rate that is input to the N109X.
  • Runs an acquisition limit test and then activates the bit-rate measurement on the data.

About the :TRIGger:MRATe? query

The :TRIGger:MRATe? query returns the baud rate of the N109X’s clock input signal. For this query to work, at least one of the N109X’s input channels must be turned on, but a signal does not need to be connected to the channel. Also, the N109X’s data acquisition must be in Run mode, or, if in single mode, a single acquisition must first be run to ensure valid data for the measurement.

To run this program

  • Run this program on a PC that has FlexDCA running. In the following program listing, FlexDCA is identified by the red text: localhost.
  • If you change localhost to an 86100D, you can run the program on a PC to control FlexDCA on an 86100D. Connect the N109X to the 86100D.
  • Install an N109X-series oscilloscope to FlexDCA’s slot 6. Change the DCAMSLT constant if you want to use a different slot.
  • Install an N1076/7A clock recovery to FlexDCA’s slot 5. Change the RECSLT constant if you want to use a different slot.
  • Data in is expected to be 10.3125 GBd, but you can change this to any acceptable rate for the oscilloscope.
  • Connect valid signal to channel 6A on the N1090X.
  • Connect a clock to the N1090X’s Clock In.
  • Display an eye diagram on FlexDCA.

Example Script

Copy

DCA-M-eye-meas-N107X.py

# -*- coding: utf-8 -*-
""" Demonstrates using a DCA-M oscilloscope with N107x-series clock
recovery to make a bit-rate eye measurement. Requires:
N109X-series DCA-M oscilloscope in slot 6. N1076/7A in slot 5.
Change the N107X_SLOT and N109X_SLOT constants if you want to use
different slots.
Runs on a PC that is controlling an N109X / N1076/7A that are
connected to the PC.
Edit "localhost" in address to a DCA-X if the N109x is connected to an
DCA-X.
Data in is expected to be 10.3125 Gb/s Data In, but you can change this
to any acceptable rate for the oscilloscope in the DRATE constant.
The default setup command places the DCA-X and DCA-M triggering to front
panel which is required to view a valid eye diagram.
"""

import pyvisa as visa  # import VISA library

visa_address = 'TCPIP0::localhost::hislip0,4880::INSTR'
ADDRESS = 'TCPIP0::localhost::hislip0,4880::INSTR'
N107X_SLOT = '5'  # N1077A's slot
N109X_SLOT = '6'  # N1092D's slot
DRATE = '10.312500E+9'  # input data rate


def open_flexdca_connection(address):
    """ Opens visa connection to FlexFlexDCA. """
    try:
        rm = visa.ResourceManager()
        connection = rm.open_resource(address)
        connection.timeout = 20000  # Set connection timeout to 20s
        connection.read_termination = '\n'
        connection.write_termination = '\n'
        inst_id = connection.query('*IDN?')
        print('\nFlexDCA connection established to:\n' + inst_id, flush=True)
        connection.write(':SYSTem:DEFault')
        connection.query('*OPC?')
    except (visa.VisaIOError, visa.InvalidSession):
        print('\nVISA ERROR: Cannot open instrument address.\n', flush=True)
        return None
    except Exception as other:
        print('\nVISA ERROR: Cannot connect to instrument:', other, flush=True)
        print('\n')
        return None
    return connection


def all_channels_off(FlexDCA):
    """ Turns all available channels off. """
    for slot in '12345678':
        for letter in 'ABCD':
            channel = slot + letter
            FlexDCA.write(':CHANnel' + channel + ':DISPlay OFF')


def setup(FlexDCA, N109X_SLOT, N107X_SLOT):
    # Default all settings. Set trigger and turn on channel.
    FlexDCA.query(':SYSTem:DEFault;*OPC?')
    FlexDCA.write(':TRIGger:SOURce FPANel')
    all_channels_off(FlexDCA)
    FlexDCA.write(':CHAN'+N109X_SLOT+'A:DISPlay ON')  # Turn channel 'A' on
    # Configure N1077A clock recovery.
    FlexDCA.write(':CRECovery' + N107X_SLOT +
                  ':SOURce ELECtrical')  # set input type
    FlexDCA.write(':CRECovery' + N107X_SLOT +
                  ':CRATe ' + DRATE)  # set input data rate
    FlexDCA.write(':CRECovery' + N107X_SLOT +
                  ':CLBandwidth 5.692E+6')  # set PLL loop BW
    FlexDCA.query(':CRECovery' + N107X_SLOT + ':RELock;*OPC?')


def setup_dcam(FlexDCA, N109X_SLOT):
    """ Configure DCA-M and query measured clock input rate."""
    FlexDCA.write(':ACQuire:SINGle')
    clockrate = FlexDCA.query(':SLOT'+N109X_SLOT+':TRIG:MRATe?')
    if '-1.00' in clockrate or '0.00' in clockrate:
        print('DCA-M is not triggered. Check inputs.')
        return False
    FlexDCA.query(':ACQ:RUN;*OPC?')
    FlexDCA.query(':SYSTem:MODE EYE;*OPC?')
    return True


def pattern_lock(FlexDCA, N109X_SLOT, DRATE):
    """ If DCA-M pattern lock option is installed, configure acquisition
    test to acquire pattern waveforms. """
    if 'PLK' in FlexDCA.query(':SYST:OPTions? SLOT'+N109X_SLOT):
        FlexDCA.write(':TRIGger:BRATe:AUTodetect OFF')
        FlexDCA.write(':TIMebase:BRATe ' + DRATE)
        FlexDCA.write(':SLOT'+N109X_SLOT+':TRIGger:TRACking ON')
        FlexDCA.query(':TRIGger:PLOCk ON;*OPC?')
        print('Pattern lock on.')
        return True
    return False


def make_measurement(patternlock):
    """ Perform acquisition limit test and bit-rate measurement. """
    FlexDCA.query(':AUToscale;*OPC?')
    FlexDCA.write(':ACQuire:STOP;:ACQuire:CDISplay')
    if patternlock:
        FlexDCA.write(':LTESt:ACQuire:CTYPe:PATTerns 1')
    else:
        FlexDCA.write(':LTESt:ACQuire:CTYPe:WAVeforms 100')
    FlexDCA.write(':LTESt:ACQuire:STATe ON')
    FlexDCA.query(':ACQuire:RUN;*OPC?')
    FlexDCA.write(':LTESt:ACQuire:STATe OFF')
    FlexDCA.write(':MEASure:EYE:BITRate')
    print('Measured:')
    print('  Eye Bit Rate: ' + FlexDCA.query(':MEASure:EYE:BITRate?') + ' b/s')
    print('  Clock rate: ' + FlexDCA.query(':SLOT'+N109X_SLOT+':TRIG:MRATe?') +
          ' baud (Bd)')


FlexDCA = open_flexdca_connection(visa_address)
setup(FlexDCA, N109X_SLOT, N107X_SLOT)
if setup_dcam(FlexDCA, N109X_SLOT):
    make_measurement(pattern_lock(FlexDCA, N109X_SLOT, DRATE))
FlexDCA.write(':SYSTem:GTLocal')
FlexDCA.close()