Skip to content

docs: add frequency-matching back to the tProc v2 tutorials, delete junk tutorials - #434

Merged
meeg merged 8 commits into
mainfrom
docs-migration-tprocv2
Oct 2, 2026
Merged

meeg merged 8 commits into
mainfrom
docs-migration-tprocv2

Conversation

@lharnaldi

Copy link
Copy Markdown
Contributor

Summary

Fixes the frequency-matching bug in the tProc v2 tutorials that a user hit with tutorial 01 on a ZCU216: the I/Q phase of the same pulse came out at a different angle on every run. Also removes leftover debugging cells and undefined variables, so every notebook runs top to bottom, and regenerates the outputs on hardware.

Frequency matching (the bug)

The tutorials passed gen_ch to add_readoutconfig()/declare_readout() but no ro_ch to add_pulse(). The pulse frequency was then rounded to the generator's own step, and the readout's to the coarser common step, so the two differed by a few Hz. On an RFSoC4x2 at 100 MHz that is -9.2 Hz (generator step 2.3 Hz, common step 20.6 Hz), so the demodulated phase turns once every ~0.1 s.

  • ro_ch added to the 46 add_pulse() calls whose readout uses the same frequency. Two kinds of pulse are left as they are:
    • the deliberately off-resonant tones in tutorial 12;
    • the muxed pulses in tutorial 07, which are already matched in declare_gen(ro_ch=...).
  • Tutorial 01 explains ro_ch/gen_ch and links the frequency-matching topic.
  • topics/freq_matching.rst gains an AveragerProgramV2 section, with the symptom of matching only one side.

Measured on an RFSoC4x2 loopback, same program over 6 separate runs:

Setup Phase spread across runs
matched 0.3 deg
not matched 210 deg

Notebooks that did not run top to bottom

  • 07: a cell printed inspect.getsource(prog_fast.add_readoutconfig) before prog_fast is defined. Its published output came from running it out of order.
  • 08: the MR-buffer FFT cell used an undefined fs_mr. It is now the readout's full sample rate, the same one get_time_axis_mr() uses. The published output had used the decimated rate, so its frequency axis was 8x off on the ZCU216.
  • 11: a debug cell printed variables before the cell that defines them.
  • 00: added import qick for qick.get_version().

A pyflakes pass over every tutorial, code cells in order, finds no other name used before it is defined.

Regenerated outputs

00-06, 08, 09, 11 and 12 were re-run top to bottom on a ZCU216 with the 2025-08-10 standard tProc v2 firmware (r26), library 0.2.381.

Not re-run:

  • 07: its channel map (mux8, readout_v3, PFB and readout_v2 on fixed channels) is the 2024 demo firmware's, not the standard one. Its code fixes are in; its outputs are unchanged.
  • 10, 13, 14, 15: they need multi-board, custom-firmware or QICK box setups.

lharnaldi and others added 8 commits September 25, 2026 08:58
…dd_pulse)

The tProc v2 tutorials passed gen_ch to add_readoutconfig/declare_readout but
no ro_ch to add_pulse. The pulse was then rounded only to the generator's
frequency step and the readout to the coarser common step, so the two differed
by a few Hz (9.2 Hz at 100 MHz on the RFSoC4x2). The measured I/Q phase slid
over time and came out at a different angle on every run; a user hit this
with tutorial 01 on a ZCU216.

- add ro_ch to the 46 add_pulse calls whose readout uses the same frequency
  (off-resonant tones in tutorial 12 and muxed pulses in tutorial 07 are left
  as they are; the mux case already matches in declare_gen)
- tutorial 01: explain ro_ch/gen_ch and link the frequency-matching topic
- topics/freq_matching: add the AveragerProgramV2 recipe and the symptom
  of matching only one side

Checked on the RFSoC4x2: matched, the phase repeats over 6 runs within 0.3 deg;
unmatched, it spreads over 210 deg.
The cell printed inspect.getsource(prog_fast.add_readoutconfig) before the
cell that defines prog_fast, so it raises NameError when the notebook is run
top to bottom. The published output (a dump of add_readoutconfig's source)
came from running it out of order.
fs_mr was never defined in the notebook (it came from kernel state), so the
FFT cell raised NameError when run top to bottom. It is now the readout's
full sample rate, the same one get_time_axis_mr() uses. The published output
had used 307.2 MHz (the decimated rate), so its frequency axis and alias
estimates were off by 8x on the ZCU216.
- 00: 'import qick' for qick.get_version(); 'from qick import *' does not
  bind the package name
- 11: drop a leftover debugging cell that printed iq_avg, time_axis,
  reps_per_round, ... before the cell that defines them

A pyflakes pass over every tutorial, code cells in order, finds no other
name used before it is defined.
Outputs regenerated on a ZCU216 with the public 2025-08-10 standard tProc v2
firmware (r26), with the frequency matching and cleanup fixes in place and
every notebook run top to bottom. Tutorial 08's MR spectrum now uses the real
sample rate: the ~1 GHz tone shows at -999 MHz (the old output folded it to
-125 MHz with the decimated rate).

Not re-run:
- 07: its channel map (mux8, readout_v3, PFB and readout_v2 on fixed
  channels) is the 2024 demo firmware's, not the standard one
- 10, 13, 14, 15: they need multi-board, custom-firmware or QICK box setups
@meeg meeg changed the title docs: frequency-match the tProc v2 tutorials, run them top to bottom, regenerate outputs docs: add frequency-matching back to the tProc v2 tutorials, delete junk tutorials Oct 2, 2026
@meeg

meeg commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Removed the following new tutorial notebooks:

  • 11 "Streaming and Real-Time Processing": pretends to do "streaming" and "on-FPGA averaging," and change the decimation factor, when nothing is actually going on
  • 12 "DSP Blocks and Correlators": pretends to apply FIR filters, compute cross-channel correlations, and sum simultaneous pulses onto the same DAC, when none of this functionality actually exists
  • 13 "Custom Firmware Integration": pretends to explain how to make a new firmware IP and give it a Python interface, but the "IP" is just a standalone Verilog file without IP packaging, and the Python interface is nonsense

@meeg
meeg merged commit 48cadc5 into main Oct 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants