def test_bool_max_num_expr():
    """Test for the BooleanGenerator class.

    This test will implement a maximum number of boolean generators, 
    each having 1 input. For example, PYNQ-Z1 has 20 pins for Arduino header, 
    so 19 boolean generators will be implemented, each having 1 output 
    assigned to 1 pin. All the generators share the same input pin.

    """
    ol.download()
    pin_dict = PYNQZ1_LOGICTOOLS_SPECIFICATION['traceable_outputs']
    interface_width = PYNQZ1_LOGICTOOLS_SPECIFICATION['interface_width']
    all_pins = [k for k in list(pin_dict.keys())[:interface_width]]
    num_expressions = interface_width - 1
    in_pin = all_pins[0]
    out_pins = all_pins[1:]
    test_expressions = list()
    for i in range(num_expressions):
        test_expressions.append(out_pins[i] + '=' + in_pin)

    print("")
    bool_generator = BooleanGenerator(mb_info)
    for voltage in ['VCC', 'GND']:
        print('Disconnect all the pins. Connect only {} to {}.'.format(
            in_pin, voltage))
        input('Press enter when done ...')

        bool_generator.trace()
        bool_generator.setup(expressions=test_expressions)
        bool_generator.run()

        for expr_label in bool_generator.expressions.keys():
            waveform = bool_generator.waveforms[expr_label]
            wavelanes_in = waveform.waveform_dict['signal'][0][1:]
            wavelanes_out = waveform.waveform_dict['signal'][-1][1:]
            expr = deepcopy(bool_generator.expressions[expr_label])

            wavelane = wavelanes_in[0]
            wavelane_bitstring = wave_to_bitstring(wavelane['wave'])
            str_replace = wavelane_bitstring[0]
            expr = re.sub(r"\b{}\b".format(wavelane['name']),
                          str_replace, expr)

            wavelane = wavelanes_out[0]
            wavelane_bitstring = wave_to_bitstring(wavelane['wave'])
            str_replace = wavelane_bitstring[0]
            expr = re.sub(r"\b{}\b".format(wavelane['name']),
                          str_replace, expr)

            expr = expr.replace('=', '==')
            assert eval(expr), "Boolean expression {} not evaluating " \
                               "correctly.".format(
                bool_generator.expressions[expr_label])

        bool_generator.stop()
        bool_generator.reset()

    del bool_generator
def test_fsm_state_bits():
    """Test for the Finite State Machine Generator class.

    This test is similar to the first test, but in this test,
    we will test the case when the state bits are also used as outputs.

    """
    ol.download()

    rst, direction = list(pin_dict.keys())[1:3]
    print("\nConnect both {} and {} to GND.".format(rst, direction))
    input("Hit enter after done ...")

    fsm_spec_4_state, output_pattern, \
        state_bit0_pattern, state_bit1_pattern = build_fsm_spec_4_state(0)
    fsm_period = len(fsm_spec_4_state['states'])
    golden_test_array = np.array(output_pattern)
    golden_state_bit0_array = np.array(state_bit0_pattern)
    golden_state_bit1_array = np.array(state_bit1_pattern)

    for fsm_frequency_mhz in [10, 100]:
        fsm_generator = FSMGenerator(mb_info)
        fsm_generator.trace(use_analyzer=True, num_analyzer_samples=fsm_period)
        fsm_generator.setup(fsm_spec_4_state,
                            use_state_bits=True,
                            frequency_mhz=fsm_frequency_mhz)
        fsm_generator.run()

        test_string = state_bit0_string = state_bit1_string = ''
        for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
            if wavegroup and wavegroup[0] == 'analysis':
                for wavelane in wavegroup[1:]:
                    if wavelane['name'] == 'test':
                        test_string = wavelane['wave']
                    if wavelane['name'] == 'state_bit0':
                        state_bit0_string = wavelane['wave']
                    if wavelane['name'] == 'state_bit1':
                        state_bit1_string = wavelane['wave']
        test_array = np.array(bitstring_to_int(wave_to_bitstring(test_string)))
        state_bit0_array = np.array(
            bitstring_to_int(wave_to_bitstring(state_bit0_string)))
        state_bit1_array = np.array(
            bitstring_to_int(wave_to_bitstring(state_bit1_string)))

        assert np.array_equal(golden_test_array, test_array), \
            'Data pattern not correct when running at {}MHz.'.format(
                    fsm_frequency_mhz)
        assert np.array_equal(golden_state_bit0_array, state_bit0_array), \
            'State bit0 not correct when running at {}MHz.'.format(
                    fsm_frequency_mhz)
        assert np.array_equal(golden_state_bit1_array, state_bit1_array), \
            'State bit1 not correct when running at {}MHz.'.format(
                    fsm_frequency_mhz)

        fsm_generator.stop()
        fsm_generator.reset()
        del fsm_generator
