automated python test frameworks for hardware verification and validation

21
Automated Python Test Frameworks for Hardware Validation and Verification Barbara Jones

Upload: barbara-jones

Post on 25-May-2015

3.752 views

Category:

Documents


0 download

DESCRIPTION

Codemash 2012

TRANSCRIPT

Page 1: Automated Python Test Frameworks for Hardware Verification and Validation

Automated Python Test Frameworks for Hardware Validation and Verification

Barbara Jones

Page 2: Automated Python Test Frameworks for Hardware Verification and Validation

About Me

Barbara [email protected]

Test & Measurement Data Acquisition

Page 3: Automated Python Test Frameworks for Hardware Verification and Validation

Boeing 787 Fatigue Test

Rack of instruments to measure strain

Page 4: Automated Python Test Frameworks for Hardware Verification and Validation

Definitions & Theory Strain gauge Thermocouple Channel Sample rate Waveform Waveform generator

Page 5: Automated Python Test Frameworks for Hardware Verification and Validation

Why test hardware?

VerificationValidation

Page 6: Automated Python Test Frameworks for Hardware Verification and Validation

Software Techniques Don’t Help

Unit TestsMockingTDD

Page 7: Automated Python Test Frameworks for Hardware Verification and Validation

What does help?

Spec-based testingTest stand automationA good test framework

Page 8: Automated Python Test Frameworks for Hardware Verification and Validation

Bed-of-nails tester

Engineeringtest rig

Page 9: Automated Python Test Frameworks for Hardware Verification and Validation
Page 10: Automated Python Test Frameworks for Hardware Verification and Validation

Test Framework Requirements Easily design

broad tests from spec

Control external equipment

Easy math handling

def module_test_1(suite, cl, slave_cls): def verify(result, success, args): if not success: return False if result[-1] != args: return False return True arg1 = 0.1 arg2 = 0.2 calls = [Call(cl.InstrumentSpecific.ThisIsAMethod, arg1, arg2), Set(cl.InstrumentSpecific, "ThisIsAProperty", arg1), Get(cl.InstrumentSpecific, "ThisIsAProperty")] suite.add(calls, verify, arg1) def add(suite, cl, slave_cls): module_test_1(suite, cl, slave_cls)

Page 11: Automated Python Test Frameworks for Hardware Verification and Validation

Designing tests based on hardware specsPhase alignment on multiple instruments must

be within 0.000010 arc seconds

𝑋𝑘=∑𝑛=0

𝑁− 1

𝑥𝑛𝑒−2𝜋 𝑘

𝑁𝑛

𝐴𝑘=|𝑋𝑘|=√ℜ ( 𝑋𝑘)2+ℑ (𝑋𝑘 )2

Discrete Fourier Transform

Amplitude

Phase

𝜙𝑘=atan 2( ℑ (𝑋𝑘 ) ,ℜ (𝑋𝑘 ) )

Page 12: Automated Python Test Frameworks for Hardware Verification and Validation

Phase Alignment

Aligned

Out of Phase

Page 13: Automated Python Test Frameworks for Hardware Verification and Validation

Controlling external equipment

Agilent 33220A Waveform Generator

Specifications IEEE 488.2 (1975) SCPI (1990) VXI-11 (1995)

Page 14: Automated Python Test Frameworks for Hardware Verification and Validation

from vxi11client import * class ag33120(TCPVXI11Client): timeout = 10000 def __init__(self, hostname, gpib): TCPVXI11Client.__init__(self, hostname, 1, gpib) def query(self, str): self.device_write(self.lid, self.timeout, self.timeout, 0, str) return self.device_read(self.lid, 256, self.timeout, self.timeout, 0x80, 0x0a) def check_error(self): res = self.query(":SYST:ERR?\n") err, msg = res.data.split(",") if int(err) != 0: raise Exception(res.data) def reset(self): self.device_write(self.lid, self.timeout, self.timeout, 0, "*RST;\n") def apply(self, func, freq=None, amp=None, off=None): freq = self._defopt(freq) amp = self._defopt(amp) off = self._defopt(off) return self.query("APPLY:%s %s, %s, %s; *OPC?\n" % (func, freq, amp, off)) def _defopt(self, arg): if arg == None: return "DEF" return "%12.7e" % arg

Controlling external equipment

Page 15: Automated Python Test Frameworks for Hardware Verification and Validation

