示例#1
0
    def init_hw(self):
        ''' initialize hardware interfaces. should never be called
        except on initialization or by the reset function, else competing
        for hardware resources

        returns log string and status for awg and digitizer as tuples
        '''
        awgModules, awg_log, awg_status = self.open_modules(
            self.awg_slots, 'awg')
        digModules, dig_log, dig_status = self.open_modules(
            self.dig_slots, 'dig')

        if self.__initialized == False:
            self.hvi = pyhvi.KtHvi("KtHvi")
            self.hvi.platform.chassis.add_auto_detect()
        index = 0
        for awgModule in awgModules:
            awg = AWG(self.hvi, awgModule, index)
            self.awgs.append(awg)
            index += 1
        for digModule in digModules:
            dig = DIG(self.hvi, digModule, index)
            self.digs.append(dig)
            index += 1
        return (awg_log, awg_status), (dig_log, dig_status)
示例#2
0
    def __init__(self, chassis):
        '''
        set up chassis

        the main function connects to hardware, writes a trigger instruction sequence to all hardware,
        then runs triggering until user interrupt
        '''
        # modules chassis and slot numbers
        if self.__initialized: return

        self.__initialized = True
        self.awg_slots = []
        self.dig_slots = []
        self.slot_free = [True] * 18

        # Ext trigger module (TODO: not sure if these values might ever change)
        self.chassis = chassis
        slotNumber = 6
        partNumber = ""

        extTrigModule = keysightSD1.SD_AOU()
        status = extTrigModule.openWithSlot(partNumber, self.chassis,
                                            slotNumber)
        if (status < 0):
            raise Error(
                "Invalid external trigger module. Name, Chassis or Slot numbers might be invalid!"
            )

        # Create HVI instance
        moduleResourceName = "KtHvi"
        self.hvi = pyhvi.KtHvi(moduleResourceName)

        # Add chassis
        self.hvi.platform.chassis.add_auto_detect()

        # initialize lists for clarity
        self.awgs = []
        self.digs = []
        # ensure that when program quits, the hardware resources will be released
        atexit.register(self.close)