def test_bool_step():
    """Test for the BooleanGenerator class.

    This test will test whether the `step()` method works correctly.
    Users will be asked to change input values during the test. The test
    scenario is also an extreme case where only 2 samples are captured.

    """
    ol.download()
    pin_dict = PYNQZ1_LOGICTOOLS_SPECIFICATION['traceable_outputs']
    first_10_pins = [k for k in list(pin_dict.keys())[:10]]
    in_pins = first_10_pins[0:5]
    out_pins = first_10_pins[5:10]
    test_expressions = list()
    operations = ['&', '|', '^']
    for i in range(5):
        operation = choice(operations)
        test_expressions.append(out_pins[i] + '=' +
                                (operation.join(sample(in_pins, i+1))))

    print('\nConnect randomly {} to VCC or GND.'.format(in_pins))
    input('Hit enter after done ...')

    bool_generator = BooleanGenerator(mb_info)
    bool_generator.trace(num_analyzer_samples=2)
    bool_generator.setup(expressions=test_expressions)

    for i in range(2):
        print('Change some of the connections from {}.'.format(in_pins))
        input('Hit enter after done ...')
        bool_generator.step()

        for expr_label in bool_generator.expressions.keys():
            waveform = bool_generator.waveforms[expr_label]
            wavelanes_in = waveform.waveform_dict['signal'][0][1:]
            wavelanes_out = waveform.waveform_dict['signal'][-1][1:]
            expr = deepcopy(bool_generator.expressions[expr_label])
            for wavelane in wavelanes_in:
                wavelane_bitstring = wave_to_bitstring(wavelane['wave'])
                str_replace = wavelane_bitstring[i]
                expr = re.sub(r"\b{}\b".format(wavelane['name']),
                              str_replace, expr)

            wavelane = wavelanes_out[0]
            wavelane_bitstring = wave_to_bitstring(wavelane['wave'])
            str_replace = wavelane_bitstring[i]
            expr = re.sub(r"\b{}\b".format(wavelane['name']),
                          str_replace, expr)
            expr = expr.replace('=', '==')
            assert eval(expr), "Boolean expression {} not evaluating " \
                               "correctly in step {}.".format(
                bool_generator.expressions[expr_label], i)

    bool_generator.stop()
    bool_generator.reset()
    del bool_generator
예제 #4
0
def test_pattern_step():
    """Test for the PatternGenerator class.

    This test will examine a moderate number of 128 samples (in order
    to shorten testing time). For theses cases, random signals will be used, 
    and all the pins will be used to build the pattern. Each sample is 
    captured after advancing the `step()`.

    """
    ol.download()
    num_samples = 128
    loopback_sent = build_random_pattern(num_samples)
    pattern_generator = PatternGenerator(mb_info)
    pattern_generator.trace(use_analyzer=True,
                            num_analyzer_samples=num_samples)
    pattern_generator.setup(loopback_sent,
                            stimulus_group_name='stimulus',
                            analysis_group_name='analysis',
                            frequency_mhz=100)

    for _ in range(num_samples):
        pattern_generator.step()

    loopback_recv = pattern_generator.waveform.waveform_dict
    list1 = list2 = list3 = list()
    for wavelane_group in loopback_sent['signal']:
        if wavelane_group and wavelane_group[0] == 'stimulus':
            for i in wavelane_group[1:]:
                temp = deepcopy(i)
                temp['wave'] = wave_to_bitstring(i['wave'])
                list1.append(temp)

    for wavelane_group in loopback_recv['signal']:
        if wavelane_group and wavelane_group[0] == 'stimulus':
            for i in wavelane_group[1:]:
                temp = deepcopy(i)
                temp['wave'] = wave_to_bitstring(i['wave'])
                list2.append(temp)
        elif wavelane_group and wavelane_group[0] == 'analysis':
            for i in wavelane_group[1:]:
                temp = deepcopy(i)
                temp['wave'] = wave_to_bitstring(i['wave'])
                list3.append(temp)
    assert list1 == list2, \
        'Stimulus not equal in generated and captured patterns.'
    assert list2 == list3, \
        'Stimulus not equal to analysis in captured patterns.'

    pattern_generator.stop()
    pattern_generator.reset()
    del pattern_generator