def dc(self, off=None): return self.query("APPLY:DC 1, 1, %s; *OPC?\n" % (off)) def set_highimpedance_mode(self): return self.query("OUTP:LOAD 9.9E37; *OPC?\n") def sine(self, freq=None, amp=None, off=None): return self.apply("SIN", freq, amp, off) def square(self, freq=None, amp=None, off=None): return self.apply("SQU", freq, amp, off) def triangle(self, freq=None, amp=None, off=None): return self.apply("TRI", freq, amp, off) def ramp(self, freq=None, amp=None, off=None): return self.apply("RAMP", freq, amp, off)

Controlling external equipment

Page 16: Automated Python Test Frameworks for Hardware Verification and Validation

Phase Alignment Test

# Data acquisition characteristics: FILTER_TYPE = ex1629constants.IIRFILTER_TYPE_NONE SAMP_FREQ = 1000.0 SAMPLE_COUNT = 1000 # Expected input: 1V peak (2V peak-to-peak) sine wave at 10Hz. INPUT_AMPLITUDE = 1 INPUT_FREQ = 10 # Maximum tolerated skew (in seconds): MAX_PERMISSIBLE_SKEW = 0.000010 def add_phase_test(suite, cl, slave_cls, wavegen) def add(suite, cl, slave_cls): wavegen = require_slaves(slave_cls, "ag33120") slaves = require_slaves(slave_cls, "ex1629") add_phase_test(suite, cl, slaves, wavegen)

Page 17: Automated Python Test Frameworks for Hardware Verification and Validation

def add_phase_test(suite, cl, slave_cls, wavegen): # Constant parameters PI = 4*atan(1) if suite.test_level == test.FULL_TEST: NUM_INNER_LOOPS = 2000 # approximately 13 hours with two devices else: NUM_INNER_LOOPS = 10 # approximately 4 minutes with 2 devices def verify(result, success, args): # Since the actual data analysis was performed in analyze_data, # we only need to check the function call returns to determine # overall success/failure. for call_result in result: if call_result == False: return False return success # set up the waveform generator # Sine wave at 10Hz, 1V peak (2V peak-to-peak), no offset calls = [Call(wavegen.reset), Call(wavegen.set_highimpedance_mode), Call(wavegen.sine(INPUT_FREQ, INPUT_AMPLITUDE, 0)] suite.add(calls) for config_name in config_sequence

Setup & Verify

Page 18: Automated Python Test Frameworks for Hardware Verification and Validation

for config_name in config_sequence: calls = [] # Configure the master & slave devices calls += configure_device(cl) calls += configure_device_trigger(cl, configs[config_name]['master']) for slave_cl in slave_cls: calls += configure_device(slave_cl) calls += configure_device_trigger(slave_cl, configs[config_name]['slave']) suite.add(calls, verify, None) for inner_loop in range(0, NUM_INNER_LOOPS): calls = [] # Instruct the master device to issue a sync pulse calls += [Call(cl.soft_sync)] # Start acquiring data on each slave device for slave_cl in slave_cls: calls += [Call(slave_cl.trig_init)] # Start acquiring data on the master device calls += [Call(cl.trig_init)] # Issue a soft trigger command to the master device calls += [Call(cl.soft_trig)] # Read the data calls += [Call(analyze_data, cl, slave_cls, config_name)] suite.add(calls, verify, None) # Reset the slave devices & the master device calls = [] for slave_cl in slave_cls: calls += [Call(slave_cl.reset)] calls += [Call(cl.reset)] suite.add(calls, verify, None)

Test Sequence

Page 19: Automated Python Test Frameworks for Hardware Verification and Validation

N = len(device_result.datapages) n = INPUT_FREQ * N / SAMP_FREQ val_dft_real = val_dft_imag = 0.0 k = 0 for page in device_result.datapages: val_dft_real += page.dataset[board][0].data[0] * cos(2*PI*n*k/N) val_dft_imag -= page.dataset[board][0].data[0] * sin(2*PI*n*k/N) k += 1 val_magnitude = sqrt(pow(val_dft_imag, 2) + pow(val_dft_real, 2))/N val_phase = atan2(val_dft_imag , val_dft_real)

DFT Calculation

Page 20: Automated Python Test Frameworks for Hardware Verification and Validation

Phase Alignment Test Data

Page 21: Automated Python Test Frameworks for Hardware Verification and Validation

Questions?