def main():
    hwSimulated = False

    if hwSimulated:
        options = ",simulated=true"
    elif hwSimulated == False:
        options = ""
    else:
        print("hwSimulated not set to valid value")
        sys.exit()

    # Create module definitions
    moduleDescriptors = [
        ModuleDescriptor(1, 7, options),
        ModuleDescriptor(1, 15, options)
    ]

    moduleList = []
    minChassis = 0
    maxChassis = 0

    # Open modules
    for descriptor in moduleDescriptors:
        newModule = keysightSD1.SD_AOU()
        chassisNumber = descriptor.chassisNumber
        id = newModule.openWithSlot("", chassisNumber, descriptor.slotNumber)
        if id < 0:
            print(
                "Error opening module in chassis {}, slot {}, opened with ID: {}"
                .format(descriptor.chassisNumber, descriptor.slotNumber, id))
            print("Press any key to exit...")
            input()
            sys.exit()

        # Determine what minChassis is based off information in module descriptors
        moduleList.append(newModule)
        if minChassis == 0 or minChassis > chassisNumber:
            minChassis = chassisNumber

        if maxChassis == 0 or maxChassis < chassisNumber:
            maxChassis = chassisNumber

    # Queue waveforms
    for index in range(0, len(moduleList)):
        AWGqueueWfm(moduleList[index])

    # Obtain HVI interface from modules
    moduleHviList = []
    for module in moduleList:
        if not module.hvi:
            print(
                "Module in chassis {} and slot {} does not support HVI2.0... exiting"
                .format(module.getChassis(), module.getSlot()))
            sys.exit()
        moduleHviList.append(module.hvi)

    ######################################
    ## Configure resources in HVI instance
    ######################################

    # Add engines to the engineList
    engineList = []
    for module in moduleHviList:
        engineList.append(module.engines.master_engine)

    # Create HVI instance
    moduleResourceName = "KtHvi"
    hvi = pyhvi.KtHvi(moduleResourceName)

    # Assign triggers to HVI object to be used for HVI-managed synch, data sharing, etc.
    triggerResources = [
        pyhvi.TriggerResourceId.PXI_TRIGGER5,
        pyhvi.TriggerResourceId.PXI_TRIGGER6,
        pyhvi.TriggerResourceId.PXI_TRIGGER7
    ]
    hvi.platform.sync_resources = triggerResources

    # Assign clock frequences that are outside the set of the clock frequencies of each hvi engine
    nonHVIclocks = [10e6]
    hvi.synchronization.non_hvi_core_clocks = nonHVIclocks

    if engineList.__len__() > 1:
        # Add chassis
        if hwSimulated:
            for chassis in range(minChassis, maxChassis + 1):
                hvi.platform.chassis.add_with_options(
                    chassis,
                    "Simulate=True,DriverSetup=model=M9018B,NoDriver=True")
        else:
            hvi.platform.chassis.add_auto_detect()

        ##### Uncomment for debugging with squidboard
        # for chassis in range(minChassis, maxChassis):
        #     lowSlot = 14
        #     if chassis == minChassis:
        #         lowSlot = 9
        #
        #     hvi.platform.add_squidboards(chassis, lowSlot, chassis + 1, 9)

    # Get engine IDs
    engine_count = 0
    for engineID in engineList:
        hvi.engines.add(engineID, "SdEngine{}".format(engine_count))
        engine_count += 1

    ######################################
    ## Start HVI sequence creation
    ######################################

    print("Press enter to begin creation of the HVI sequence")
    input()

    # Create register cycleCnt in module0, the module waiting for external trigger events
    seq0 = hvi.engines[0].main_sequence
    cycleCnt = seq0.registers.add("cycleCnt", pyhvi.RegisterSize.SHORT)

    # Create a register WfNum in each PXI module. WfNum will be used to queue waveforms
    for index in range(0, hvi.engines.count):
        engine = hvi.engines[index]
        seq = engine.main_sequence
        seq.registers.add("WfNum", pyhvi.RegisterSize.SHORT)

    # Create list of module resources to use in HVI sequence
    waitTrigger = moduleHviList[0].triggers.pxi_2
    hvi.engines[0].events.add(waitTrigger, "extEvent")

    # Add wait statement to first engine sequence (using sequence.programming interface)
    waitEvent = seq0.programming.add_wait_event("wait_external_trigger", 10)
    waitEvent.event = hvi.engines[0].events["extEvent"]
    waitEvent.set_mode(pyhvi.EventDetectionMode.TRANSITION_TO_IDLE,
                       pyhvi.SyncMode.IMMEDIATE)

    # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for).
    trigger = hvi.engines[0].triggers.add(waitTrigger, "extTrigger")
    trigger.configuration.direction = pyhvi.Direction.INPUT
    trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_HIGH

    # Add global synchronized junction to HVI instance using hvi.programming interface
    junctionName = "GlobalJunction"
    junctionTime_ns = 10
    hvi.programming.add_junction(junctionName, junctionTime_ns)

    # Parameters for AWG queue WFM with register
    startDelay = 0
    nCycles = 1
    prescaler = 0
    nAWG = 0

    # Add actions to HVI engines
    for index in range(0, hvi.engines.count):
        moduleActions = moduleList[index].hvi.actions
        engine = hvi.engines[index]
        engine.actions.add(moduleActions.awg1_start, "awg_start1")
        engine.actions.add(moduleActions.awg2_start, "awg_start2")

        engine.actions.add(moduleActions.awg1_trigger, "awg_trigger1")
        engine.actions.add(moduleActions.awg2_trigger, "awg_trigger2")

    # Add AWG queue waveform and AWG trigger to each module's sequence
    for index in range(0, hvi.engines.count):
        engine = hvi.engines[index]

        # Obtain main sequence from engine to add instructions
        seq = engine.main_sequence

        # Add AWG queue waveform instruction to the sequence
        AwgQueueWfmInstrId = moduleList[
            index].hvi.instructions.queuewaveform.id
        AwgQueueWfmId = moduleList[
            index].hvi.instructions.queuewaveform.waveform.id

        instruction0 = seq.programming.add_instruction("awgQueueWaveform", 10,
                                                       AwgQueueWfmInstrId)
        instruction0.set_parameter(AwgQueueWfmId, seq.registers["WfNum"])
        instruction0.set_parameter(
            moduleList[index].hvi.instructions.queuewaveform.channel.id, nAWG)
        instruction0.set_parameter(
            moduleList[index].hvi.instructions.queuewaveform.trigger_mode.id,
            keysightSD1.SD_TriggerModes.SWHVITRIG)
        instruction0.set_parameter(
            moduleList[index].hvi.instructions.queuewaveform.start_delay.id,
            startDelay)
        instruction0.set_parameter(
            moduleList[index].hvi.instructions.queuewaveform.cycles.id,
            nCycles)
        instruction0.set_parameter(
            moduleList[index].hvi.instructions.queuewaveform.prescaler.id,
            prescaler)

        awgTriggerList = [
            engine.actions["awg_trigger1"], engine.actions["awg_trigger2"]
        ]
        instruction2 = seq.programming.add_instruction(
            "AWG trigger", 2e3, hvi.instructions.action_execute.id)
        instruction2.set_parameter(hvi.instructions.action_execute.action,
                                   awgTriggerList)

    # Increment cycleCnt in module0
    instructionRYinc = seq0.programming.add_instruction(
        "add", 10, hvi.instructions.add.id)
    instructionRYinc.set_parameter(hvi.instructions.add.left_operand, 1)
    instructionRYinc.set_parameter(hvi.instructions.add.right_operand,
                                   cycleCnt)
    instructionRYinc.set_parameter(hvi.instructions.add.result_register,
                                   cycleCnt)

    # Global Jump
    jumpName = "jumpStatement"
    jumpTime = 10000
    jumpDestination = "Start"
    hvi.programming.add_jump(jumpName, jumpTime, jumpDestination)

    # Add global synchronized end to close HVI execution (close all sequences - using hvi-programming interface)
    hvi.programming.add_end("EndOfSequence", 100)

    ############################################
    ## Compile and run HVI2.0 virtual instrument
    ############################################

    # Compile the sequence
    hvi.compile()

    # Load the HVI to HW: load sequences, config triggers/events/..., lock resources, etc.
    hvi.load_to_hw()

    print("Press enter to start HVI...")
    input()

    time = timedelta(seconds=0)
    hvi.run(time)

    status = 1
    chassisNumber = 1
    slotNumber = 8
    extTrigModule = keysightSD1.SD_AOU()

    partNumber = ""

    # Connect to trigger module
    status = extTrigModule.openWithSlot(partNumber, chassisNumber, slotNumber)
    if (status < 0):
        print(
            "Invalid Module Name, Chassis or Slot numbers might be invalid! Press enter to quit"
        )
        input()
        sys.exit()

    # initialize register cycleCnt
    seq0.registers["cycleCnt"].write(0)

    wfNum = 1
    nWfm = 2

    # Loop as many times as desired, press q to exit
    while True:
        for index in range(0, hvi.engines.count):
            engine = hvi.engines[index]
            seq = engine.main_sequence
            seq.registers["WfNum"].write(wfNum)

        print("N. of external triggers received at Module0: cycleCnt = {}".
              format(seq0.registers["cycleCnt"].read()))
        print("Press enter to trigger PXI2, press q to exit")

        key = input()

        if key == 'q':
            break
        else:
            triggerPXI2(extTrigModule)

        # Change wfNum at each iteration
        if (wfNum >= nWfm):  # general case of nWfm
            wfNum = 1
        else:
            wfNum = wfNum + 1

    # Release HVI instance from HW (unlock resources)
    print("Exiting...")
    hvi.release_hw()

    # Close modules
    for module in moduleList:
        module.close()
