예제 #1
0
    def _get_waveform_table(self, awg_nr: int) -> list:
        """
        Returns the waveform table.

        The waveform table determines the mapping of waveforms to DIO codewords.
        The index of the table corresponds to the DIO codeword.
        The entry is a tuple of waveform names.

        Example:
            ["wave_ch7_cw000", "wave_ch8_cw000",
            "wave_ch7_cw001", "wave_ch8_cw001",
            "wave_ch7_cw002", "wave_ch8_cw002"]

        The waveform table generated depends on the awg_nr and the codeword
        protocol.
        """
        ch = awg_nr * 2
        wf_table = []
        if 'flux' in self.cfg_codeword_protocol():
            for cw_r in range(8):
                for cw_l in range(8):
                    wf_table.append((zibase.gen_waveform_name(ch, cw_l),
                                     zibase.gen_waveform_name(ch + 1, cw_r)))
        else:
            for dio_cw in range(self._num_codewords):
                wf_table.append((zibase.gen_waveform_name(ch, dio_cw),
                                 zibase.gen_waveform_name(ch + 1, dio_cw)))
        return wf_table
예제 #2
0
 def plot_awg_codewords(self, awg_nr=0, range=None):
     ts = []
     cws = []
     for d in self.getv('awgs/{}/dio/data'.format(awg_nr)):
         cws.append(d & 0x3ff)
         ts.append((d >> 10) & 0x3fffff)
     zibase.plot_codeword_diagram(ts, cws, range)
예제 #3
0
 def _check_awg_nr(self, awg_nr):
     """
     Checks that the given AWG index is valid for the device.
     """
     if self.devtype == 'HDAWG8' and (awg_nr < 0 or awg_nr > 3):
         raise zibase.ziValueError(
             'Invalid AWG index of {} detected!'.format(awg_nr))
     elif self.devtype == 'HDAWG4' and (awg_nr < 0 or awg_nr > 1):
         raise zibase.ziValueError(
             'Invalid AWG index of {} detected!'.format(awg_nr))