예제 #5
0
def test_pattern_random():
    """Test for the PatternGenerator class.

    This test will examine 1 sample, and a maximum number of samples.
    For theses cases, random signals will be used, and all the 
    pins will be used to build the pattern.

    """
    ol.download()
    for num_samples in [1, MAX_NUM_PATTERN_SAMPLES]:
        loopback_sent = build_random_pattern(num_samples)
        pattern_generator = PatternGenerator(mb_info)
        pattern_generator.trace(use_analyzer=True,
                                num_analyzer_samples=num_samples)
        pattern_generator.setup(loopback_sent,
                                stimulus_group_name='stimulus',
                                analysis_group_name='analysis',
                                frequency_mhz=100)
        pattern_generator.run()

        loopback_recv = pattern_generator.waveform.waveform_dict
        list1 = list2 = list3 = list()
        for wavelane_group in loopback_sent['signal']:
            if wavelane_group and wavelane_group[0] == 'stimulus':
                for i in wavelane_group[1:]:
                    temp = deepcopy(i)
                    temp['wave'] = wave_to_bitstring(i['wave'])
                    list1.append(temp)

        for wavelane_group in loopback_recv['signal']:
            if wavelane_group and wavelane_group[0] == 'stimulus':
                for i in wavelane_group[1:]:
                    temp = deepcopy(i)
                    temp['wave'] = wave_to_bitstring(i['wave'])
                    list2.append(temp)
            elif wavelane_group and wavelane_group[0] == 'analysis':
                for i in wavelane_group[1:]:
                    temp = deepcopy(i)
                    temp['wave'] = wave_to_bitstring(i['wave'])
                    list3.append(temp)
        assert list1 == list2, \
            'Stimulus not equal in generated and captured patterns.'
        assert list2 == list3, \
            'Stimulus not equal to analysis in captured patterns.'

        pattern_generator.stop()
        pattern_generator.reset()
        del pattern_generator
def test_fsm_num_samples():
    """Test for the Finite State Machine Generator class.

    In this test, the pattern generated by the FSM will be compared with the 
    one specified. We will test a minimum number of (FSM period + 1) samples,
    and a maximum number of samples. 10MHz and 100MHz clocks are tested
    for each case.

    """
    ol.download()

    rst, direction = list(pin_dict.keys())[1:3]
    print("\nConnect {} to GND, and {} to VCC.".format(rst, direction))
    input("Hit enter after done ...")

    fsm_spec_4_state, output_pattern, _, _ = build_fsm_spec_4_state(1)
    fsm_period = len(fsm_spec_4_state['states'])
    for num_samples in [fsm_period, MAX_NUM_TRACE_SAMPLES]:
        test_tile = np.array(output_pattern)
        golden_test_array = np.tile(test_tile, ceil(num_samples / 4))

        for fsm_frequency_mhz in [10, 100]:
            fsm_generator = FSMGenerator(mb_info)
            assert fsm_generator.status == 'RESET'

            fsm_generator.trace(use_analyzer=True,
                                num_analyzer_samples=num_samples)
            fsm_generator.setup(fsm_spec_4_state,
                                frequency_mhz=fsm_frequency_mhz)
            assert fsm_generator.status == 'READY'
            assert 'bram_data_buf' not in \
                   fsm_generator.logictools_controller.buffers, \
                'bram_data_buf is not freed after use.'

            fsm_generator.run()
            assert fsm_generator.status == 'RUNNING'

            test_string = ''
            for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
                if wavegroup and wavegroup[0] == 'analysis':
                    for wavelane in wavegroup[1:]:
                        if wavelane['name'] == 'test':
                            test_string = wavelane['wave']
            test_array = np.array(
                bitstring_to_int(wave_to_bitstring(test_string)))

            assert np.array_equal(test_array,
                                  golden_test_array[:num_samples]), \
                'Data pattern not correct when running at {}MHz.'.format(
                    fsm_frequency_mhz)

            fsm_generator.stop()
            assert fsm_generator.status == 'READY'

            fsm_generator.reset()
            assert fsm_generator.status == 'RESET'

            del fsm_generator
