TDR mode DUT setup with fixture de-embedding
This Python example, tdr_dut_setup.py, creates a 2-port single-ended DUT setup and applies fixture de-embedding. No TDR waveforms are captured or measured, as this script simply shows how to successfuly setup a DUT with de-embedding. Before running the script, you must install a TDR module in the N1000A's slot 1. Calibrate the module.
TDR/TDT instrument mode requires a instrument as there are no simulated TDR/TDT modules. Perform a TDR step calibration on the TDR module before running the script.
Editable Constants
At the top of the script, edit the following three global constants with your values. Each constant must have a value and all three are passed to the basic_setup()
function. Refer to locating the VISA address.
- ADDRESS
- Edit this constant to be the VISA HiSLIP address for FlexDCA on the PC or an DCA-X.
- SPARAMETER_FILE
- The file name including path for the s2p file that is loaded into the new deembed fixtures. This happens in the
create_deembed_fixture()
function. The file is imported from FlexDCA's Demo folder, which is sure to be available for the script. Any s2p that you want can be substituted. The demo folder is indicated by the path substitution variable (%DEMO_DIR%
). Path subsitution variables make saving files in the default user folders easier and more reliable because they automatically point to different paths depending if FlexDCA is running on a PC or N1000A.
Script Notes
The find_available_dut()
function, locates the first available DUT definition. Up to 16 DUTs can be defined. Determines the next available DUT
number and returns that DUT. So, if 3 DUTs exist, it returns "DUT4".
The find_available_fixtures()
function, locates the first available deembed definition. Up to 16 fixture components can be defined for the Fixture De-Embedding
setup. Returns a list of the requested fixture names.
So, if 3 fixtures exist (a,b, and c), it returns "FCOMD" and "FCOME'.
Up to 16 fixtures can exist with the last one identified with the letter "P". If there are not enough available fixtures and empty list is returned.
The create_deembed_fixture()
function creates a new fixture component.
The 5th character in the fixture argument (index number 4) identifies
the new fixture. For example, "E" in "FCOME". Letters can range from
"A" to "P". The filename argument is the s2p file.
The create_TDR_setup()
function, creates a new TDR DUT setup (2-port SE) using the dut argument. The
dut argument is a string. For example, "DUT4".
Algorithm
- Connects to FlexDCA.
- Changes to TDR/TDT mode. Assumes that an TDR module is installed in slot 1.
- Determine if a DUT definition is available in TDR Setup. A maximum of 16 DUTs defined.
- Determine if two fixture de-embedding component definitions are available in TDR De-Embedding Setup. A maximum of 16 fixture components defined.
- Creates two fixture components if available otherwise aborts program. The fixture components are created from an s2p S-parameter file that is located in the FlexDCA's Demo folder.
- Creates a new single-ended DUT setup with fixture deembeding.
- Turns on the channel 1A step. Turns on channel 1B. Turns off channels 1C and 1D.
- Save an instrument state. For example, DUT3.setx. This ensures that the DUT setup and fixture de-embedding compontents are saved.
- Closes the FlexDCA session.
Example Script
tdr-dut-setup.py
# -*- coding: utf-8 -*-
""" In TDR mode, creates a 2-port single-ended DUT and creates a fixture
deembedding setup with two fixture components.
Finds if capacity exists to add a new TDR DUT setup. There
can be up to 16. If available, creates a 2-port single-ended
DUT in TDR setup.
Finds if capacity exists to add 2 fixture deembedding
components. There can be up to 16. If available, creates
components from s2p file in DEMO folder.
Creates DUT setup with fixture deembedded fixtures connected.
Requires N1055A or 54754A TDR module. """
import pyvisa as visa # import VISA library
ADDRESS = 'TCPIP0::K-N1000A-00003::hislip0,4880::INSTR' # DCA-X
CHA = '2A' # TDR module channel
CHB = '2B' # TDR module channel
SPARAMETER_FILE = '"%DEMO_DIR%\\S-Parameter Data\Demo\\TDRDemoBoard_ET55780\
\\ET55780_Impedance_Profile.s2p"'
def open_flexdca_connection(address):
""" Opens visa connection to FlexFlexDCA. """
print('Connecting to Flexdca ...')
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)
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 find_available_dut():
""" Up to 16 DUTs can be defined. Determines the next available DUT
number and returns that DUT. So, if 3 DUTs exist, it returns "DUT4".
"""
global FlexDCA
for number in range(1, 17):
dut = 'DUT' + str(number)
if FlexDCA.query(':TDR:' + dut + ':ENABle?') == '1':
if number == 16: # all potential DUTs exist
return ''
continue
else:
return dut # found available DUT
def find_available_fixtures(*args):
""" Up to 16 fixture components can be defined for the Fixture
De-Embedding setup. Returns the number of requested fixture
names and returns the names. For example, if 3 fixtures
exist (a,b, and c), it might return "FCOMD" and "FCOME'.
If there are not enough available fixtures and empty tupple is returned.
"""
global FlexDCA
letters = 'ABCDEFGHIJKLMNOP'
fixture_count = len(args) # args is tupple of requestd fixtures
fixture = ''
available = []
fixture_list = []
for i in range(0, 16): # find available fixtures
fixture = 'FCOM' + letters[i]
if FlexDCA.query(':TDR:DEEMbed:' + fixture + ':STATus?') == 'INV':
available.append(fixture) # make a list of available fixtures
if len(available) < fixture_count:
fixture_list = ['' for item in range(0, fixture_count)]
return fixture_list # Fixtures not available, return empty list.
i = 0
while i < fixture_count:
fixture_list.append(available[i])
i += 1
return fixture_list
def create_deembed_fixture(fixture, filename):
""" Creates a new fixture component.
The 5th character in the fixture argument (index number 4) identifies
the new fixture. For example, "E" in "FCOME". Letters can range from
"A" to "P". The filename argument is the s2p file.
"""
global FlexDCA
FlexDCA.write(':TDR:DEEMbed:' + fixture + ':LOAD:FNAMe ' + filename)
FlexDCA.write(':TDR:DEEMbed:' + fixture + ':LOAD')
print('Created fixture: ' + fixture[4])
def create_TDR_setup(dut, fixture1, fixture2):
""" Creates a new TDR DUT setup (2-port SE) using the dut argument. The
dut argument is a string. For example, "DUT4".
"""
global FlexDCA
FlexDCA.write(':TDR:AMODe SENDed') # single-ended DUT
FlexDCA.write(':TDR:' + dut + ':ENABle ON')
FlexDCA.write(':TDR:' + dut + ':DTYPe SEPorts2')
print('Created ' + dut)
FlexDCA.write(':TDR:CHANnel' + CHA + ':DUT ' + dut)
FlexDCA.write(':TDR:CHANnel' + CHA + ':PORT PORT1')
FlexDCA.write(':TDR:STIMulus:CHANnel' + CHA + ':STEP ON')
FlexDCA.write(':TDR:CHANnel' + CHB + ':DUT ' + dut)
FlexDCA.write(':TDR:CHANnel' + CHB + ':PORT PORT2')
FlexDCA.write(':TDR:DEEMbed:' + dut + ':PORT1:FIXTure ' + fixture1)
FlexDCA.write(':TDR:DEEMbed:' + dut + ':PORT1:TPORt PORT1')
FlexDCA.write(':TDR:DEEMbed:' + dut + ':PORT1:DPORt PORT2')
FlexDCA.write(':TDR:DEEMbed:' + dut + ':PORT2:FIXTure ' + fixture2)
FlexDCA.write(':TDR:DEEMbed:' + dut + ':PORT2:TPORt PORT2')
FlexDCA.write(':TDR:DEEMbed:' + dut + ':PORT2:DPORt PORT1')
FlexDCA.write(':TDR:STIMulus:CHANnel' + CHA + ':STEP ON')
print('Created TDR setup with deembedding.', flush=True)
def save_instrument_state(dut):
""" Save DUT and fixture deembeding settings in instrument state file. """
global FlexDCA
print('Saving the instrument state....')
FlexDCA.write(':DISK:SETup:SAVe "%USER_DATA_DIR%\\Setups\\' +
dut + '.setx"')
FlexDCA = open_flexdca_connection(ADDRESS)
FlexDCA.query(':SYSTem:MODE TDR;*OPC?')
dut = find_available_dut()
fixture1 = ''
fixture2 = ''
fixture1, fixture2 = find_available_fixtures(fixture1, fixture2)
if not (fixture1 and fixture2):
print('\nERROR: fixtures not available.')
elif not dut:
print('\nERROR: DUT not available.')
else:
create_deembed_fixture(fixture1, SPARAMETER_FILE)
create_deembed_fixture(fixture2, SPARAMETER_FILE)
create_TDR_setup(dut, fixture1, fixture2)
save_instrument_state(dut)
print('Program has successfully completed.')
FlexDCA.write(':SYSTem:GTLocal')
FlexDCA.close()