예제 #4
0
    def _prepare_CCL_dio_calibration(self, CCL, verbose=False):
        """
        Prepares the appropriate program to calibrate DIO and returns
        expected sequence.
        N.B. only works for microwave on DIO4 and for Flux on DIO3
            (TODO add support for microwave on DIO5)
        """
        log.info('Calibrating DIO delays')
        if verbose: print("Calibrating DIO delays")

        cs_filepath = os.path.join(pycqed.__path__[0], 'measurement',
                                   'openql_experiments', 'output', 'cs.txt')

        opc_filepath = os.path.join(pycqed.__path__[0], 'measurement',
                                    'openql_experiments', 'output',
                                    'qisa_opcodes.qmap')

        # Configure CCL
        CCL.control_store(cs_filepath)
        CCL.qisa_opcode(opc_filepath)

        if self.cfg_codeword_protocol() == 'flux':
            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'CCLight_example', 'qisa_test_assembly',
                             'calibration_cws_flux.qisa'))

            sequence_length = 8
            staircase_sequence = np.arange(1, sequence_length)
            expected_sequence = [(0, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (1, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (2, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (3, list(staircase_sequence))]
        elif self.cfg_codeword_protocol() == 'microwave':
            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'CCLight_example', 'qisa_test_assembly',
                             'calibration_cws_mw.qisa'))

            sequence_length = 32
            staircase_sequence = range(1, sequence_length)
            expected_sequence = [(0, list(reversed(staircase_sequence))), \
                                 (1, list(reversed(staircase_sequence))), \
                                 (2, list(reversed(staircase_sequence))), \
                                 (3, list(reversed(staircase_sequence)))]

        else:
            zibase.ziConfigurationError(
                "Can only calibrate DIO protocol for 'flux' or 'microwave' mode!"
            )

        # Start the CCL with the program configured above
        CCL.eqasm_program(test_fp)
        CCL.start()
        return expected_sequence
예제 #5
0
 def _check_options(self) -> None:
     """
     Checks that the correct options are installed on the instrument.
     """
     options = self.gets('features/options').split('\n')
     if 'QA' not in options and 'QC' not in options:
         raise zibase.ziOptionsError(
             'Device {} is missing the QA or QC option!'.format(
                 self.devname))
     if 'AWG' not in options:
         raise zibase.ziOptionsError(
             'Device {} is missing the AWG option!'.format(self.devname))
예제 #6
0
    def _check_versions(self):
        """
        Checks that sufficient versions of the firmware are available.
        """
        if self.geti('system/fwrevision') < ZI_PQSC.MIN_FWREVISION:
            raise zibase.ziVersionError(
                'Insufficient firmware revision detected! Need {}, got {}!'.
                format(ZI_PQSC.MIN_FWREVISION, self.geti('system/fwrevision')))

        if self.geti('system/fpgarevision') < ZI_PQSC.MIN_FPGAREVISION:
            raise zibase.ziVersionError(
                'Insufficient FPGA revision detected! Need {}, got {}!'.format(
                    ZI_PQSC.MIN_FPGAREVISION,
                    self.geti('system/fpgarevision')))
예제 #7
0
 def _check_awg_nr(self, awg_nr) -> None:
     """
     Checks that the given AWG index is valid for the device.
     """
     if (awg_nr != 0):
         raise zibase.ziValueError(
             'Invalid AWG index of {} detected!'.format(awg_nr))
예제 #8
0
    def _ensure_activity(self,
                         awg_nr,
                         mask_value=None,
                         timeout=5,
                         verbose=False):
        """
        Record DIO data and test whether there is activity on the bits activated in the DIO protocol for the given AWG.
        """
        if verbose: print("Testing DIO activity for AWG {}".format(awg_nr))

        vld_mask = 1 << self.geti('awgs/{}/dio/valid/index'.format(awg_nr))
        vld_polarity = self.geti('awgs/{}/dio/valid/polarity'.format(awg_nr))
        strb_mask = (1 << self.geti('awgs/{}/dio/strobe/index'.format(awg_nr)))
        strb_slope = self.geti('awgs/{}/dio/strobe/slope'.format(awg_nr))

        if mask_value is None:
            mask_value = self.geti('awgs/{}/dio/mask/value'.format(awg_nr))

        cw_mask = mask_value << self.geti(
            'awgs/{}/dio/mask/shift'.format(awg_nr))

        for i in range(timeout):
            valid = True

            data = self.getv('raw/dios/0/data')
            if data is None:
                raise zibase.ziValueError('Failed to get DIO snapshot!')

            vld_activity = 0
            strb_activity = 0
            cw_activity = 0
            for d in data:
                cw_activity |= (d & cw_mask)
                vld_activity |= (d & vld_mask)
                strb_activity |= (d & strb_mask)

            if cw_activity != cw_mask:
                print(
                    "Did not see all codeword bits toggle! Got 0x{:08x}, expected 0x{:08x}."
                    .format(cw_activity, cw_mask))
                valid = False

            if vld_polarity != 0 and vld_activity != vld_mask:
                print("Did not see valid bit toggle!")
                valid = False

            if strb_slope != 0 and strb_activity != strb_mask:
                print("Did not see valid bit toggle!")
                valid = False

            if valid:
                return True

        return False
예제 #9
0
    def _set_dio_calibration_delay(self, value):
        # Sanity check the value
        if value < 0 or value > 15:
            raise zibase.ziValueError(
                'Trying to set DIO calibration delay to invalid value! Expected value in range 0 to 15. Got {}.'
                .format(value))

        log.info('Setting DIO calibration delay to {}'.format(value))
        # Store the value
        self._dio_calibration_delay = value

        # And configure the delays
        self.setd('raw/dios/0/delays/*', self._dio_calibration_delay)
예제 #10
0
    def _prepare_CC_dio_calibration(self, CC, verbose=False):
        """
        Prepares the appropriate program to calibrate DIO and returns
        expected sequence.
        """
        log.info('Calibrating DIO delays')
        if verbose: print("Calibrating DIO delays")

        if self.cfg_codeword_protocol() == 'flux':
            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'CC_examples', 'flux_calibration.vq1asm'))

            sequence_length = 8
            staircase_sequence = np.arange(1, sequence_length)

            # expected sequence should be ([9, 18, 27, 36, 45, 54, 63])
            expected_sequence = [(0, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (1, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (2, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (3, list(staircase_sequence+ (staircase_sequence << 3)))]

        elif self.cfg_codeword_protocol() == 'microwave':

            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'CC_examples', 'old_hdawg_calibration.vq1asm'))

            sequence_length = 32
            staircase_sequence = range(0, sequence_length)
            expected_sequence = [(0, list(staircase_sequence)), \
                                 (1, list(staircase_sequence)), \
                                 (2, list(reversed(staircase_sequence))), \
                                 (3, list(reversed(staircase_sequence)))]

        elif self.cfg_codeword_protocol() == 'new_microwave':
            raise NotImplementedError

        elif self.cfg_codeword_protocol() == 'new_novsm_microwave':
            raise NotImplementedError

        else:
            raise zibase.ziConfigurationError(
                "Can only calibrate DIO protocol for 'flux' or 'microwave' mode!"
            )

        # Start the QCC with the program configured above
        CC.eqasm_program(test_fp)
        CC.start()
        return expected_sequence
예제 #11
0
 def _check_devtype(self) -> None:
     if self.devtype != 'UHFQA':
         raise zibase.ziDeviceError(
             'Device {} of type {} is not a UHFQA instrument!'.format(
                 self.devname, self.devtype))
예제 #12
0
 def plot_dio_snapshot(self, bits=range(32)):
     zibase.plot_timing_diagram(self.getv('raw/dios/0/data'), bits, 64)
예제 #13
0
 def _check_devtype(self):
     if self.devtype != 'HDAWG8' and self.devtype != 'HDAWG4':
         raise zibase.ziDeviceError(
             'Device {} of type {} is not a HDAWG instrument!'.format(
                 self.devname, self.devtype))
예제 #14
0
 def _check_devtype(self):
     if self.devtype != 'PQSC':
         raise zibase.ziDeviceError('Device {} of type {} is not a PQSC \
             instrument!'.format(self.devname, self.devtype))
예제 #15
0
    def check_errors(self, errors_to_ignore=None) -> None:
        """
        Checks the instrument for errors.
        """
        errors = json.loads(self.getv('raw/error/json/errors'))

        # If this is the first time we are called, log the detected errors,
        # but don't raise any exceptions
        if self._errors is None:
            raise_exceptions = False
            self._errors = {}
        else:
            raise_exceptions = True

        # Asserted in case errors were found
        found_errors = False

        # Combine errors_to_ignore with commandline
        _errors_to_ignore = copy.copy(self._errors_to_ignore)
        if errors_to_ignore is not None:
            _errors_to_ignore += errors_to_ignore

        # Go through the errors and update our structure, raise exceptions if
        # anything changed
        for m in errors['messages']:
            code = m['code']
            count = m['count']
            severity = m['severity']
            message = m['message']

            if severity == 0:
                log.info(
                    f'{self.devname}: Code {code}: "{message}" ({severity})')
                continue
            if not raise_exceptions:
                self._errors[code] = {
                    'count': count,
                    'severity': severity,
                    'message': message
                }
                log.warning(
                    f'{self.devname}: Code {code}: "{message}" ({severity})')
            else:
                # Check if there are new errors
                if code not in self._errors or count > self._errors[code][
                        'count']:
                    if code in _errors_to_ignore:
                        log.info(
                            f'{self.devname}: {message} ({code}/{severity})')
                    else:
                        log.error(
                            f'{self.devname}: {message} ({code}/{severity})')
                        found_errors = True

                if code in self._errors:
                    self._errors[code]['count'] = count
                else:
                    self._errors[code] = {
                        'count': count,
                        'severity': severity,
                        'message': message
                    }

        if found_errors:
            raise zibase.ziRuntimeError('Errors detected during run-time!')
예제 #16
0
    def _prepare_QCC_dio_calibration(self, QCC, verbose=False):
        """
        Prepares the appropriate program to calibrate DIO and returns
        expected sequence.
        N.B. only works for microwave on DIO4 and for Flux on DIO3
            (TODO add support for microwave on DIO5)
        """
        log.info('Calibrating DIO delays')
        if verbose: print("Calibrating DIO delays")

        cs_filepath = os.path.join(pycqed.__path__[0], 'measurement',
                                   'openql_experiments', 's17', 'cs.txt')

        opc_filepath = os.path.join(pycqed.__path__[0], 'measurement',
                                    'openql_experiments', 's17',
                                    'qisa_opcodes.qmap')

        # Configure QCC
        QCC.control_store(cs_filepath)
        QCC.qisa_opcode(opc_filepath)

        if self.cfg_codeword_protocol() == 'flux':
            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'QCC_example', 'qisa_test_assembly',
                             'flux_calibration.qisa'))

            sequence_length = 8
            staircase_sequence = np.arange(1, sequence_length)

            # expected sequence should be ([9, 18, 27, 36, 45, 54, 63])
            expected_sequence = [(0, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (1, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (2, list(staircase_sequence + (staircase_sequence << 3))), \
                                 (3, list(staircase_sequence+ (staircase_sequence << 3)))]

        elif self.cfg_codeword_protocol() == 'microwave':
            raise zibase.ziConfigurationError(
                'old_microwave DIO scheme not supported on QCC.')

        elif self.cfg_codeword_protocol() == 'new_microwave':

            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'QCC_example', 'qisa_test_assembly',
                             'withvsm_calibration.qisa'))

            sequence_length = 32
            staircase_sequence = range(1, sequence_length)
            expected_sequence =  [(0, list(staircase_sequence)), \
                                 (1, list(staircase_sequence)), \
                                 (2, list(reversed(staircase_sequence))), \
                                 (3, list(reversed(staircase_sequence)))]

        elif self.cfg_codeword_protocol() == 'new_novsm_microwave':

            test_fp = os.path.abspath(
                os.path.join(pycqed.__path__[0], '..', 'examples',
                             'QCC_example', 'qisa_test_assembly',
                             'novsm_calibration.qisa'))

            sequence_length = 32
            staircase_sequence = range(1, sequence_length)
            expected_sequence = [(0, list(staircase_sequence)), \
                                 (1, list(reversed(staircase_sequence))), \
                                 (2, list(staircase_sequence)), \
                                 (3, list(reversed(staircase_sequence))) ]

        else:
            zibase.ziConfigurationError(
                "Can only calibrate DIO protocol for 'flux' or 'microwave' mode!"
            )

        # Start the QCC with the program configured above
        QCC.eqasm_program(test_fp)
        QCC.start()
        return expected_sequence