@@ -141,7 +141,7 @@ function create_wf_instrs!(instr_lib, wfs, pulses)
141141 # TODO : better handle Id so we don't generate useless long wfs and have repeated TAZ offsets
142142 idx = 0
143143 for p in pulses
144- wf = p. amp * QGL. waveform (p, DAC_CLOCK)
144+ wf = p. amp . * QGL. waveform (p, DAC_CLOCK)
145145 if ! USE_PHASE_OFFSET_INSTRUCTION
146146 wf *= exp (1im * 2 π * p. phase)
147147 end
@@ -173,21 +173,37 @@ function create_marker_instrs!(instr_lib, pulses, marker_chan)
173173 end
174174end
175175
176+ """
177+ find_next_analog_entry!(entry, chan, wf_lib, analog_timestamps, id_ch, Z_chs_id)
178+
179+ Finds the next sequential entry in a sequence for channels that have multiple logical
180+ channels sharing a physical channel.
176181
177- function find_next_analog_entry! (entry, chan, wf_lib, analog_timestamps, id_ch, Z_chs_id)
178- if any ([id_ch[ct] > length (entry. pulses[chan[ct]]) for ct in 1 : length (chan)])
182+ `analog_timestamps` tracks the time from the start of the PulseBlock for each logical channel
183+ `ch_idx` tracks the index into the PulseBlock of each logical channel
184+ `Z_chs_ids` carries the logical channel index of the previous Z pulses
185+ """
186+ function find_next_analog_entry! (entry, chan, wf_lib, analog_timestamps, ch_idx, Z_chs_id)
187+ if all ([ch_idx[ct] > length (entry. pulses[chan[ct]]) for ct in 1 : length (chan)])
179188 return
180189 end
190+ # get all logical channel indices that could have the next pulse
181191 sim_chs_id = findall (x-> x == minimum (analog_timestamps), analog_timestamps)
182192 filter! (x-> ! (x in Z_chs_id), sim_chs_id)
193+ if length (sim_chs_id) == 0
194+ # must be done...
195+ return
196+ end
183197 pulses = []
184198 for ct in sim_chs_id
185- pulse = entry. pulses[chan[ct]][id_ch [ct]]
199+ pulse = entry. pulses[chan[ct]][ch_idx [ct]]
186200 if typeof (pulse) == QGL. ZPulse
187201 if length (sim_chs_id) > 1 # if simultaneous logical channels, remove the Z pulses one by one
188202 push! (Z_chs_id, ct)
203+ else
204+ Z_chs_id = Int[]
189205 end
190- id_ch [ct]+= 1
206+ ch_idx [ct] += 1
191207 return pulse, Z_chs_id
192208 end
193209 push! (pulses, pulse)
@@ -202,15 +218,17 @@ function find_next_analog_entry!(entry, chan, wf_lib, analog_timestamps, id_ch,
202218 elseif length (nonid_ids) == 1
203219 chan_select = sim_chs_id[nonid_ids[1 ]]
204220 else # select the channel with the shortest Id
205- chan_select = sim_chs_id[indmin ([pulse. length for pulse in pulses])]
221+ chan_select = sim_chs_id[argmin ([pulse. length for pulse in pulses])]
206222 end
207223 end
208- next_entry = entry. pulses[chan[chan_select]][id_ch[chan_select]]
209- for ct in sim_chs_id
210- analog_timestamps[ct] += wf_lib[entry. pulses[chan[ct]][id_ch[ct]]]. count + 1
211- id_ch[ct]+= 1
212- end
213- Z_chs_id = []
224+ next_entry = entry. pulses[chan[chan_select]][ch_idx[chan_select]]
225+ analog_timestamps[chan_select] += wf_lib[entry. pulses[chan[chan_select]][ch_idx[chan_select]]]. count + 1
226+ ch_idx[chan_select] += 1
227+ # for ct in sim_chs_id
228+ # analog_timestamps[ct] += wf_lib[entry.pulses[chan[ct]][ch_idx[ct]]].count + 1
229+ # ch_idx[ct] += 1
230+ # end
231+ Z_chs_id = Int[]
214232 return next_entry, Z_chs_id
215233end
216234
@@ -247,9 +265,11 @@ function create_instrs(seqs, wf_lib, chans, chan_freqs)
247265 all_done[ct] = num_entries[ct] == 0
248266 end
249267
268+ # analog_timestamps will track time delay from the start of the PulseBlock
250269 analog_timestamps = zeros (Int, length (chan_freqs))
251270 analog_idx = ones (Int, length (chan_freqs))
252- Z_chs_id = []
271+ num_analog_entries = [length (entry. pulses[chan]) for chan in keys (chan_freqs)]
272+ Z_chs_id = Int[]
253273 # serialize pulses from the PulseBlock
254274 # round-robin through the channels until all are exhausted
255275 while ! all (all_done)
@@ -258,9 +278,9 @@ function create_instrs(seqs, wf_lib, chans, chan_freqs)
258278 for (ct, chan) in enumerate (chans)
259279 if (! all_done[ct]) && (time_stamp[ct] <= next_instr_time)
260280
261- if length (chan)> 1 # multiple logical channels per analog channel
281+ if length (chan) > 1 # multiple logical channels per analog channel
262282 next_entry_info = find_next_analog_entry! (entry, chan, wf_lib, analog_timestamps, analog_idx, Z_chs_id)
263- if typeof ( next_entry_info) === nothing
283+ if next_entry_info === nothing
264284 all_done[ct] = true
265285 break
266286 end
@@ -277,7 +297,11 @@ function create_instrs(seqs, wf_lib, chans, chan_freqs)
277297 push! (instrs, modulation_instr (MODULATE, nco_select[next_entry. channel], wf. count))
278298 end
279299 push! (instrs, wf. instruction)
280- time_stamp[ct] += wf. count+ 1
300+ if length (chan) > 1
301+ time_stamp[ct] = minimum (analog_timestamps)
302+ else
303+ time_stamp[ct] += wf. count+ 1
304+ end
281305 elseif typeof (next_entry) == QGL. ZPulse
282306 # round phase to 28 bit integer
283307 fixed_pt_phase = round (Int32, mod (- next_entry. angle, 1 ) * 2 ^ 28 )
0 commit comments