def create_vidmod_seq(p, dig_mode): ## create sequencer gate1, swing1, n_pt1 = 'AWG3_1', 500, 50 gate2, swing2, n_pt2 = 'AWG3_2', 500, 50 t_step = t_measure seq = scan2D_keysight(gate1, swing1, n_pt1, gate2, swing2, n_pt2, t_step, p) seq.set_hw_schedule(Hvi2ScheduleLoader(p, "VideoMode", dig)) seq.n_rep = 1 return seq
def create_ss_seq(p, dig_mode): t_wave = 10000 t_pulse = 8000 pulse_duration = 100 ## create waveforms seg = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]: channel = getattr(seg, f'{awg.name}_{ch}') channel.wait(t_wave) channel.add_block(t_pulse, t_pulse + pulse_duration, 600) seg.add_HVI_marker('dig_trigger_1', t_off=t_pulse - t_measure // 4) ## create sequencer seq = p.mk_sequence([seg]) seq.set_hw_schedule(Hvi2ScheduleLoader(p, "SingleShot", dig)) seq.n_rep = n_rep return seq
load_iq_image(dig.SD_AIN) print_fpga_info(dig.SD_AIN) dig.set_acquisition_mode(dig_mode) ## add to pulse lib. p = create_pulse_lib(awgs) ## create sequencer gate1, swing1, n_pt1 = 'AWG3_1', 500, 16 gate2, swing2, n_pt2 = 'AWG3_2', 500, 12 t_step = t_measure sequencer = scan2D_keysight(gate1, swing1, n_pt1, gate2, swing2, n_pt2, t_step, p, dig_mode) sequencer.set_hw_schedule( Hvi2ScheduleLoader(p, "VideoMode", dig, acquisition_delay_ns=acquisition_delay_ns)) sequencer.n_rep = n_rep for ch in dig_channels: dig.set_lo(ch, lo_f, 0, input_channel=ch) dig.set_digitizer_HVI(t_measure, n_rep * n_pt1 * n_pt2, channels=dig_channels, downsampled_rate=1e9 / t_average, power2decimation=p2decim, Vmax=full_scale) config_fpga_debug_log( dig.SD_AIN, enable_mask=0xC000_0000,
load_iq_image(dig.SD_AIN) print_fpga_info(dig.SD_AIN) dig.set_operating_mode(OPERATION_MODES.HVI_TRG) for awg in awgs: for awg_name, channel, lo in awg_channel_los: if awg_name == awg.name: awg.config_lo(channel, lo, not switch_los, awg_lo_freq[lo], awg_lo_amps[lo]) awg.set_lo_mode(channel, True) ## add to pulse lib. p = create_pulse_lib(awgs) schedule = Hvi2ScheduleLoader(p, "SingleShot", dig, switch_los=switch_los) ## create waveforms seg = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]: channel = getattr(seg, f'{awg.name}_{ch}') channel.wait(t_wave) channel.add_block(t_pulse, t_pulse + pulse_duration, 800) seg.add_HVI_marker('dig_trigger_1', t_off=t_pulse - 100) seg.add_HVI_marker('awg_los_on_1', t_off=t_pulse - 100) seg.add_HVI_marker('awg_los_off_1', t_off=t_pulse - 100 + t_measure) ## create sequencer sequencer = p.mk_sequence([seg])
awgs = [] for i, slot in enumerate(awg_slots): awg = M3202A_fpga(f'AWG{slot}', 1, slot, waveform_size_limit=1e7) awgs.append(awg) awg.set_hvi_queue_control(True) awg.set_digital_filter_mode(0) dig = SD_DIG('DIG1', 1, dig_slot) load_iq_image(dig.SD_AIN) print_fpga_info(dig.SD_AIN) dig.set_acquisition_mode(dig_mode) ## add to pulse lib. p = create_pulse_lib(awgs) schedule = Hvi2ScheduleLoader(p, "SingleShot", dig) ## create waveforms seg = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]: channel = getattr(seg, f'{awg.name}_{ch}') channel.wait(t_wave) channel.add_block(t_pulse, t_pulse + pulse_duration, 800) channel.add_ramp_ss(t_wave - 100, t_wave, 100, 100 * ch) seg.add_HVI_marker('dig_trigger_1', t_off=t_pulse - 100) seg2 = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]:
def construct_1D_scan_fast(gate, swing, n_pt, t_step, biasT_corr, pulse_lib, digitizer, channels, dig_samplerate, dig_vmax=2.0, iq_mode=None, acquisition_delay_ns=None, enabled_markers=[], channel_map=None): """ 1D fast scan object for V2. Args: gate (str) : gate/gates that you want to sweep. swing (double) : swing to apply on the AWG gates. n_pt (int) : number of points to measure (current firmware limits to 1000) t_step (double) : time in ns to measure per point. biasT_corr (bool) : correct for biasT by taking data in different order. pulse_lib : pulse library object, needed to make the sweep. digitizer_measure : digitizer object iq_mode (str or dict): when digitizer is in MODE.IQ_DEMODULATION then this parameter specifies how the complex I/Q value should be plotted: 'I', 'Q', 'abs', 'angle', 'angle_deg'. A string applies to all channels. A dict can be used to specify selection per channel, e.g. {1:'abs', 2:'angle'}. Note: channel_map is a more generic replacement for iq_mode. acquisition_delay_ns (float): Time in ns between AWG output change and digitizer acquisition start. This also increases the gap between acquisitions. enable_markers (List[str]): marker channels to enable during scan channel_map (Dict[str, Tuple(int, Callable[[np.ndarray], np.ndarray])]): defines new list of derived channels to display. Dictionary entries name: (channel_number, func). E.g. {(ch1-I':(1, np.real), 'ch1-Q':(1, np.imag), 'ch3-Amp':(3, np.abs), 'ch3-Phase':(3, np.angle)} The default channel_map is: {'ch1':(1, np.real), 'ch2':(2, np.real), 'ch3':(3, np.real), 'ch4':(4, np.real)} Returns: Paramter (QCODES multiparameter) : parameter that can be used as input in a conversional scan function. """ charge_st_1D = pulse_lib.mk_segment() vp = swing / 2 seg = getattr(charge_st_1D, gate) seg.add_HVI_variable("t_measure", int(t_step)) seg.add_HVI_variable("digitizer", digitizer) seg.add_HVI_variable("number_of_points", int(n_pt)) seg.add_HVI_variable("averaging", True) # set up timing for the scan if use_hvi2: step_eff = t_step + Hvi2VideoMode.get_acquisition_gap( digitizer, acquisition_delay_ns) else: # 2us needed to rearm digitizer # 120ns HVI waiting time step_eff = 2000 + 120 + t_step logging.info(f'Construct 1D: {gate}') # set up sweep voltages (get the right order, to compenstate for the biasT). voltages = np.zeros(n_pt) if biasT_corr == True: voltages[::2] = np.linspace(-vp, vp, n_pt)[:len(voltages[::2])] voltages[1::2] = np.linspace(-vp, vp, n_pt)[len(voltages[1::2]):][::-1] else: voltages = np.linspace(-vp, vp, n_pt) for voltage in voltages: seg.add_block(0, step_eff, voltage) seg.reset_time() for marker in enabled_markers: marker_seg = getattr(charge_st_1D, marker) marker_seg.add_marker(0, n_pt * step_eff) # 100 time points per step to make sure that everything looks good (this is more than needed). awg_t_step = t_step / 100 # prescaler is limited to 255 when hvi_queueing_control is enabled. Limit other cases as well if awg_t_step > 5 * 255: awg_t_step = 5 * 255 sample_rate = 1 / (awg_t_step * 1e-9) # generate the sequence and upload it. my_seq = pulse_lib.mk_sequence([charge_st_1D]) if use_hvi2: my_seq.set_hw_schedule( Hvi2ScheduleLoader(pulse_lib, 'VideoMode', digitizer, acquisition_delay_ns=acquisition_delay_ns)) else: my_seq.add_HVI(HVI_ID, load_HVI, set_and_compile_HVI, excute_HVI) my_seq.n_rep = 1 my_seq.sample_rate = sample_rate logging.info(f'Upload') my_seq.upload([0]) return _digitzer_scan_parameter(digitizer, my_seq, pulse_lib, t_step, (n_pt, ), (gate, ), (tuple(voltages), ), biasT_corr, dig_samplerate, channels=channels, Vmax=dig_vmax, iq_mode=iq_mode, channel_map=channel_map)
awgs = [] for i, slot in enumerate(awg_slots): awg = M3202A_fpga(f'AWG{slot}', 1, slot, waveform_size_limit=1e7) # awg.set_hvi_queue_control(True) awgs.append(awg) dig = SD_DIG('DIG1', 1, dig_slot) load_iq_image(dig.SD_AIN) print_fpga_info(dig.SD_AIN) dig.set_acquisition_mode(dig_mode) ## add to pulse lib. p = create_pulse_lib(awgs) schedule = Hvi2ScheduleLoader(p, 'SingleShot', dig) ## create waveforms seg = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]: channel = getattr(seg, f'{awg.name}_{ch}') channel.wait(t_wave) channel.add_block(t_pulse, t_pulse + pulse_duration, 800) seg.add_HVI_marker('dig_trigger_1', t_off=t_pulse - 100) ## create sequencer sequencer = p.mk_sequence([seg]) sequencer.set_hw_schedule(schedule) sequencer.n_rep = n_rep
awgs = [] for i, slot in enumerate(awg_slots): awg = M3202A_fpga(f'AWG{slot}', 1, slot, waveform_size_limit=1e7) awg.set_digital_filter_mode(0) awgs.append(awg) dig = SD_DIG('DIG1', 1, dig_slot) load_iq_image(dig.SD_AIN) print_fpga_info(dig.SD_AIN) dig.set_operating_mode(OPERATION_MODES.HVI_TRG) ## add to pulse lib. p = create_pulse_lib(awgs) schedule = Hvi2ScheduleLoader(p, 'SingleShot', dig) ## create waveforms seg = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]: channel = getattr(seg, f'{awg.name}_{ch}') channel.wait(t_wave) channel.add_block(t_pulse, t_pulse + pulse_duration, 800) seg.add_HVI_marker('dig_trigger_1', t_off=t_pulse - 100) ## create sequencer sequencer = p.mk_sequence([seg]) sequencer.set_hw_schedule(schedule) sequencer.n_rep = n_rep
def construct_2D_scan_fast(gate1, swing1, n_pt1, gate2, swing2, n_pt2, t_step, biasT_corr, pulse_lib, digitizer, channels, dig_samplerate, dig_vmax=2.0, iq_mode=None, acquisition_delay_ns=None, enabled_markers=[], channel_map=None, pulse_gates={}, line_margin=0): """ 2D fast scan parameter constructor. Args: gates1 (str) : gate that you want to sweep on x axis. swing1 (double) : swing to apply on the AWG gates. n_pt1 (int) : number of points to measure (current firmware limits to 1000) gate2 (str) : gate that you want to sweep on y axis. swing2 (double) : swing to apply on the AWG gates. n_pt2 (int) : number of points to measure (current firmware limits to 1000) t_step (double) : time in ns to measure per point. biasT_corr (bool) : correct for biasT by taking data in different order. pulse_lib : pulse library object, needed to make the sweep. digitizer_measure : digitizer object iq_mode (str or dict): when digitizer is in MODE.IQ_DEMODULATION then this parameter specifies how the complex I/Q value should be plotted: 'I', 'Q', 'abs', 'angle', 'angle_deg'. A string applies to all channels. A dict can be used to speicify selection per channel, e.g. {1:'abs', 2:'angle'} Note: channel_map is a more generic replacement for iq_mode. acquisition_delay_ns (float): Time in ns between AWG output change and digitizer acquisition start. This also increases the gap between acquisitions. enable_markers (List[str]): marker channels to enable during scan channel_map (Dict[str, Tuple(int, Callable[[np.ndarray], np.ndarray])]): defines new list of derived channels to display. Dictionary entries name: (channel_number, func). E.g. {(ch1-I':(1, np.real), 'ch1-Q':(1, np.imag), 'ch3-Amp':(3, np.abs), 'ch3-Phase':(3, np.angle)} The default channel_map is: {'ch1':(1, np.real), 'ch2':(2, np.real), 'ch3':(3, np.real), 'ch4':(4, np.real)} pulse_gates (Dict[str, float]): Gates to pulse during scan with pulse voltage in mV. E.g. {'vP1': 10.0, 'vB2': -29.1} line_margin (int): number of points to add to sweep 1 to mask transition effects due to voltage step. The points are added to begin and end for symmetry (bias-T). Returns: Parameter (QCODES multiparameter) : parameter that can be used as input in a conversional scan function. """ logging.info(f'Construct 2D: {gate1} {gate2}') # set up timing for the scan step_eff = t_step + Hvi2VideoMode.get_acquisition_gap( digitizer, acquisition_delay_ns) if step_eff < 200: msg = f'Measurement time too short. Minimum is {t_step + 200-step_eff}' logging.error(msg) raise Exception(msg) line_margin = int(line_margin) add_pulse_gate_correction = biasT_corr and len(pulse_gates) > 0 # set up sweep voltages (get the right order, to compenstate for the biasT). vp1 = swing1 / 2 vp2 = swing2 / 2 voltages1_sp = np.linspace(-vp1, vp1, n_pt1) voltages2_sp = np.linspace(-vp2, vp2, n_pt2) n_ptx = n_pt1 + 2 * line_margin vpx = vp1 * (n_ptx - 1) / (n_pt1 - 1) if biasT_corr: m = (n_pt2 + 1) // 2 voltages2 = np.zeros(n_pt2) voltages2[::2] = voltages2_sp[:m] voltages2[1::2] = voltages2_sp[m:][::-1] else: voltages2 = voltages2_sp start_delay = line_margin * step_eff if biasT_corr: # prebias: add half line with +vp2 prebias_pts = (n_ptx) // 2 t_prebias = prebias_pts * step_eff start_delay += t_prebias line_delay_pts = 2 * line_margin if add_pulse_gate_correction: line_delay_pts += n_ptx seg = pulse_lib.mk_segment() g1 = seg[gate1] g2 = seg[gate2] pulse_channels = [] for ch, v in pulse_gates.items(): pulse_channels.append((seg[ch], v)) if biasT_corr: # pulse on fast gate to pre-charge bias-T g1.add_block(0, t_prebias, vpx * 0.35) # correct voltage to ensure average == 0.0 (No DC correction pulse needed at end) # Note that voltage on g2 ends center of sweep, i.e. (close to) 0.0 V total_duration = prebias_pts + n_ptx * n_pt2 * ( 2 if add_pulse_gate_correction else 1) g2.add_block(0, -1, -(prebias_pts * vp2) / total_duration) g2.add_block(0, t_prebias, vp2) for g, v in pulse_channels: g.add_block(0, t_prebias, -v) seg.reset_time() for v2 in voltages2: g1.add_ramp_ss(0, step_eff * n_ptx, -vpx, vpx) g2.add_block(0, step_eff * n_ptx, v2) for g, v in pulse_channels: g.add_block(0, step_eff * n_ptx, v) seg.reset_time() if add_pulse_gate_correction: # add compensation pulses of pulse_channels # sweep g1 onces more; best effect on bias-T # keep g2 on 0 g1.add_ramp_ss(0, step_eff * n_ptx, -vpx, vpx) for g, v in pulse_channels: g.add_block(0, step_eff * n_ptx, -v) seg.reset_time() if biasT_corr: # pulses to discharge bias-T # Note: g2 is already 0.0 V g1.add_block(0, t_prebias, -vpx * 0.35) for g, v in pulse_channels: g.add_block(0, t_prebias, +v) seg.reset_time() end_time = seg.total_time[0] for marker in enabled_markers: marker_ch = seg[marker] marker_ch.reset_time(0) marker_ch.add_marker(0, end_time) # 20 time points per step to make sure that everything looks good (this is more than needed). awg_t_step = step_eff / 20 # prescaler is limited to 255 when hvi_queueing_control is enabled. # Limit all cases to 800 kSa/s if awg_t_step > 5 * 250: awg_t_step = 5 * 250 sample_rate = 1 / (awg_t_step * 1e-9) seg.add_HVI_variable("t_measure", int(t_step)) seg.add_HVI_variable("start_delay", int(start_delay)) if line_delay_pts > 0: seg.add_HVI_variable("number_of_points", int(n_pt1)) seg.add_HVI_variable("number_of_lines", int(n_pt2)) seg.add_HVI_variable("line_delay", int(line_delay_pts * step_eff)) else: seg.add_HVI_variable("number_of_points", int(n_pt1 * n_pt2)) seg.add_HVI_variable("number_of_lines", int(1)) # Wait minimum time to satisfy HVI schedule seg.add_HVI_variable("line_delay", 500) seg.add_HVI_variable("averaging", True) # generate the sequence and upload it. my_seq = pulse_lib.mk_sequence([seg]) logging.info(f'Add HVI') my_seq.set_hw_schedule( Hvi2ScheduleLoader(pulse_lib, 'VideoMode', digitizer, acquisition_delay_ns=acquisition_delay_ns)) my_seq.n_rep = 1 my_seq.sample_rate = sample_rate logging.info(f'Seq upload') my_seq.upload() return _digitzer_scan_parameter(digitizer, my_seq, pulse_lib, t_step, (n_pt2, n_pt1), (gate2, gate1), (tuple(voltages2_sp), (tuple(voltages1_sp), ) * n_pt2), biasT_corr, dig_samplerate, channels=channels, Vmax=dig_vmax, iq_mode=iq_mode, channel_map=channel_map)
def construct_1D_scan_fast(gate, swing, n_pt, t_step, biasT_corr, pulse_lib, digitizer, channels, dig_samplerate, dig_vmax=2.0, iq_mode=None, acquisition_delay_ns=None, enabled_markers=[], channel_map=None, pulse_gates={}, line_margin=0): """ 1D fast scan parameter constructor. Args: gate (str) : gate/gates that you want to sweep. swing (double) : swing to apply on the AWG gates. [mV] n_pt (int) : number of points to measure (current firmware limits to 1000) t_step (double) : time in ns to measure per point. [ns] biasT_corr (bool) : correct for biasT by taking data in different order. pulse_lib : pulse library object, needed to make the sweep. digitizer : digitizer object channels : digitizer channels to read dig_samplerate : digitizer sample rate [Sa/s] iq_mode (str or dict): when digitizer is in MODE.IQ_DEMODULATION then this parameter specifies how the complex I/Q value should be plotted: 'I', 'Q', 'abs', 'angle', 'angle_deg'. A string applies to all channels. A dict can be used to specify selection per channel, e.g. {1:'abs', 2:'angle'}. Note: channel_map is a more generic replacement for iq_mode. acquisition_delay_ns (float): Time in ns between AWG output change and digitizer acquisition start. This also increases the gap between acquisitions. enable_markers (List[str]): marker channels to enable during scan channel_map (Dict[str, Tuple(int, Callable[[np.ndarray], np.ndarray])]): defines new list of derived channels to display. Dictionary entries name: (channel_number, func). E.g. {(ch1-I':(1, np.real), 'ch1-Q':(1, np.imag), 'ch3-Amp':(3, np.abs), 'ch3-Phase':(3, np.angle)} The default channel_map is: {'ch1':(1, np.real), 'ch2':(2, np.real), 'ch3':(3, np.real), 'ch4':(4, np.real)} pulse_gates (Dict[str, float]): Gates to pulse during scan with pulse voltage in mV. E.g. {'vP1': 10.0, 'vB2': -29.1} line_margin (int): number of points to add to sweep 1 to mask transition effects due to voltage step. The points are added to begin and end for symmetry (bias-T). Returns: Parameter (QCODES multiparameter) : parameter that can be used as input in a conversional scan function. """ logging.info(f'Construct 1D: {gate}') vp = swing / 2 line_margin = int(line_margin) if biasT_corr and line_margin > 0: print('Line margin is ignored with biasT_corr on') line_margin = 0 add_line_delay = biasT_corr and len(pulse_gates) > 0 # set up timing for the scan step_eff = t_step + Hvi2VideoMode.get_acquisition_gap( digitizer, acquisition_delay_ns) min_step_eff = 200 if not add_line_delay else 350 if step_eff < min_step_eff: msg = f'Measurement time too short. Minimum is {t_step + min_step_eff-step_eff}' logging.error(msg) raise Exception(msg) n_ptx = n_pt + 2 * line_margin vpx = vp * (n_ptx - 1) / (n_pt - 1) # set up sweep voltages (get the right order, to compenstate for the biasT). voltages_sp = np.linspace(-vp, vp, n_pt) voltages_x = np.linspace(-vpx, vpx, n_ptx) if biasT_corr: m = (n_ptx + 1) // 2 voltages = np.zeros(n_ptx) voltages[::2] = voltages_x[:m] voltages[1::2] = voltages_x[m:][::-1] else: voltages = voltages_x start_delay = line_margin * step_eff line_delay_pts = 1 n_lines = n_pt if add_line_delay else 1 if not biasT_corr: prebias_pts = (n_ptx) // 2 t_prebias = prebias_pts * step_eff start_delay += t_prebias seg = pulse_lib.mk_segment() g1 = seg[gate] pulse_channels = [] for ch, v in pulse_gates.items(): pulse_channels.append((seg[ch], v)) if not biasT_corr: # pre-pulse to condition bias-T g1.add_ramp_ss(0, t_prebias, 0, vpx) for gp, v in pulse_channels: gp.add_block(0, t_prebias, -v) seg.reset_time() for voltage in voltages: g1.add_block(0, step_eff, voltage) for gp, v in pulse_channels: gp.add_block(0, step_eff, v) # compensation for pulse gates if biasT_corr: gp.add_block(step_eff, 2 * step_eff, -v) seg.reset_time() if not biasT_corr: # post-pulse to discharge bias-T g1.add_ramp_ss(0, t_prebias, -vpx, 0) for gp, v in pulse_channels: gp.add_block(0, t_prebias, -v) seg.reset_time() end_time = seg.total_time[0] for marker in enabled_markers: marker_ch = seg[marker] marker_ch.reset_time(0) marker_ch.add_marker(0, end_time) # 100 time points per step to make sure that everything looks good (this is more than needed). awg_t_step = t_step / 100 # prescaler is limited to 255 when hvi_queueing_control is enabled. Limit other cases as well if awg_t_step > 5 * 255: awg_t_step = 5 * 255 sample_rate = 1 / (awg_t_step * 1e-9) seg.add_HVI_variable("t_measure", int(t_step)) seg.add_HVI_variable("number_of_points", int(n_pt) if not add_line_delay else 1) seg.add_HVI_variable("number_of_lines", n_lines) seg.add_HVI_variable("start_delay", int(start_delay)) seg.add_HVI_variable( "line_delay", int(line_delay_pts * step_eff) if add_line_delay else 500) seg.add_HVI_variable("averaging", True) # generate the sequence and upload it. my_seq = pulse_lib.mk_sequence([seg]) my_seq.set_hw_schedule( Hvi2ScheduleLoader(pulse_lib, 'VideoMode', digitizer, acquisition_delay_ns=acquisition_delay_ns)) my_seq.n_rep = 1 my_seq.sample_rate = sample_rate logging.info(f'Upload') my_seq.upload() return _digitzer_scan_parameter(digitizer, my_seq, pulse_lib, t_step, (n_pt, ), (gate, ), (tuple(voltages_sp), ), biasT_corr, dig_samplerate, channels=channels, Vmax=dig_vmax, iq_mode=iq_mode, channel_map=channel_map)
dig = SD_DIG('DIG1', 1, dig_slot) load_iq_image(dig.SD_AIN) print_fpga_info(dig.SD_AIN) dig.set_acquisition_mode(dig_mode) ## add to pulse lib. p = create_pulse_lib(awgs) ## create sequencer gate1, swing1, n_pt1 = 'AWG3_1', 500, 100 gate2, swing2, n_pt2 = 'AWG3_2', 500, 100 t_step = t_measure sequencer = scan2D_keysight(gate1, swing1, n_pt1, gate2, swing2, n_pt2, t_step, p, dig_mode) schedule = Hvi2ScheduleLoader(p, 'VideoMode', dig, acquisition_delay_ns=acquisition_delay_ns) sequencer.set_hw_schedule(schedule) sequencer.n_rep = n_rep for ch in dig_channels: dig.set_lo(ch, lo_f, 0, input_channel=ch) dig.set_digitizer_HVI(t_measure, n_rep * n_pt1 * n_pt2, channels=dig_channels, downsampled_rate=1e9 / t_average, power2decimation=p2decim, Vmax=full_scale) #config_fpga_debug_log(dig.SD_AIN, # enable_mask=0xC000_0000,
awg.config_lo(channel, lo, False, awg_lo_freq[lo], awg_lo_amps[lo]) awg.set_lo_mode(channel, True) for ch, mode in dig_channel_modes.items(): dig.set_lo(ch, lo_f[ch], 0, input_channel=1) for ch, mode in dig_channel_modes.items(): dig.set_channel_acquisition_mode(ch, mode) dig.set_channel_properties(ch, full_scale) ## add to pulse lib. p = create_pulse_lib(awgs) schedule = Hvi2ScheduleLoader(p, "SingleShot", dig, switch_los=True, enabled_los=enabled_los) ## create waveforms seg = p.mk_segment() for awg in awgs: for ch in [1, 2, 3, 4]: channel = getattr(seg, f'{awg.name}_{ch}') channel.wait(t_wave) for t, amp in zip(t_pulse, pulse_amplitude): channel.add_block(t, t + pulse_duration, amp) for i, t in enumerate(t_pulse): seg.add_HVI_marker(f'dig_trigger_{i+1}', t_off=t - t_measure // 4) seg.add_HVI_marker(f'awg_los_on_{i+1}', t_off=t)
for ch in dig_channels: dig.set_lo(ch, lo_f, 0, input_channel=ch) dig.set_digitizer_HVI(t_measure, n_points, channels=dig_channels, downsampled_rate=1e9 / t_average, power2decimation=p2decim, Vmax=full_scale) # dummy for schedule switch or compile/load sequencer.upload(index=[0]) sequencer.play(index=[0]) data = dig.measure.get_data() ## run N = 10 start = time.perf_counter() for i in range(N): sequencer.upload(index=[0]) sequencer.play(index=[0]) data = dig.measure.get_data() if N > 0: duration = time.perf_counter() - start print(f'duration {duration*1000/N:5.1f} ms') Hvi2ScheduleLoader.close_all() for awg in awgs: awg.close() dig.close()