示例#4
0
def main():
    # Initialize variables used in 'finally:' block (in case an exception is thrown early)
    hvi = 0
    module = None

    try:
        # Parse the optional --simulate argument
        args = parse_args()
        hardware_simulated = args.simulate

        # Set the options string based on the value of the optional --simulate argument
        options = 'simulate=true' if hardware_simulated else ''

        # Open SD module
        module = keysightSD1.SD_AOU()

        chassis_number = 1
        slot_number = 4
        module_id = module.openWithOptions('M3201A', chassis_number,
                                           slot_number, options)
        if module_id < 0:
            raise Exception(
                f'Error opening module in chassis: {chassis_number}, {slot_number}, opened with ID: {module_id}'
            )
        print(f'Module ID {module_id} opened')

        # Create SD_AOUHvi object from SD module
        sd_hvi = module.hvi
        if not sd_hvi:
            raise Exception('Module does not support HVI2')

        # Get engine from SD module's SD_AOUHvi object
        sd_engine_aou = sd_hvi.engines.master_engine

        # Create KtHvi instance
        module_resource_name = 'KtHvi'
        hvi = pyhvi.KtHvi(module_resource_name)

        # Add SD HVI engine to KtHvi instance
        engine = hvi.engines.add(sd_engine_aou, 'SdEngine1')

        # Configure the trigger used by the sequence
        sequence_trigger = engine.triggers.add(sd_hvi.triggers.pxi_5,
                                               'SequenceTrigger')
        sequence_trigger.configuration.direction = pyhvi.Direction.OUTPUT
        sequence_trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL
        sequence_trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW
        sequence_trigger.configuration.delay = 0
        sequence_trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL
        sequence_trigger.configuration.pulse_length = 250

        # *******************************
        # Start KtHvi sequences creation
        sequence = engine.main_sequence  # Obtain main squence from the created HVI instrument

        instruction1 = sequence.programming.add_instruction(
            'TriggerOn', 10, hvi.instructions.instructions_trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction1.set_parameter(
            hvi.instructions.instructions_trigger_write.parameters.trigger,
            sequence_trigger)  # Specify which trigger is going to be used
        instruction1.set_parameter(
            hvi.instructions.instructions_trigger_write.parameters.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction1.set_parameter(
            hvi.instructions.instructions_trigger_write.parameters.value,
            pyhvi.TriggerValue.ON
        )  # Specify trigger value that is going to be applied

        instruction2 = sequence.programming.add_instruction(
            'TriggerOff', 100, hvi.instructions.instructions_trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction2.set_parameter(
            hvi.instructions.instructions_trigger_write.parameters.trigger,
            sequence_trigger)  # Specify which trigger is going to be used
        instruction2.set_parameter(
            hvi.instructions.instructions_trigger_write.parameters.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction2.set_parameter(
            hvi.instructions.instructions_trigger_write.parameters.value,
            pyhvi.TriggerValue.OFF
        )  # Specify trigger value that is going to be applied

        hvi.programming.add_end(
            'EndOfSequence',
            10)  # Add the end statement at the end of the sequence

        # Assign triggers to HVI object to be used for HVI-managed synchronization, data sharing, etc
        trigger_resources = [
            pyhvi.TriggerResourceId.PXI_TRIGGER0,
            pyhvi.TriggerResourceId.PXI_TRIGGER1
        ]
        hvi.platform.sync_resources = trigger_resources
        hvi.compile()  # Compile the instrument sequence(s)
        hvi.load_to_hw()  # Load the instrument sequence(s) to HW
        time = timedelta(seconds=1)
        hvi.run(time)  # Execute the instrument sequence(s)

    except Exception as ex:
        print(ex)
        print('helloworld.py encountered the error above - exiting')

    finally:
        # Release KtHvi instance from HW (unlock resources)
        if hvi:
            hvi.release_hw()

        # Close module
        if module:
            module.close()
示例#5
0
def main():
    # Initialize variables used in 'finally:' block (in case an exception is thrown early)
    hvi = 0
    module_list = []

    try:
        # Parse the optional --simulate argument
        args = parse_args()
        hardware_simulated = args.simulate

        # Set the options string based on the value of the optional --simulate argument
        options = 'simulate=true' if hardware_simulated else ''

        # Define list of module descriptors
        module_descriptors = [{
            'chassis_number': 1,
            'slot_number': 9,
            'options': options
        }, {
            'chassis_number': 1,
            'slot_number': 10,
            'options': options
        }]

        # Open SD modules
        module_list = []
        for descriptor in module_descriptors:
            module = keysightSD1.SD_AOU()
            id = module.openWithOptions('M3201A', descriptor['chassis_number'],
                                        descriptor['slot_number'],
                                        descriptor['options'])
            if id < 0:
                raise Exception(
                    f"Error opening module in chassis: {descriptor['chassis_number']}, {descriptor['slot_number']}, opened with ID: {id}"
                )
            module_list.append(module)

        # Obtain SD_AOUHvi interface from modules
        module_hvi_list = []
        for module in module_list:
            if not module.hvi:
                raise Exception(
                    f'Module in chassis {module.chassis} and slot {module.slot} does not support HVI2'
                )
            module_hvi_list.append(module.hvi)

        # Create list of triggers to use in KtHvi sequence
        trigger_list = [
            module_hvi_list[0].triggers.front_panel_1,
            module_hvi_list[1].triggers.front_panel_1
        ]

        # Create KtHvi instance
        module_resource_name = 'KtHvi'
        hvi = pyhvi.KtHvi(module_resource_name)

        # *********************************
        # Config resource in KtHvi instance

        # Add chassis to KtHvi instance
        if hardware_simulated:
            hvi.platform.chassis.add_with_options(
                1, 'Simulate=True,DriverSetup=model=M9018B,NoDriver=True')
        else:
            hvi.platform.chassis.add_auto_detect()

        # Get engine IDs from module's SD_AOUHvi interface and add each engine to KtHvi instance
        engine_index = 0
        for module_hvi in module_hvi_list:
            sd_engine = module_hvi.engines.master_engine
            hvi.engines.add(sd_engine, f'SdEngine{engine_index}')
            engine_index += 1

        # Configure the trigger used by the sequence
        for index in range(0, hvi.engines.count):
            engine = hvi.engines[index]

            trigger = engine.triggers.add(trigger_list[index],
                                          'SequenceTrigger')
            trigger.configuration.direction = pyhvi.Direction.OUTPUT
            trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL
            trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW
            # trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_HIGH
            trigger.configuration.delay = 0
            trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL
            trigger.configuration.pulse_length = 250

# *******************************
# Start KtHvi sequences creation

        for index in range(0, hvi.engines.count):
            # Get engine in the KtHvi instance
            engine = hvi.engines[index]

            # Obtain main sequence from engine to add instructions
            sequence = engine.main_sequence

            # Add instructions to specific sequence (using sequence.programming interface)
            instruction1 = sequence.programming.add_instruction(
                'TriggerOn', 10, hvi.instructions.instructions_trigger_write.id
            )  # Add trigger write instruction to the sequence
            instruction1.set_parameter(
                hvi.instructions.instructions_trigger_write.trigger,
                engine.triggers['SequenceTrigger']
            )  # Specify which trigger is going to be used
            instruction1.set_parameter(
                hvi.instructions.instructions_trigger_write.sync_mode,
                pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
            instruction1.set_parameter(
                hvi.instructions.instructions_trigger_write.value,
                pyhvi.TriggerValue.ON
            )  # Specify trigger value that is going to be applyed

            instruction2 = sequence.programming.add_instruction(
                'TriggerOff', 500, hvi.instructions.instructions_trigger_write.
                id)  # Add trigger write instruction to the sequence
            instruction2.set_parameter(
                hvi.instructions.instructions_trigger_write.trigger,
                engine.triggers['SequenceTrigger']
            )  # Specify which trigger is going to be used
            instruction2.set_parameter(
                hvi.instructions.instructions_trigger_write.sync_mode,
                pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
            instruction2.set_parameter(
                hvi.instructions.instructions_trigger_write.value,
                pyhvi.TriggerValue.OFF
            )  # Specify trigger value that is going to be applyed

        # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface)
        hvi.programming.add_end('EndOfSequence', 10)

        # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc
        hvi.platform.sync_resources = [
            pyhvi.TriggerResourceId.PXI_TRIGGER0,
            pyhvi.TriggerResourceId.PXI_TRIGGER1
        ]

        # Compile the instrument sequence(s)
        hvi.compile()

        # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc
        hvi.load_to_hw()

        # Execute KtHvi instance
        time = timedelta(seconds=1)
        hvi.run(time)

    except Exception as ex:
        print(ex)
        print('helloworldmimo.py encountered the error above - exiting')

    finally:
        # Release KtHvi instance from HW (unlock resources)
        if hvi:
            hvi.release_hw()

        # Close all modules
        for module in module_list:
            module.close()
示例#6
0
def main():
    # Initialize variables used in 'finally:' block (in case an exception is thrown early)
    hvi = 0
    module_list = []

    try:
        # Parse the optional --simulate argument
        args = parse_args()
        hardware_simulated = args.simulate

        # Set the options string based on the value of the optional --simulate argument
        options = 'simulate=true' if hardware_simulated else ''

        # Define list of module descriptors
        module_descriptors = [{
            'model_number': 'M3201A',
            'chassis_number': 1,
            'slot_number': 9,
            'options': options
        }, {
            'model_number': 'M3201A',
            'chassis_number': 1,
            'slot_number': 10,
            'options': options
        }]

        # Open SD modules
        nModules = 0
        for descriptor in module_descriptors:
            module = keysightSD1.SD_AOU()
            id = module.openWithOptions(descriptor['model_number'],
                                        descriptor['chassis_number'],
                                        descriptor['slot_number'],
                                        descriptor['options'])
            if id < 0:
                raise Exception(
                    f"Error opening module in chassis: {descriptor['chassis_number']}, {descriptor['slot_number']}, opened with ID: {id}"
                )
            module_list.append(module)
            nModules += 1

        # Queue AWG Waveforms
        for index in range(0, nModules):
            awgQueueWaveform(module_list[index])

        # Obtain SD_AOUHvi interface from modules
        module_hvi_list = []
        for module in module_list:
            if not module.hvi:
                raise Exception(
                    f'Module in chassis {module.chassis} and slot {module.slot} does not support HVI2'
                )
            module_hvi_list.append(module.hvi)

        # Create lists of triggers to use in KtHvi sequence
        wait_trigger = module_hvi_list[0].triggers.pxi_2
        trigger_list = []
        engine_list = []
        for module in module_hvi_list:
            trigger_list.append(module.triggers.front_panel_1)
            engine_list.append(module.engines.master_engine)

        # Create KtHvi instance
        module_resource_name = 'KtHvi'
        hvi = pyhvi.KtHvi(module_resource_name)

        # *********************************
        # Config resource in KtHvi instance

        # Add chassis to KtHvi instance
        if hardware_simulated:
            hvi.platform.chassis.add_with_options(
                1, 'Simulate=True,DriverSetup=model=M9018B,NoDriver=True')
        else:
            hvi.platform.chassis.add_auto_detect()

        # Add each engine to KtHvi instance
        engine_index = 0
        for engine in engine_list:
            hvi.engines.add(engine, f'SdEngine{engine_index}')
            engine_index += 1

        # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for).
        start_trigger = hvi.engines[0].triggers.add(wait_trigger,
                                                    'StartTrigger')
        start_trigger.configuration.direction = pyhvi.Direction.INPUT
        start_trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW

        # Add start event
        start_event = hvi.engines[0].events.add(wait_trigger, 'StartEvent')
        print("HVI Engine Count {} \n".format(hvi.engines.count))

        # *******************************
        # Start KtHvi sequences creation

        # Add wait statement to first engine sequence (using sequence.programming interface)
        engine_aou1_sequence = hvi.engines[0].main_sequence
        wait_event = engine_aou1_sequence.programming.add_wait_event(
            'wait external_trigger', 10)
        wait_event.event = hvi.engines[0].events['StartEvent']
        wait_event.set_mode(
            pyhvi.EventDetectionMode.HIGH, pyhvi.SyncMode.IMMEDIATE
        )  # Configure event detection and synchronization modes

        # Add global synchronized junction to HVI instance (to all sequences!!! - using hvi.programming interface)
        global_junction = 'GlobalJunction'
        junction_time_ns = 10
        hvi.programming.add_junction(global_junction, junction_time_ns)

        #Create a list of possible actions for AWG modules
        actions = module_list[0].hvi.actions
        # Define global AWG Trigger Action and Add it to the HVI Engine
        hvi.engines[0].actions.add(actions.awg1_trigger, 'AWG1_trigger')
        hvi.engines[0].actions.add(actions.awg2_trigger, 'AWG2_trigger')
        hvi.engines[0].actions.add(actions.awg3_trigger, 'AWG3_trigger')
        hvi.engines[0].actions.add(actions.awg4_trigger, 'AWG4_trigger')

        #Add AWG trigger to each module's sequence
        for index in range(0, hvi.engines.count):
            # Get engine in the KtHvi instance
            engine = hvi.engines[index]

            # Obtain main sequence from engine to add instructions
            sequence = engine.main_sequence

            #list of module possible actions
            actionList = [
                hvi.engines[0].actions['AWG1_trigger'],
                hvi.engines[0].actions['AWG2_trigger'],
                hvi.engines[0].actions['AWG3_trigger'],
                hvi.engines[0].actions['AWG4_trigger']
            ]

            #Add AWG trigger instruction to the sequence
            actionExecute = hvi.instructions.instructions_action_execute
            instruction1 = sequence.programming.add_instruction(
                "AWG trigger", 100, actionExecute.id)
            instruction1.set_parameter(actionExecute.action, actionList)

        #Synchronized jump
        jump_name = 'JumpStatement'
        jump_time = 1000
        jump_destination = "Start"
        hvi.programming.add_jump(jump_name, jump_time, jump_destination)

        # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface)
        hvi.programming.add_end('EndOfSequence', 10)

        # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc
        #NOTE: In a multi-chassis setup ALL the PXI lines listed below need to be shared among each squid board pair by means of SMB cable connections
        hvi.platform.sync_resources = [
            pyhvi.TriggerResourceId.PXI_TRIGGER5,
            pyhvi.TriggerResourceId.PXI_TRIGGER6,
            pyhvi.TriggerResourceId.PXI_TRIGGER7
        ]

        #Assign clock frequencies that are outside the set of the clock frequencies of each HVI engine
        hvi.synchronization.non_hvi_core_clocks = [10e6]

        #Force synchronization
        hvi.synchronization.synchronize(True)

        # Compile the instrument sequence(s)
        hvi.compile()
        print("HVI Compiled")

        # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc
        hvi.load_to_hw()
        print("HVI Loaded to HW")

        # Execute KtHvi instance
        time = timedelta(seconds=0)
        hvi.run(time)
        print("HVI Running...")

        # If running with hardware, stop execution here until the user presses a key to finish
        if not hardware_simulated:
            print("Press enter to finish...")
            input()

    except Exception as ex:
        print(ex)
        print('HD1_AN1_Multi.py encountered the error above - exiting')

    finally:
        # Release KtHvi instance from HW (unlock resources)
        if hvi:
            hvi.release_hw()

        # Close all modules
        for module in module_list:
            module.close()
if AWG_ID_b < 0:
    print("Error opening AWG_b")
    
error_chanWaveShape = AWG_b.channelWaveShape(AWG_b_channel,waveshape)
AWG_b.waveformFlush() 
AWG_b.AWGflush(AWG_b_channel) #clear waveform from channel


SD1hvi_a = AWG_a.hvi
SD1hvi_b = AWG_b.hvi
#get engine from SD module's HVI object
engine =
engine_a = SD1hvi_a.engines.master_engine;
engine_b = SD1hvi_b.engines.master_engine;

hvi = pyhvi.KtHvi(ResourceName)


#Add simulateed chassis
hvi.platform.chassis.add_with_options(1, "Simulate=True,DriverSetup=model=M9018B,NoDriver=True")


engineAOU_a = hvi.engines.add(engine_a, "SdEngine1")
engineAOU_b = hvi.engines.add(engine_b, "SdEngine2")


# triggerList = [SD1hvi_a.triggers.front_panel_1,SD1hvi_b.triggers.front_panel_1]

AWG_a_sequence = engineAOU_a.main_sequence
AWG_b_sequence = engineAOU_b.main_sequence
示例#8
0
def _fast_branching_hvi_configurator(Test_obj):

    moduleHviList = []
    for module in Test_obj.module_instances:
        if not module[0].hvi:
            print(
                "Module in chassis {} and slot {} does not support HVI2.0... exiting"
                .format(module.getChassis(), module.getSlot()))
            sys.exit()
        moduleHviList.append(module[0].hvi)

    ######################################
    ## Configure resources in HVI instance
    ######################################

    # Add engines to the engineList
    engineList = []
    for module in moduleHviList:
        engineList.append(module.engines.main_engine)

    # Create HVI instance
    moduleResourceName = "KtHvi"
    Test_obj.hvi = pyhvi.KtHvi(moduleResourceName)

    # Assign triggers to HVI object to be used for HVI-managed synch, data sharing, etc.
    triggerResources = [
        pyhvi.TriggerResourceId.PXI_TRIGGER0,
        pyhvi.TriggerResourceId.PXI_TRIGGER1,
        pyhvi.TriggerResourceId.PXI_TRIGGER7
    ]
    Test_obj.hvi.platform.sync_resources = triggerResources

    # Assign clock frequences that are outside the set of the clock frequencies of each hvi engine
    nonHVIclocks = [10e6]
    Test_obj.hvi.synchronization.non_hvi_core_clocks = nonHVIclocks

    if engineList.__len__() > 1:
        Test_obj.hvi.platform.chassis.add_auto_detect()

    # Get engine IDs
    engine_count = 0
    for engineID in engineList:
        Test_obj.hvi.engines.add(engineID, "SdEngine{}".format(engine_count))
        engine_count += 1

    ######################################
    ## Start HVI sequence creation
    ######################################

    print("Press enter to begin creation of the HVI sequence")
    input()

    # Create register cycleCnt in module0, the module waiting for external trigger events
    seq0 = Test_obj.hvi.engines[Test_obj.master_module_index].main_sequence
    cycleCnt = seq0.registers.add("cycleCnt", pyhvi.RegisterSize.SHORT)

    # Create a register WfNum in each PXI module. WfNum will be used to queue waveforms
    for index in range(0, Test_obj.hvi.engines.count):
        engine = Test_obj.hvi.engines[index]
        seq = engine.main_sequence
        seq.registers.add("WfNum", pyhvi.RegisterSize.SHORT)

    # Create list of module resources to use in HVI sequence
    waitTrigger = moduleHviList[Test_obj.master_module_index].triggers.pxi_2
    Test_obj.hvi.engines[Test_obj.master_module_index].events.add(
        waitTrigger, "extEvent")

    # Add wait statement to first engine sequence (using sequence.programming interface)
    waitEvent = seq0.programming.add_wait_event("wait_external_trigger", 10)
    waitEvent.event = Test_obj.hvi.engines[
        Test_obj.master_module_index].events["extEvent"]
    waitEvent.set_mode(pyhvi.EventDetectionMode.TRANSITION_TO_ACTIVE,
                       pyhvi.SyncMode.IMMEDIATE)

    # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for).
    trigger = Test_obj.hvi.engines[Test_obj.master_module_index].triggers.add(
        waitTrigger, "extTrigger")
    trigger.configuration.direction = pyhvi.Direction.INPUT
    trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_HIGH

    # Add global synchronized junction to HVI instance using hvi.programming interface
    junctionName = "GlobalJunction"
    junctionTime_ns = 10
    Test_obj.hvi.programming.add_junction(junctionName, junctionTime_ns)

    # Parameters for AWG queue WFM with register
    startDelay = 0
    nCycles = 1
    prescaler = 0
    nAWG = 1

    # Add actions to HVI engines
    for index in range(0, Test_obj.hvi.engines.count):
        moduleActions = Test_obj.module_instances[index][0].hvi.actions
        engine = Test_obj.hvi.engines[index]
        engine.actions.add(moduleActions.awg1_start, "awg_start1")
        # engine.actions.add(moduleActions.awg2_start, "awg_start2")
        # engine.actions.add(moduleActions.awg3_start, "awg_start3")
        # engine.actions.add(moduleActions.awg4_start, "awg_start4")

        engine.actions.add(moduleActions.awg1_trigger, "awg_trigger1")
        # engine.actions.add(moduleActions.awg2_trigger, "awg_trigger2")
        # engine.actions.add(moduleActions.awg3_trigger, "awg_trigger3")
        # engine.actions.add(moduleActions.awg4_trigger, "awg_trigger4")

    # Add AWG queue waveform and AWG trigger to each module's sequence
    for index in range(0, Test_obj.hvi.engines.count):
        engine = Test_obj.hvi.engines[index]

        # Obtain main sequence from engine to add instructions
        seq = engine.main_sequence

        # Add AWG queue waveform instruction to the sequence
        AwgQueueWfmInstrId = Test_obj.module_instances[index][
            0].hvi.instructions.queueWaveform.id
        AwgQueueWfmId = Test_obj.module_instances[index][
            0].hvi.instructions.queueWaveform.waveformNumber.id

        instruction0 = seq.programming.add_instruction("awgQueueWaveform", 10,
                                                       AwgQueueWfmInstrId)
        instruction0.set_parameter(AwgQueueWfmId, seq.registers["WfNum"])
        instruction0.set_parameter(
            Test_obj.module_instances[index]
            [0].hvi.instructions.queueWaveform.channel.id, nAWG)
        instruction0.set_parameter(
            Test_obj.module_instances[index]
            [0].hvi.instructions.queueWaveform.triggerMode.id,
            keysightSD1.SD_TriggerModes.SWHVITRIG)
        instruction0.set_parameter(
            Test_obj.module_instances[index]
            [0].hvi.instructions.queueWaveform.startDelay.id, startDelay)
        instruction0.set_parameter(
            Test_obj.module_instances[index]
            [0].hvi.instructions.queueWaveform.cycles.id, nCycles)
        instruction0.set_parameter(
            Test_obj.module_instances[index]
            [0].hvi.instructions.queueWaveform.prescaler.id, prescaler)

        awgTriggerList = [
            engine.actions["awg_trigger1"]
        ]  #, engine.actions["awg_trigger2"], engine.actions["awg_trigger3"], engine.actions["awg_trigger4"]]
        instruction2 = seq.programming.add_instruction(
            "AWG trigger", 2e3, Test_obj.hvi.instructions.action_execute.id)
        instruction2.set_parameter(
            Test_obj.hvi.instructions.action_execute.action, awgTriggerList)

    # Increment cycleCnt in module0
    instructionRYinc = seq0.programming.add_instruction(
        "add", 10, Test_obj.hvi.instructions.add.id)
    instructionRYinc.set_parameter(Test_obj.hvi.instructions.add.left_operand,
                                   1)
    instructionRYinc.set_parameter(Test_obj.hvi.instructions.add.right_operand,
                                   cycleCnt)
    instructionRYinc.set_parameter(
        Test_obj.hvi.instructions.add.result_register, cycleCnt)

    # Global Jump
    jumpName = "jumpStatement"
    jumpTime = 10000
    jumpDestination = "Start"
    Test_obj.hvi.programming.add_jump(jumpName, jumpTime, jumpDestination)

    # Add global synchronized end to close HVI execution (close all sequences - using hvi-programming interface)
    Test_obj.hvi.programming.add_end("EndOfSequence", 100)

    Test_obj.seq_master = Test_obj.hvi.engines[
        Test_obj.master_module_index].main_sequence

    print("Configured HVI for fast branching test.")
示例#9
0
def _helloworld_hvi_configurator(Test_obj):
    # Create SD_AOUHvi object from SD module

    for mod_inst in Test_obj.module_instances:

        module = mod_inst[0]

        sd_hvi = module.hvi

        if not sd_hvi:
            print('Module in CHASSIS {}, SLOT {} does not support HVI2'.format(
                mod_inst[2][0], mod_inst[2][1]))
            print("Press enter to exit.")
            input()
            sys.exit()

        # Get engine from SD module's SD_AOUHvi object
        sd_engine_aou = sd_hvi.engines.main_engine

        # Create KtHvi instance
        module_resource_name = 'KtHvi'
        hvi = pyhvi.KtHvi(module_resource_name)
        print("HVI instance: ...".format(hvi))

        # Add SD HVI engine to KtHvi instance
        engine = hvi.engines.add(sd_engine_aou, 'SdEngine1')
        print("hvi engine: {}...".format(engine))

        # Configure the trigger used by the sequence
        sequence_trigger = engine.triggers.add(sd_hvi.triggers.front_panel_1,
                                               'SequenceTrigger')
        sequence_trigger.configuration.direction = pyhvi.Direction.OUTPUT
        sequence_trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_LOW
        sequence_trigger.configuration.delay = 0
        sequence_trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL
        sequence_trigger.configuration.pulse_length = 250

        # *******************************
        # Start KtHvi sequences creation

        sequence = engine.main_sequence  # Obtain main squence from the created HVI instrument

        instruction1 = sequence.programming.add_instruction(
            'TriggerOn', 100, hvi.instructions.trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction1.set_parameter(
            hvi.instructions.trigger_write.trigger,
            sequence_trigger)  # Specify which trigger is going to be used
        instruction1.set_parameter(
            hvi.instructions.trigger_write.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction1.set_parameter(
            hvi.instructions.trigger_write.value, pyhvi.TriggerValue.ON
        )  # Specify trigger value that is going to be applied

        instruction2 = sequence.programming.add_instruction(
            'TriggerOff', 1000, hvi.instructions.trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction2.set_parameter(
            hvi.instructions.trigger_write.trigger,
            sequence_trigger)  # Specify which trigger is going to be used
        instruction2.set_parameter(
            hvi.instructions.trigger_write.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction2.set_parameter(
            hvi.instructions.trigger_write.value, pyhvi.TriggerValue.OFF
        )  # Specify trigger value that is going to be applied

        hvi.programming.add_end(
            'EndOfSequence',
            10)  # Add the end statement at the end of the sequence

        # Assign triggers to HVI object to be used for HVI-managed synchronization, data sharing, etc
        trigger_resources = [
            pyhvi.TriggerResourceId.PXI_TRIGGER0,
            pyhvi.TriggerResourceId.PXI_TRIGGER1
        ]
        hvi.platform.sync_resources = trigger_resources

        Test_obj.hvi_instances.append(hvi)

        print("Configured HVI for helloworld test")
示例#10
0
def _mimoresync_hvi_configurator(Test_obj):

    # Obtain SD_AOUHvi interface from modules
    module_hvi_list = []
    for module in Test_obj.module_instances:
        if not module[0].hvi:
            raise Exception(
                f'Module in chassis {module[2][0]} and slot {module[2][1]} does not support HVI2'
            )
        module_hvi_list.append(module[0].hvi)

    # Create lists of triggers to use in KtHvi sequence
    wait_trigger = module_hvi_list[Test_obj.master_module_index].triggers.pxi_2
    trigger_list = []
    engine_list = []
    for module in module_hvi_list:
        trigger_list.append(module.triggers.front_panel_1)
        engine_list.append(module.engines.main_engine)

    # Create KtHvi instance
    module_resource_name = 'KtHvi'
    Test_obj.hvi = pyhvi.KtHvi(module_resource_name)

    # *********************************
    # Config resource in KtHvi instance

    Test_obj.hvi.platform.chassis.add_auto_detect()

    #TODO: need to implement this portion
    # interconnects = hvi.platform.interconnects
    # interconnects.add_squidboards(1, 9, 2, 9)
    # interconnects.add_squidboards(2, 14, 3, 9)
    # interconnects.add_squidboards(3, 14, 4, 9)

    # Add each engine to KtHvi instance
    engine_index = 0
    for engine in engine_list:
        Test_obj.hvi.engines.add(engine, f'SdEngine{engine_index}')
        engine_index += 1

    # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for).
    start_trigger = Test_obj.hvi.engines[
        Test_obj.master_module_index].triggers.add(wait_trigger,
                                                   'StartTrigger')
    start_trigger.configuration.direction = pyhvi.Direction.INPUT
    start_trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_LOW

    # Add start event
    start_event = Test_obj.hvi.engines[
        Test_obj.master_module_index].events.add(wait_trigger, 'StartEvent')

    for index in range(0, Test_obj.hvi.engines.count):
        # Get engine in the KtHvi instance
        engine = Test_obj.hvi.engines[index]

        # Add trigger to engine
        trigger = engine.triggers.add(trigger_list[index], 'PulseOut')
        trigger.configuration.direction = pyhvi.Direction.OUTPUT
        trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL
        trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_LOW
        trigger.configuration.delay = 0
        trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL
        trigger.configuration.pulse_length = 250

    # *******************************
    # Start KtHvi sequences creation

    # Add wait statement to first engine sequence (using sequence.programming interface)
    engine_aou1_sequence = Test_obj.hvi.engines[
        Test_obj.master_module_index].main_sequence
    wait_event = engine_aou1_sequence.programming.add_wait_event(
        'wait external_trigger', 10)
    wait_event.event = Test_obj.hvi.engines[
        Test_obj.master_module_index].events['StartEvent']
    wait_event.set_mode(
        pyhvi.EventDetectionMode.ACTIVE, pyhvi.SyncMode.IMMEDIATE
    )  # Configure event detection and synchronization modes

    # Add global synchronized junction to HVI instance (to all sequences!!! - using hvi.programming interface)
    global_junction = 'GlobalJunction'
    junction_time_ns = 100
    Test_obj.hvi.programming.add_junction(global_junction, junction_time_ns)

    for index in range(0, Test_obj.hvi.engines.count):
        # Get engine in the KtHvi instance
        engine = Test_obj.hvi.engines[index]

        # Obtain main sequence from engine to add instructions
        sequence = engine.main_sequence

        # Add instructions to specific sequence (using sequence.programming interface)
        instruction1 = sequence.programming.add_instruction(
            'TriggerOn', 10, Test_obj.hvi.instructions.trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction1.set_parameter(
            Test_obj.hvi.instructions.trigger_write.trigger, engine.
            triggers['PulseOut'])  # Specify which trigger is going to be used
        instruction1.set_parameter(
            Test_obj.hvi.instructions.trigger_write.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction1.set_parameter(
            Test_obj.hvi.instructions.trigger_write.value, pyhvi.TriggerValue.
            ON)  # Specify trigger value that is going to be applyed

        instruction2 = sequence.programming.add_instruction(
            'TriggerOff', 100, Test_obj.hvi.instructions.trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction2.set_parameter(
            Test_obj.hvi.instructions.trigger_write.trigger, engine.
            triggers['PulseOut'])  # Specify which trigger is going to be used
        instruction2.set_parameter(
            Test_obj.hvi.instructions.trigger_write.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction2.set_parameter(
            Test_obj.hvi.instructions.trigger_write.value, pyhvi.TriggerValue.
            OFF)  # Specify trigger value that is going to be applyed

    jump_name = 'JumpStatement'
    jump_time = 1000
    jump_destination = "Start"
    Test_obj.hvi.programming.add_jump(jump_name, jump_time, jump_destination)

    # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface)
    Test_obj.hvi.programming.add_end('EndOfSequence', 10)

    # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc
    Test_obj.hvi.platform.sync_resources = [
        pyhvi.TriggerResourceId.PXI_TRIGGER5,
        pyhvi.TriggerResourceId.PXI_TRIGGER6,
        pyhvi.TriggerResourceId.PXI_TRIGGER7
    ]

    print("Configured HVI for mimo resync test")
示例#11
0
def _helloworldmimo_hvi_configurator(Test_obj):

    # Obtain SD_AOUHvi interface from modules
    module_hvi_list = []
    for module in Test_obj.module_instances:
        if not module[0].hvi:
            raise Exception(
                f'Module in chassis {module[2][0]} and slot {module[2][1]} does not support HVI2'
            )
        module_hvi_list.append(module[0].hvi)

    # Create list of triggers to use in KtHvi sequence
    trigger_list = []
    for mod in module_hvi_list:
        trigger_list.append(mod.triggers.front_panel_1)

    # Create KtHvi instance
    module_resource_name = 'KtHvi'
    Test_obj.hvi = pyhvi.KtHvi(module_resource_name)

    # *********************************
    # Config resource in KtHvi instance

    # Add chassis to KtHvi instance
    Test_obj.hvi.platform.chassis.add_auto_detect()

    # Get engine IDs from module's SD_AOUHvi interface and add each engine to KtHvi instance
    engine_index = 0
    for module_hvi in module_hvi_list:
        sd_engine = module_hvi.engines.main_engine
        Test_obj.hvi.engines.add(sd_engine, f'SdEngine{engine_index}')
        engine_index += 1

    # Configure the trigger used by the sequence
    for index in range(0, Test_obj.hvi.engines.count):
        engine = Test_obj.hvi.engines[index]

        trigger = engine.triggers.add(trigger_list[index], 'SequenceTrigger')
        trigger.configuration.direction = pyhvi.Direction.OUTPUT
        trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL
        trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_LOW
        trigger.configuration.delay = 0
        trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL
        trigger.configuration.pulse_length = 250

    # *******************************
    # Start KtHvi sequences creation

    for index in range(0, Test_obj.hvi.engines.count):
        # Get engine in the KtHvi instance
        engine = Test_obj.hvi.engines[index]

        # Obtain main sequence from engine to add instructions
        sequence = engine.main_sequence

        # Add instructions to specific sequence (using sequence.programming interface)
        instruction1 = sequence.programming.add_instruction(
            'TriggerOn', 10, Test_obj.hvi.instructions.trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction1.set_parameter(
            Test_obj.hvi.instructions.trigger_write.trigger,
            engine.triggers['SequenceTrigger']
        )  # Specify which trigger is going to be used
        instruction1.set_parameter(
            Test_obj.hvi.instructions.trigger_write.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction1.set_parameter(
            Test_obj.hvi.instructions.trigger_write.value, pyhvi.TriggerValue.
            ON)  # Specify trigger value that is going to be applyed

        instruction2 = sequence.programming.add_instruction(
            'TriggerOff', 500, Test_obj.hvi.instructions.trigger_write.id
        )  # Add trigger write instruction to the sequence
        instruction2.set_parameter(
            Test_obj.hvi.instructions.trigger_write.trigger,
            engine.triggers['SequenceTrigger']
        )  # Specify which trigger is going to be used
        instruction2.set_parameter(
            Test_obj.hvi.instructions.trigger_write.sync_mode,
            pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
        instruction2.set_parameter(
            Test_obj.hvi.instructions.trigger_write.value, pyhvi.TriggerValue.
            OFF)  # Specify trigger value that is going to be applyed

    # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface)
    Test_obj.hvi.programming.add_end('EndOfSequence', 10)

    # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc
    Test_obj.hvi.platform.sync_resources = [
        pyhvi.TriggerResourceId.PXI_TRIGGER0,
        pyhvi.TriggerResourceId.PXI_TRIGGER1
    ]

    print("Configured HVI for helloworldmimo test")
def main():
    # Initialize variables used in 'finally:' block (in case an exception is thrown early)
    hvi = 0
    module_list = []

    try:
        # Parse the optional --simulate argument
        args = parse_args()
        hardware_simulated = args.simulate

        # Set the options string based on the value of the optional --simulate argument
        options = 'HVI2=true,factory=true,' + ('simulate=true'
                                               if hardware_simulated else '')

        # Define list of module descriptors
        module_descriptors = [
            {
                'model_number': 'M3201A',
                'chassis_number': 1,
                'slot_number': 9,
                'options': options
            }, {
                'model_number': 'M3201A',
                'chassis_number': 1,
                'slot_number': 10,
                'options': options
            }
            # {'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 3, 'options': options },
            # {'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 8, 'options': options },
            # {'model_number': 'M3201A', 'chassis_number': 2, 'slot_number': 17, 'options': options },
            # {'model_number': 'M3201A', 'chassis_number': 3, 'slot_number': 15, 'options': options },
            # {'model_number': 'M3201A', 'chassis_number': 4, 'slot_number': 16, 'options': options }
        ]

        chassis_list = set()

        # Open SD modules
        for descriptor in module_descriptors:
            module = keysightSD1.SD_AOU()
            id = module.openWithOptions(descriptor['model_number'],
                                        descriptor['chassis_number'],
                                        descriptor['slot_number'],
                                        descriptor['options'])
            if id < 0:
                raise Exception(
                    f"Error opening module in chassis: {descriptor['chassis_number']}, {descriptor['slot_number']}, opened with ID: {id}"
                )
            module_list.append(module)
            chassis_list.add(descriptor['chassis_number'])

        # Obtain SD_AOUHvi interface from modules
        module_hvi_list = []
        for module in module_list:
            if not module.hvi:
                raise Exception(
                    f'Module in chassis {module.chassis} and slot {module.slot} does not support HVI2'
                )
            module_hvi_list.append(module.hvi)

        # Create lists of triggers to use in KtHvi sequence
        wait_trigger = module_hvi_list[0].triggers.pxi_2
        trigger_list = []
        engine_list = []
        for module in module_hvi_list:
            trigger_list.append(module.triggers.front_panel_1)
            engine_list.append(module.engines.master_engine)

        # Create KtHvi instance
        module_resource_name = 'KtHvi'
        hvi = pyhvi.KtHvi(module_resource_name)

        # *********************************
        # Config resource in KtHvi instance

        # Add chassis to KtHvi instance
        if hardware_simulated:
            for chassis_number in chassis_list:
                hvi.platform.chassis.add_with_options(
                    chassis_number,
                    'Simulate=True,DriverSetup=model=M9018B,NoDriver=True')
        else:
            hvi.platform.chassis.add_auto_detect()

        # interconnects = hvi.platform.interconnects
        # interconnects.add_squidboards(1, 9, 2, 9)
        # interconnects.add_squidboards(2, 14, 3, 9)
        # interconnects.add_squidboards(3, 14, 4, 9)

        # Add each engine to KtHvi instance
        engine_index = 0
        for engine in engine_list:
            hvi.engines.add(engine, f'SdEngine{engine_index}')
            engine_index += 1

        # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for).
        start_trigger = hvi.engines[0].triggers.add(wait_trigger,
                                                    'StartTrigger')
        start_trigger.configuration.direction = pyhvi.Direction.INPUT
        start_trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW

        # Add start event
        start_event = hvi.engines[0].events.add(wait_trigger, 'StartEvent')

        for index in range(0, hvi.engines.count):
            # Get engine in the KtHvi instance
            engine = hvi.engines[index]

            # Add trigger to engine
            trigger = engine.triggers.add(trigger_list[index], 'PulseOut')
            trigger.configuration.direction = pyhvi.Direction.OUTPUT
            trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL
            trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW
            trigger.configuration.delay = 0
            trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL
            trigger.configuration.pulse_length = 250

        # *******************************
        # Start KtHvi sequences creation

        # Add wait statement to first engine sequence (using sequence.programming interface)
        engine_aou1_sequence = hvi.engines[0].main_sequence
        wait_event = engine_aou1_sequence.programming.add_wait_event(
            'wait external_trigger', 10)
        wait_event.event = hvi.engines[0].events['StartEvent']
        wait_event.set_mode(
            pyhvi.EventDetectionMode.HIGH, pyhvi.SyncMode.IMMEDIATE
        )  # Configure event detection and synchronization modes

        # Add global synchronized junction to HVI instance (to all sequences!!! - using hvi.programming interface)
        global_junction = 'GlobalJunction'
        junction_time_ns = 100
        hvi.programming.add_junction(global_junction, junction_time_ns)

        for index in range(0, hvi.engines.count):
            # Get engine in the KtHvi instance
            engine = hvi.engines[index]

            # Obtain main sequence from engine to add instructions
            sequence = engine.main_sequence

            # Add instructions to specific sequence (using sequence.programming interface)
            instruction1 = sequence.programming.add_instruction(
                'TriggerOn', 10, hvi.instructions.instructions_trigger_write.id
            )  # Add trigger write instruction to the sequence
            instruction1.set_parameter(
                hvi.instructions.instructions_trigger_write.trigger,
                engine.triggers['PulseOut']
            )  # Specify which trigger is going to be used
            instruction1.set_parameter(
                hvi.instructions.instructions_trigger_write.sync_mode,
                pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
            instruction1.set_parameter(
                hvi.instructions.instructions_trigger_write.value,
                pyhvi.TriggerValue.ON
            )  # Specify trigger value that is going to be applyed

            instruction2 = sequence.programming.add_instruction(
                'TriggerOff', 100, hvi.instructions.instructions_trigger_write.
                id)  # Add trigger write instruction to the sequence
            instruction2.set_parameter(
                hvi.instructions.instructions_trigger_write.trigger,
                engine.triggers['PulseOut']
            )  # Specify which trigger is going to be used
            instruction2.set_parameter(
                hvi.instructions.instructions_trigger_write.sync_mode,
                pyhvi.SyncMode.IMMEDIATE)  # Specify synchronization mode
            instruction2.set_parameter(
                hvi.instructions.instructions_trigger_write.value,
                pyhvi.TriggerValue.OFF
            )  # Specify trigger value that is going to be applyed

        jump_name = 'JumpStatement'
        jump_time = 1000
        jump_destination = "Start"
        hvi.programming.add_jump(jump_name, jump_time, jump_destination)

        # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface)
        hvi.programming.add_end('EndOfSequence', 10)

        # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc
        hvi.platform.sync_resources = [
            pyhvi.TriggerResourceId.PXI_TRIGGER5,
            pyhvi.TriggerResourceId.PXI_TRIGGER6,
            pyhvi.TriggerResourceId.PXI_TRIGGER7
        ]

        # Compile the instrument sequence(s)
        hvi.compile()

        # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc
        hvi.load_to_hw()

        # Execute KtHvi instance
        time = timedelta(seconds=0)
        hvi.run(time)

        # If running with hardware, stop execution here until the user presses a key to finish
        if not hardware_simulated:
            print("Press enter to finish...")
            input()

    except Exception as ex:
        print(ex)
        print('mimoresync.py encountered the error above - exiting')

    finally:
        # Release KtHvi instance from HW (unlock resources)
        if hvi:
            hvi.release_hw()

        # Close all modules
        for module in module_list:
            module.close()