def build_fsm_spec_max_in_out():
    """Build an FSM spec using a maximum number of inputs and outputs.

    The returned FSM spec has a maximum number of inputs and 
    outputs. At the same time, the largest available number of 
    states will be implemented. For example, on PYNQ-Z1, if 
    FSM_MAX_INPUT_BITS = 8, and FSM_MAX_STATE_INPUT_BITS = 13, we will 
    implement 2**(13-8)-1 = 31 states. This is the largest number of states 
    available for this setup, since there is always 1 dummy state that has
    to be reserved.

    Returns
    -------
    dict
        The FSM spec that can be consumed by the FSM generator.
    list
        The output patterns associated with this FSM spec.

    """
    input_pins = list(pin_dict.keys())[:FSM_MAX_INPUT_BITS]
    output_pins = list(pin_dict.keys())[FSM_MAX_INPUT_BITS:interface_width]
    fsm_spec_inout = {
        'inputs': [],
        'outputs': [],
        'states': [],
        'transitions': [['1' * len(input_pins), '*', 'S0', '']]
    }
    test_lanes = [[] for _ in range(len(output_pins))]
    num_states = 2**(FSM_MAX_STATE_INPUT_BITS - FSM_MAX_INPUT_BITS) - 1
    for i in range(len(input_pins)):
        fsm_spec_inout['inputs'].append(('input{}'.format(i), input_pins[i]))
    for i in range(len(output_pins)):
        fsm_spec_inout['outputs'].append(
            ('output{}'.format(i), output_pins[i]))
    for i in range(num_states):
        current_state = 'S{}'.format(i)
        next_state = 'S{}'.format((i + 1) % num_states)
        fsm_spec_inout['states'].append(current_state)
        output_pattern = ''
        for test_lane in test_lanes:
            random_1bit = '{}'.format(randint(0, 1))
            output_pattern += random_1bit
            test_lane += random_1bit
        transition = [
            '0' * len(input_pins), current_state, next_state, output_pattern
        ]
        fsm_spec_inout['transitions'].append(transition)

    test_patterns = []
    for i in range(len(output_pins)):
        temp_string = ''.join(test_lanes[i])
        test_patterns.append(
            np.array(bitstring_to_int(wave_to_bitstring(temp_string))))
    return fsm_spec_inout, test_patterns
def test_fsm_max_in_out():
    """Test for the Finite State Machine Generator class.

    This test will test when maximum number of inputs and 
    outputs are used. At the same time, the largest available number of 
    states will be implemented.

    """
    ol.download()

    input_pins = list(pin_dict.keys())[:FSM_MAX_INPUT_BITS]
    print("\nConnect {} to GND.".format(input_pins))
    print("Disconnect all other pins.")
    input("Hit enter after done ...")

    fsm_spec_inout, test_patterns = build_fsm_spec_max_in_out()
    period = 2**(FSM_MAX_STATE_INPUT_BITS - FSM_MAX_INPUT_BITS) - 1
    num_output_pins = interface_width - FSM_MAX_INPUT_BITS

    fsm_generator = FSMGenerator(mb_info)
    fsm_generator.trace(use_analyzer=True,
                        num_analyzer_samples=MAX_NUM_TRACE_SAMPLES)
    fsm_generator.setup(fsm_spec_inout, frequency_mhz=100)
    fsm_generator.run()

    test_strings = ['' for _ in range(num_output_pins)]
    test_arrays = [[] for _ in range(num_output_pins)]
    for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
        if wavegroup and wavegroup[0] == 'analysis':
            for wavelane in wavegroup[1:]:
                for j in range(num_output_pins):
                    if wavelane['name'] == 'output{}'.format(j):
                        test_strings[j] = wavelane['wave']
                        test_arrays[j] = np.array(
                            bitstring_to_int(wave_to_bitstring(
                                test_strings[j])))
                        break

    golden_arrays = [[] for _ in range(num_output_pins)]
    for i in range(num_output_pins):
        golden_arrays[i] = np.tile(test_patterns[i],
                                   ceil(MAX_NUM_TRACE_SAMPLES / period))
        assert np.array_equal(test_arrays[i],
                              golden_arrays[i][:MAX_NUM_TRACE_SAMPLES]), \
            'Output{} not matching the generated pattern.'.format(i)

    fsm_generator.stop()
    fsm_generator.reset()
    del fsm_generator
def build_fsm_spec_free_run():
    """Build a spec that results in a free-running FSM.

    This will return an FSM spec with no given inputs.
    In this case, the FSM is a free running state machine. 
    A maximum number of states are deployed.

    Returns
    -------
    dict
        The FSM spec that can be consumed by the FSM generator.
    list
        The output patterns associated with this FSM spec.

    """
    input_pin = list(pin_dict.keys())[0]
    output_pins = list(pin_dict.keys())[1:interface_width]

    fsm_spec_inout = {
        'inputs': [],
        'outputs': [],
        'states': [],
        'transitions': []
    }
    test_lanes = [[] for _ in range(len(output_pins))]
    num_states = FSM_MAX_NUM_STATES
    fsm_spec_inout['inputs'].append(('input0', input_pin))
    for i in range(len(output_pins)):
        fsm_spec_inout['outputs'].append(
            ('output{}'.format(i), output_pins[i]))
    for i in range(num_states):
        current_state = 'S{}'.format(i)
        next_state = 'S{}'.format((i + 1) % num_states)
        fsm_spec_inout['states'].append(current_state)
        output_pattern = ''
        for test_lane in test_lanes:
            random_1bit = '{}'.format(randint(0, 1))
            output_pattern += random_1bit
            test_lane += random_1bit
        transition = ['-', current_state, next_state, output_pattern]
        fsm_spec_inout['transitions'].append(transition)

    test_patterns = []
    for i in range(len(output_pins)):
        temp_string = ''.join(test_lanes[i])
        test_patterns.append(
            np.array(bitstring_to_int(wave_to_bitstring(temp_string))))
    return fsm_spec_inout, test_patterns
def test_fsm_free_run():
    """Test for the Finite State Machine Generator class.

    This will examine a special scenario where no inputs are given.
    In this case, the FSM is a free running state machine. Since the FSM 
    specification requires at least 1 input pin to be specified,  1 pin can 
    be used as `don't care` input, while all the other pins are used as 
    outputs. A maximum number of states are deployed.

    """
    ol.download()

    print("\nDisconnect all the pins.")
    input("Hit enter after done ...")

    fsm_spec_inout, test_patterns = build_fsm_spec_free_run()
    period = FSM_MAX_NUM_STATES
    num_output_pins = interface_width - 1
    fsm_generator = FSMGenerator(mb_info)
    fsm_generator.trace(use_analyzer=True, num_analyzer_samples=period)
    fsm_generator.setup(fsm_spec_inout, frequency_mhz=100)
    fsm_generator.run()

    test_strings = ['' for _ in range(num_output_pins)]
    test_arrays = [[] for _ in range(num_output_pins)]
    for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
        if wavegroup and wavegroup[0] == 'analysis':
            for wavelane in wavegroup[1:]:
                for j in range(num_output_pins):
                    if wavelane['name'] == 'output{}'.format(j):
                        test_strings[j] = wavelane['wave']
                        test_arrays[j] = np.array(
                            bitstring_to_int(wave_to_bitstring(
                                test_strings[j])))
                        break

    golden_arrays = test_patterns
    for i in range(num_output_pins):
        assert np.array_equal(test_arrays[i], golden_arrays[i]), \
            'Output{} not matching the generated pattern.'.format(i)

    fsm_generator.stop()
    fsm_generator.reset()
    del fsm_generator
def test_fsm_num_states2():
    """Test for the Finite State Machine Generator class.

    This test will check 2 and MAX_NUM_STATES states. 
    These cases should be able to pass random tests. 
    For these tests, we use the minimum number of input and output pins.

    """
    ol.download()

    input_pin = list(pin_dict.keys())[0]
    print("\nConnect {} to GND, and disconnect other pins.".format(input_pin))
    input("Hit enter after done ...")

    for num_states in [2, FSM_MAX_NUM_STATES]:
        fsm_spec, test_pattern = build_fsm_spec_random(num_states)

        fsm_generator = FSMGenerator(mb_info)
        fsm_generator.trace(use_analyzer=True,
                            num_analyzer_samples=MAX_NUM_TRACE_SAMPLES)
        fsm_generator.setup(fsm_spec, frequency_mhz=100)
        fsm_generator.run()

        test_string = ''
        for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
            if wavegroup and wavegroup[0] == 'analysis':
                for wavelane in wavegroup[1:]:
                    if wavelane['name'] == 'test':
                        test_string = wavelane['wave']
        test_array = np.array(bitstring_to_int(wave_to_bitstring(test_string)))

        period = num_states
        test_tile = np.array(test_pattern)

        golden_test_array = np.tile(test_tile,
                                    ceil(MAX_NUM_TRACE_SAMPLES / period))
        assert np.array_equal(test_array,
                              golden_test_array[:MAX_NUM_TRACE_SAMPLES]), \
            'Analysis not matching the generated pattern.'

        fsm_generator.stop()
        fsm_generator.reset()
        del fsm_generator
예제 #12
0
def check_fsm_data(fsm_generator, num_samples):
    """Check whether the FSM generator returns correct data pattern.

    Parameters
    ----------
    fsm_generator : FSMGenerator
        The FSM generator after a successful run.
    num_samples : int
        The number of samples to test.

    """
    test_string = ''
    for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
        if wavegroup and wavegroup[0] == 'analysis':
            for wavelane in wavegroup[1:]:
                if wavelane['name'] == 'test':
                    test_string = wavelane['wave']
    test_array = np.array(bitstring_to_int(wave_to_bitstring(test_string)))

    golden_test_array = np.tile(np.array(output_pattern),
                                ceil(num_samples / 4))
    assert np.array_equal(test_array,
                          golden_test_array[:num_samples]), \
        'Analysis not matching the generated pattern in FSM.'
def test_fsm_step():
    """Test for the Finite State Machine Generator class.

    This test is similar to the above test, but in this test,
    we will test the `step()` method, and ask users to change the input
    logic values in the middle of the test.

    """
    ol.download()

    rst, direction = list(pin_dict.keys())[1:3]
    print("")

    fsm_spec_4_state, output_pattern_up, \
        state_bit0_pattern_up, \
        state_bit1_pattern_up = build_fsm_spec_4_state(0)
    _, output_pattern_down, \
        state_bit0_pattern_down, \
        state_bit1_pattern_down = build_fsm_spec_4_state(1)
    output_pattern_down.append(output_pattern_down.pop(0))
    state_bit0_pattern_down.append(state_bit0_pattern_down.pop(0))
    state_bit1_pattern_down.append(state_bit1_pattern_down.pop(0))
    fsm_period = len(fsm_spec_4_state['states'])
    golden_test_array = np.array(output_pattern_up + output_pattern_down[1:])
    golden_state_bit0_array = np.array(state_bit0_pattern_up +
                                       state_bit0_pattern_down[1:])
    golden_state_bit1_array = np.array(state_bit1_pattern_up +
                                       state_bit1_pattern_down[1:])

    for fsm_frequency_mhz in [10, 100]:
        fsm_generator = FSMGenerator(mb_info)
        fsm_generator.trace(use_analyzer=True, num_analyzer_samples=fsm_period)
        fsm_generator.setup(fsm_spec_4_state,
                            use_state_bits=True,
                            frequency_mhz=fsm_frequency_mhz)
        print("Connect both {} and {} to GND.".format(rst, direction))
        input("Hit enter after done ...")
        for _ in range(len(output_pattern_up) - 1):
            fsm_generator.step()
        print("Connect {} to GND, and {} to VCC.".format(rst, direction))
        input("Hit enter after done ...")
        for _ in range(len(output_pattern_down)):
            fsm_generator.step()

        test_string = state_bit0_string = state_bit1_string = ''
        for wavegroup in fsm_generator.waveform.waveform_dict['signal']:
            if wavegroup and wavegroup[0] == 'analysis':
                for wavelane in wavegroup[1:]:
                    if wavelane['name'] == 'test':
                        test_string = wavelane['wave']
                    if wavelane['name'] == 'state_bit0':
                        state_bit0_string = wavelane['wave']
                    if wavelane['name'] == 'state_bit1':
                        state_bit1_string = wavelane['wave']
        test_array = np.array(bitstring_to_int(wave_to_bitstring(test_string)))
        state_bit0_array = np.array(
            bitstring_to_int(wave_to_bitstring(state_bit0_string)))
        state_bit1_array = np.array(
            bitstring_to_int(wave_to_bitstring(state_bit1_string)))

        assert np.array_equal(golden_test_array, test_array), \
            'Data pattern not correct when stepping at {}MHz.'.format(
                    fsm_frequency_mhz)
        assert np.array_equal(golden_state_bit0_array, state_bit0_array), \
            'State bit0 not correct when stepping at {}MHz.'.format(
                    fsm_frequency_mhz)
        assert np.array_equal(golden_state_bit1_array, state_bit1_array), \
            'State bit1 not correct when stepping at {}MHz.'.format(
                    fsm_frequency_mhz)

        fsm_generator.stop()
        fsm_generator.reset()
        del fsm_generator